Reland "Preserve base device origin on saveLayer and image filters"

This reverts commit 814652c373.

Reason for revert: missed suppression has landed in chrome

Original change's description:
> Revert "Preserve base device origin on saveLayer and image filters"
>
> This reverts commit f436cf2343.
>
> Reason for revert: May need to be behind flag or more
> suppressions. Breaking linux-rel vulkan_swiftshader_blink_web_tests
> css3/filters/effect-blur-hw.html .
>
> Original change's description:
> > Preserve base device origin on saveLayer and image filters
> >
> > SaveLayerOriginTest taken from https://skia-review.googlesource.com/c/skia/+/277977
> >
> > Bug: skia:12732
> > Change-Id: I5ce75355bb16237043c229e1cbc7a106eb636d18
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/508919
> > Reviewed-by: Greg Daniel <egdaniel@google.com>
> > Commit-Queue: Michael Ludwig <michaelludwig@google.com>
>
> Bug: skia:12732
> Change-Id: I74cc8dc279d22c4fbd313ae3caeb4d0748daf003
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/510196
> Auto-Submit: Ben Wagner <bungeman@google.com>
> Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
> Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>

Bug: skia:12732
Change-Id: Ifdc3ac96b1b695c208960915ca313fbacf4b7ed6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/510203
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
This commit is contained in:
Michael Ludwig 2022-02-17 17:02:48 +00:00 committed by SkCQ
parent 1f987af388
commit a872718e51
14 changed files with 145 additions and 13 deletions

View File

@ -217,6 +217,7 @@ tests_sources = [
"$_tests/SVGDeviceTest.cpp",
"$_tests/SafeMathTest.cpp",
"$_tests/SamplingTest.cpp",
"$_tests/SaveLayerOriginTest.cpp",
"$_tests/ScalarTest.cpp",
"$_tests/ScaleToSidesTest.cpp",
"$_tests/SerialProcsTest.cpp",

View File

@ -1077,6 +1077,14 @@ static constexpr const char* GrCompressionTypeToStr(SkImage::CompressionType com
}
SkUNREACHABLE;
}
static constexpr const char* GrSurfaceOriginToStr(GrSurfaceOrigin origin) {
switch (origin) {
case kTopLeft_GrSurfaceOrigin: return "kTopLeft";
case kBottomLeft_GrSurfaceOrigin: return "kBottomLeft";
}
SkUNREACHABLE;
}
#endif
#endif

View File

@ -589,6 +589,7 @@ sk_sp<SkSpecialImage> SkImageFilter_Base::DrawWithFP(GrRecordingContext* rContex
SkColorType colorType,
const SkColorSpace* colorSpace,
const SkSurfaceProps& surfaceProps,
GrSurfaceOrigin surfaceOrigin,
GrProtected isProtected) {
GrImageInfo info(SkColorTypeToGrColorType(colorType),
kPremul_SkAlphaType,
@ -600,7 +601,7 @@ sk_sp<SkSpecialImage> SkImageFilter_Base::DrawWithFP(GrRecordingContext* rContex
1,
GrMipmapped::kNo,
isProtected,
kBottomLeft_GrSurfaceOrigin);
surfaceOrigin);
if (!sfc) {
return nullptr;
}

View File

@ -310,6 +310,7 @@ protected:
SkColorType colorType,
const SkColorSpace* colorSpace,
const SkSurfaceProps&,
GrSurfaceOrigin surfaceOrigin,
GrProtected isProtected = GrProtected::kNo);
/**

View File

@ -429,7 +429,7 @@ public:
SkImageInfo ii = SkImageInfo::Make(size, colorType, at, sk_ref_sp(colorSpace));
return SkSpecialSurface::MakeRenderTarget(fContext, ii, props);
return SkSpecialSurface::MakeRenderTarget(fContext, ii, props, fView.origin());
}
sk_sp<SkSpecialImage> onMakeSubset(const SkIRect& subset) const override {
@ -497,7 +497,8 @@ public:
colorType = colorSpace && colorSpace->gammaIsLinear()
? kRGBA_F16_SkColorType : kRGBA_8888_SkColorType;
SkImageInfo info = SkImageInfo::Make(size, colorType, at, sk_ref_sp(colorSpace));
return SkSurface::MakeRenderTarget(fContext, SkBudgeted::kYes, info);
return SkSurface::MakeRenderTarget(
fContext, SkBudgeted::kYes, info, 0, fView.origin(), nullptr);
}
private:

View File

@ -157,14 +157,15 @@ private:
sk_sp<SkSpecialSurface> SkSpecialSurface::MakeRenderTarget(GrRecordingContext* rContext,
const SkImageInfo& ii,
const SkSurfaceProps& props) {
const SkSurfaceProps& props,
GrSurfaceOrigin surfaceOrigin) {
if (!rContext) {
return nullptr;
}
auto device = rContext->priv().createDevice(SkBudgeted::kYes, ii, SkBackingFit::kApprox, 1,
GrMipmapped::kNo, GrProtected::kNo,
kBottomLeft_GrSurfaceOrigin, props,
surfaceOrigin, props,
skgpu::BaseDevice::InitContents::kUninit);
if (!device) {
return nullptr;

View File

@ -62,7 +62,8 @@ public:
*/
static sk_sp<SkSpecialSurface> MakeRenderTarget(GrRecordingContext*,
const SkImageInfo&,
const SkSurfaceProps&);
const SkSurfaceProps&,
GrSurfaceOrigin);
#endif
/**

View File

@ -193,6 +193,7 @@ sk_sp<SkSpecialImage> SkAlphaThresholdImageFilter::onFilterImage(const Context&
GrSurfaceProxyView inputView = (input->view(context));
SkASSERT(inputView.asTextureProxy());
const GrProtected isProtected = inputView.proxy()->isProtected();
const GrSurfaceOrigin origin = inputView.origin();
offset->fX = bounds.left();
offset->fY = bounds.top();
@ -227,7 +228,7 @@ sk_sp<SkSpecialImage> SkAlphaThresholdImageFilter::onFilterImage(const Context&
}
return DrawWithFP(context, std::move(thresholdFP), bounds, ctx.colorType(),
ctx.colorSpace(), ctx.surfaceProps(), isProtected);
ctx.colorSpace(), ctx.surfaceProps(), origin, isProtected);
}
#endif

View File

@ -176,6 +176,7 @@ sk_sp<SkSpecialImage> SkMagnifierImageFilter::onFilterImage(const Context& ctx,
SkASSERT(inputView.asTextureProxy());
const auto isProtected = inputView.proxy()->isProtected();
const auto origin = inputView.origin();
offset->fX = bounds.left();
offset->fY = bounds.top();
@ -204,7 +205,7 @@ sk_sp<SkSpecialImage> SkMagnifierImageFilter::onFilterImage(const Context& ctx,
}
return DrawWithFP(context, std::move(fp), bounds, ctx.colorType(), ctx.colorSpace(),
ctx.surfaceProps(), isProtected);
ctx.surfaceProps(), origin, isProtected);
}
#endif

View File

@ -372,6 +372,7 @@ sk_sp<SkSpecialImage> SkMatrixConvolutionImageFilter::onFilterImage(const Contex
SkASSERT(inputView.asTextureProxy());
const auto isProtected = inputView.proxy()->isProtected();
const auto origin = inputView.origin();
offset->fX = dstBounds.left();
offset->fY = dstBounds.top();
@ -403,7 +404,7 @@ sk_sp<SkSpecialImage> SkMatrixConvolutionImageFilter::onFilterImage(const Contex
// evaluating the FP, and the dst rect just uses the size of dstBounds.
dstBounds.offset(input->subset().x(), input->subset().y());
return DrawWithFP(context, std::move(fp), dstBounds, ctx.colorType(), ctx.colorSpace(),
ctx.surfaceProps(), isProtected);
ctx.surfaceProps(), origin, isProtected);
}
#endif

View File

@ -1088,7 +1088,8 @@ SkBaseDevice* Device::onCreateDevice(const CreateInfo& cinfo, const SkPaint*) {
fContext.get(), SkColorTypeToGrColorType(cinfo.fInfo.colorType()),
fSurfaceDrawContext->colorInfo().refColorSpace(), fit, cinfo.fInfo.dimensions(), props,
fSurfaceDrawContext->numSamples(), GrMipmapped::kNo,
fSurfaceDrawContext->asSurfaceProxy()->isProtected(), kBottomLeft_GrSurfaceOrigin,
fSurfaceDrawContext->asSurfaceProxy()->isProtected(),
fSurfaceDrawContext->origin(),
SkBudgeted::kYes);
if (!sdc) {
return nullptr;

View File

@ -26,6 +26,7 @@
#include "src/core/SkSpecialSurface.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/image/SkImage_Base.h"
#include "tests/Test.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"
@ -34,6 +35,8 @@ static const int kBitmapSize = 4;
namespace {
static constexpr GrSurfaceOrigin kTestSurfaceOrigin = kTopLeft_GrSurfaceOrigin;
class MatrixTestImageFilter : public SkImageFilter_Base {
public:
static sk_sp<SkImageFilter> Make(skiatest::Reporter* reporter,
@ -337,7 +340,8 @@ static sk_sp<SkSpecialSurface> create_empty_special_surface(GrRecordingContext*
kPremul_SkAlphaType);
if (rContext) {
return SkSpecialSurface::MakeRenderTarget(rContext, ii, SkSurfaceProps());
return SkSpecialSurface::MakeRenderTarget(rContext, ii, SkSurfaceProps(),
kTestSurfaceOrigin);
} else {
return SkSpecialSurface::MakeRaster(ii, SkSurfaceProps());
}
@ -346,7 +350,8 @@ static sk_sp<SkSpecialSurface> create_empty_special_surface(GrRecordingContext*
static sk_sp<SkSurface> create_surface(GrRecordingContext* rContext, int width, int height) {
const SkImageInfo info = SkImageInfo::MakeN32(width, height, kOpaque_SkAlphaType);
if (rContext) {
return SkSurface::MakeRenderTarget(rContext, SkBudgeted::kNo, info);
return SkSurface::MakeRenderTarget(rContext, SkBudgeted::kNo, info,
0, kTestSurfaceOrigin, nullptr);
} else {
return SkSurface::MakeRaster(info);
}
@ -1738,6 +1743,13 @@ static void test_make_with_filter(skiatest::Reporter* reporter, GrRecordingConte
result = sourceImage->makeWithFilter(rContext, filter.get(), subset, clipBounds,
&outSubset, &offset);
REPORTER_ASSERT(reporter, result);
// In GPU-mode, we want the result image (and all intermediate steps) to have used the same
// origin as the original surface.
if (rContext) {
auto [proxyView, _] = as_IB(result)->asView(rContext, GrMipmapped::kNo);
REPORTER_ASSERT(reporter, proxyView && proxyView.origin() == kTestSurfaceOrigin);
}
}
}

View File

@ -0,0 +1,101 @@
/*
* 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/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);
}

View File

@ -87,7 +87,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialSurface_Gpu1, reporter, ctxInfo) {
SkImageInfo ii = SkImageInfo::Make({ kSmallerSize, kSmallerSize }, colorType,
kPremul_SkAlphaType);
auto surf(SkSpecialSurface::MakeRenderTarget(dContext, ii, SkSurfaceProps()));
auto surf(SkSpecialSurface::MakeRenderTarget(dContext, ii, SkSurfaceProps(),
kTopLeft_GrSurfaceOrigin));
test_surface(surf, reporter, 0);
}
}