blob: 60646971fc9c4082c364d4201f3e1d20f93b40f7 [file] [log] [blame]
/*
* Copyright 2022 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/core/SkCanvas.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "tests/Test.h"
#include "tests/TestUtils.h"
static void check_pixels(skiatest::Reporter* reporter, const SkBitmap& bitmap,
GrSurfaceOrigin origin) {
const uint32_t* canvasPixels = static_cast<const uint32_t*>(bitmap.getPixels());
bool failureFound = false;
bool foundNonBlue = false;
for (int cy = 0; cy < 8 && !failureFound; ++cy) {
int cx = 4; // Just need to check one column;
SkPMColor canvasPixel = canvasPixels[cy * 8 + cx];
// We don't know which way the GPU will snap so the non-blue line could either be at row
// 3 or 4 since we drew the line at a y value of 4. We check that one of those two values
// is green and all the rest are blue. The key thing is that we should not get any red
// values since the green line in the saveLayer should snap the same way and overwrite the
// red line.
if (cy == 3) {
if (canvasPixel != 0xFFFF0000 && canvasPixel != 0xFF00FF00) {
failureFound = true;
ERRORF(reporter, "Wrong color at %d, %d. Got 0x%08x when we expected Blue or Green."
" Origin is: %s",
cx, cy, canvasPixel, GrSurfaceOriginToStr(origin));
}
if (canvasPixel != 0XFFFF0000) {
foundNonBlue = true;
}
} else {
SkPMColor expectedPixel;
if (cy == 4 && !foundNonBlue) {
expectedPixel = 0xFF00FF00; // Green
} else {
expectedPixel = 0xFFFF0000; // Blue
}
if (canvasPixel != expectedPixel) {
failureFound = true;
ERRORF(reporter,
"Wrong color at %d, %d. Got 0x%08x when we expected 0x%08x. Origin is: %s",
cx, cy, canvasPixel, expectedPixel, GrSurfaceOriginToStr(origin));
}
}
}
}
static void run_test(skiatest::Reporter* reporter,
GrDirectContext* context,
GrSurfaceOrigin origin) {
auto beTexture = context->createBackendTexture(8, 8, kRGBA_8888_SkColorType, GrMipmapped::kNo,
GrRenderable::kYes, GrProtected::kNo);
REPORTER_ASSERT(reporter, beTexture.isValid());
if (!beTexture.isValid()) {
return;
}
auto surface = SkSurface::MakeFromBackendTexture(context, beTexture, origin, 0,
kRGBA_8888_SkColorType, nullptr, nullptr);
REPORTER_ASSERT(reporter, surface);
if (!surface) {
return;
}
SkCanvas* canvas = surface->getCanvas();
canvas->clear(SK_ColorBLUE);
SkPaint paint;
paint.setColor(SK_ColorRED);
canvas->drawLine({ 0,4 }, { 8,4 }, paint);
SkRect bounds = SkRect::MakeWH(8, 8);
SkPaint layerPaint;
canvas->saveLayer(bounds, &paint);
paint.setColor(SK_ColorGREEN);
canvas->drawLine({ 0,4 }, { 8,4 }, paint);
canvas->restore();
SkBitmap bitmap;
bitmap.allocPixels(SkImageInfo::Make(8, 8, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
surface->readPixels(bitmap, 0, 0);
check_pixels(reporter, bitmap, origin);
context->deleteBackendTexture(beTexture);
}
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SaveLayerOrigin, reporter, context_info) {
GrDirectContext* context = context_info.directContext();
run_test(reporter, context, kBottomLeft_GrSurfaceOrigin);
run_test(reporter, context, kTopLeft_GrSurfaceOrigin);
}