From af5f9f008de060a91d8069c876a765f11c3d36f6 Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Thu, 20 Feb 2020 14:21:38 -0500 Subject: [PATCH] Remove GrDeviceSpaceTextureDecalFragmentProcessor. It was used to sample clip masks using device coords. Replace with a more generic GrDeviceSpaceEffect that simply calls a child FP with sk_FragCoord. Also fix issue in GrQuadPerEdgeAA GP. It wouldn't setup coord transforms at all if they are all applied in the FS (explicit coords). Moreover, the GrGLSLGeometryProcessor::emitTransforms() helper required a valid VS var for local coords even when all FPs use explicit coords and wouldn't use a local coords var. Make CPP SkSL code gen for clone copy the explicit coord status of children. Change-Id: Ib8bb36028354405c8012f6e91e9eb46db75d16a6 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271658 Commit-Queue: Brian Salomon Reviewed-by: Brian Osman --- gm/windowrectangles.cpp | 15 ++- gn/gpu.gni | 2 + gn/sksl.gni | 1 + src/gpu/GrClipStackClip.cpp | 24 +++- src/gpu/GrProcessor.h | 2 +- src/gpu/effects/GrDeviceSpaceEffect.fp | 22 ++++ src/gpu/effects/GrTextureDomain.cpp | 120 ------------------ src/gpu/effects/GrTextureDomain.h | 43 ------- .../effects/generated/GrDeviceSpaceEffect.cpp | 71 +++++++++++ .../effects/generated/GrDeviceSpaceEffect.h | 42 ++++++ 10 files changed, 168 insertions(+), 174 deletions(-) create mode 100644 src/gpu/effects/GrDeviceSpaceEffect.fp create mode 100644 src/gpu/effects/generated/GrDeviceSpaceEffect.cpp create mode 100644 src/gpu/effects/generated/GrDeviceSpaceEffect.h diff --git a/gm/windowrectangles.cpp b/gm/windowrectangles.cpp index b14d137373..1244b90b0c 100644 --- a/gm/windowrectangles.cpp +++ b/gm/windowrectangles.cpp @@ -33,6 +33,7 @@ #include "src/gpu/GrFixedClip.h" #include "src/gpu/GrFragmentProcessor.h" #include "src/gpu/GrPaint.h" +#include "src/gpu/GrRecordingContextPriv.h" #include "src/gpu/GrReducedClip.h" #include "src/gpu/GrRenderTargetContext.h" #include "src/gpu/GrRenderTargetContextPriv.h" @@ -40,6 +41,7 @@ #include "src/gpu/GrTextureProxy.h" #include "src/gpu/GrUserStencilSettings.h" #include "src/gpu/effects/GrTextureDomain.h" +#include "src/gpu/effects/generated/GrDeviceSpaceEffect.h" #include "tools/ToolUtils.h" #include @@ -177,10 +179,17 @@ public: AlphaOnlyClip(GrSurfaceProxyView mask, int x, int y) : fMask(std::move(mask)), fX(x), fY(y) {} private: - bool apply(GrRecordingContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip* out, + bool apply(GrRecordingContext* ctx, GrRenderTargetContext*, bool, bool, GrAppliedClip* out, SkRect* bounds) const override { - out->addCoverageFP(GrDeviceSpaceTextureDecalFragmentProcessor::Make( - fMask, SkIRect::MakeSize(fMask.proxy()->dimensions()), {fX, fY})); + GrSamplerState samplerState(GrSamplerState::WrapMode::kClampToBorder, + GrSamplerState::Filter::kNearest); + auto m = SkMatrix::MakeTrans(-fX, -fY); + auto subset = SkRect::Make(fMask.dimensions()); + auto domain = bounds->makeOffset(-fX, -fY).makeInset(0.5, 0.5); + auto fp = GrTextureEffect::MakeSubset(fMask, kPremul_SkAlphaType, m, samplerState, subset, + domain, *ctx->priv().caps()); + fp = GrDeviceSpaceEffect::Make(std::move(fp)); + out->addCoverageFP(std::move(fp)); return true; } GrSurfaceProxyView fMask; diff --git a/gn/gpu.gni b/gn/gpu.gni index 6be74098f0..f30a97f979 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -374,6 +374,8 @@ skia_gpu_sources = [ "$_src/gpu/effects/generated/GrConstColorProcessor.h", "$_src/gpu/effects/generated/GrEllipseEffect.cpp", "$_src/gpu/effects/generated/GrEllipseEffect.h", + "$_src/gpu/effects/generated/GrDeviceSpaceEffect.cpp", + "$_src/gpu/effects/generated/GrDeviceSpaceEffect.h", "$_src/gpu/effects/generated/GrHSLToRGBFilterEffect.cpp", "$_src/gpu/effects/generated/GrHSLToRGBFilterEffect.h", "$_src/gpu/effects/generated/GrLumaColorFilterEffect.cpp", diff --git a/gn/sksl.gni b/gn/sksl.gni index a692166b5b..7ad737a33d 100644 --- a/gn/sksl.gni +++ b/gn/sksl.gni @@ -47,6 +47,7 @@ skia_gpu_processor_sources = [ "$_src/gpu/effects/GrConfigConversionEffect.fp", "$_src/gpu/effects/GrConstColorProcessor.fp", "$_src/gpu/effects/GrColorMatrixFragmentProcessor.fp", + "$_src/gpu/effects/GrDeviceSpaceEffect.fp", "$_src/gpu/effects/GrEllipseEffect.fp", "$_src/gpu/effects/GrHSLToRGBFilterEffect.fp", "$_src/gpu/effects/GrLumaColorFilterEffect.fp", diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp index 2c5a941288..66f2de8461 100644 --- a/src/gpu/GrClipStackClip.cpp +++ b/src/gpu/GrClipStackClip.cpp @@ -5,12 +5,13 @@ * found in the LICENSE file. */ +#include "src/gpu/GrClipStackClip.h" + #include "include/private/SkTo.h" #include "src/core/SkClipOpPriv.h" #include "src/core/SkTaskGroup.h" #include "src/core/SkTraceEvent.h" #include "src/gpu/GrAppliedClip.h" -#include "src/gpu/GrClipStackClip.h" #include "src/gpu/GrContextPriv.h" #include "src/gpu/GrDeferredProxyUploader.h" #include "src/gpu/GrDrawingManager.h" @@ -26,6 +27,7 @@ #include "src/gpu/effects/GrConvexPolyEffect.h" #include "src/gpu/effects/GrRRectEffect.h" #include "src/gpu/effects/GrTextureDomain.h" +#include "src/gpu/effects/generated/GrDeviceSpaceEffect.h" #include "src/gpu/geometry/GrShape.h" typedef SkClipStack::Element Element; @@ -78,11 +80,18 @@ void GrClipStackClip::getConservativeBounds(int width, int height, SkIRect* devR //////////////////////////////////////////////////////////////////////////////// // set up the draw state to enable the aa clipping mask. static std::unique_ptr create_fp_for_mask(GrSurfaceProxyView mask, - const SkIRect& devBound) { - SkASSERT(mask.asTextureProxy()); - SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); - return GrDeviceSpaceTextureDecalFragmentProcessor::Make(std::move(mask), domainTexels, - {devBound.fLeft, devBound.fTop}); + const SkIRect& devBound, + const GrCaps& caps) { + GrSamplerState samplerState(GrSamplerState::WrapMode::kClampToBorder, + GrSamplerState::Filter::kNearest); + auto m = SkMatrix::MakeTrans(-devBound.fLeft, -devBound.fTop); + auto subset = SkRect::Make(devBound.size()); + // We scissor to devBounds. The mask's texel centers are aligned to device space + // pixel centers. Hence this domain of texture coordinates. + auto domain = subset.makeInset(0.5, 0.5); + auto fp = GrTextureEffect::MakeSubset(std::move(mask), kPremul_SkAlphaType, m, samplerState, + subset, domain, caps); + return GrDeviceSpaceEffect::Make(std::move(fp)); } // Does the path in 'element' require SW rendering? If so, return true (and, @@ -283,7 +292,8 @@ bool GrClipStackClip::applyClipMask(GrRecordingContext* context, if (result) { // The mask's top left coord should be pinned to the rounded-out top left corner of // the clip's device space bounds. - out->addCoverageFP(create_fp_for_mask(std::move(result), reducedClip.scissor())); + out->addCoverageFP(create_fp_for_mask(std::move(result), reducedClip.scissor(), + *context->priv().caps())); return true; } diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h index 3274a148d5..40693446b3 100644 --- a/src/gpu/GrProcessor.h +++ b/src/gpu/GrProcessor.h @@ -101,7 +101,7 @@ public: kGrConicEffect_ClassID, kGrConstColorProcessor_ClassID, kGrConvexPolyEffect_ClassID, - kGrDeviceSpaceTextureDecalFragmentProcessor_ClassID, + kGrDeviceSpaceEffect_ClassID, kGrDiffuseLightingEffect_ClassID, kGrDisplacementMapEffect_ClassID, kGrDistanceFieldA8TextGeoProc_ClassID, diff --git a/src/gpu/effects/GrDeviceSpaceEffect.fp b/src/gpu/effects/GrDeviceSpaceEffect.fp new file mode 100644 index 0000000000..d817ec2b19 --- /dev/null +++ b/src/gpu/effects/GrDeviceSpaceEffect.fp @@ -0,0 +1,22 @@ +/* +* Copyright 2020 Google LLC +* +* Use of this source code is governed by a BSD-style license that can be +* found in the LICENSE file. +*/ + +in fragmentProcessor fp; + +void main() { + sk_OutColor = sample(fp, sk_InColor, sk_FragCoord.xy); +} + +@test(d) { + std::unique_ptr fp; + // We have a restriction that explicit coords only work for FPs with exactly one + // coord transform. + do { + fp = GrProcessorUnitTest::MakeChildFP(d); + } while (fp->numCoordTransforms() != 1); + return GrDeviceSpaceEffect::Make(std::move(fp)); +} diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp index 59c3dfa66c..9d8202c41d 100644 --- a/src/gpu/effects/GrTextureDomain.cpp +++ b/src/gpu/effects/GrTextureDomain.cpp @@ -314,123 +314,3 @@ void GrTextureDomain::GLDomain::setData(const GrGLSLProgramDataManager& pdman, std::copy_n(decalFilterWeights, 3, fPrevDeclFilterWeights); } } - -/////////////////////////////////////////////////////////////////////////////// - -std::unique_ptr GrDeviceSpaceTextureDecalFragmentProcessor::Make( - GrSurfaceProxyView view, const SkIRect& subset, const SkIPoint& deviceSpaceOffset) { - return std::unique_ptr(new GrDeviceSpaceTextureDecalFragmentProcessor( - std::move(view), subset, deviceSpaceOffset)); -} - -GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentProcessor( - GrSurfaceProxyView view, const SkIRect& subset, const SkIPoint& deviceSpaceOffset) - : INHERITED(kGrDeviceSpaceTextureDecalFragmentProcessor_ClassID, - kCompatibleWithCoverageAsAlpha_OptimizationFlag) - , fTextureDomain(view.proxy(), - GrTextureDomain::MakeTexelDomain(subset, GrTextureDomain::kDecal_Mode), - GrTextureDomain::kDecal_Mode, GrTextureDomain::kDecal_Mode) - , fTextureSampler(std::move(view), GrSamplerState::Filter::kNearest) { - this->setTextureSamplerCnt(1); - fDeviceSpaceOffset.fX = deviceSpaceOffset.fX - subset.fLeft; - fDeviceSpaceOffset.fY = deviceSpaceOffset.fY - subset.fTop; -} - -GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentProcessor( - const GrDeviceSpaceTextureDecalFragmentProcessor& that) - : INHERITED(kGrDeviceSpaceTextureDecalFragmentProcessor_ClassID, - kCompatibleWithCoverageAsAlpha_OptimizationFlag) - , fTextureDomain(that.fTextureDomain) - , fTextureSampler(that.fTextureSampler) - , fDeviceSpaceOffset(that.fDeviceSpaceOffset) { - this->setTextureSamplerCnt(1); -} - -std::unique_ptr GrDeviceSpaceTextureDecalFragmentProcessor::clone() const { - return std::unique_ptr( - new GrDeviceSpaceTextureDecalFragmentProcessor(*this)); -} - -GrGLSLFragmentProcessor* GrDeviceSpaceTextureDecalFragmentProcessor::onCreateGLSLInstance() const { - class GLSLProcessor : public GrGLSLFragmentProcessor { - public: - void emitCode(EmitArgs& args) override { - const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp = - args.fFp.cast(); - const char* scaleAndTranslateName; - fScaleAndTranslateUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, - kHalf4_GrSLType, - "scaleAndTranslate", - &scaleAndTranslateName); - args.fFragBuilder->codeAppendf("half2 coords = half2(sk_FragCoord.xy * %s.xy + %s.zw);", - scaleAndTranslateName, scaleAndTranslateName); - fGLDomain.sampleTexture(args.fFragBuilder, - args.fUniformHandler, - args.fShaderCaps, - dstdfp.fTextureDomain, - args.fOutputColor, - SkString("coords"), - args.fTexSamplers[0], - args.fInputColor); - } - - protected: - void onSetData(const GrGLSLProgramDataManager& pdman, - const GrFragmentProcessor& fp) override { - const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp = - fp.cast(); - const auto& view = dstdfp.textureSampler(0).view(); - SkISize textureDims = view.proxy()->backingStoreDimensions(); - - fGLDomain.setData(pdman, dstdfp.fTextureDomain, view, - dstdfp.textureSampler(0).samplerState()); - float iw = 1.f / textureDims.width(); - float ih = 1.f / textureDims.height(); - float scaleAndTransData[4] = { - iw, ih, - -dstdfp.fDeviceSpaceOffset.fX * iw, -dstdfp.fDeviceSpaceOffset.fY * ih - }; - if (view.origin() == kBottomLeft_GrSurfaceOrigin) { - scaleAndTransData[1] = -scaleAndTransData[1]; - scaleAndTransData[3] = 1 - scaleAndTransData[3]; - } - pdman.set4fv(fScaleAndTranslateUni, 1, scaleAndTransData); - } - - private: - GrTextureDomain::GLDomain fGLDomain; - UniformHandle fScaleAndTranslateUni; - }; - - return new GLSLProcessor; -} - -bool GrDeviceSpaceTextureDecalFragmentProcessor::onIsEqual(const GrFragmentProcessor& fp) const { - const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp = - fp.cast(); - return dstdfp.fTextureSampler.view().proxy()->underlyingUniqueID() == - fTextureSampler.view().proxy()->underlyingUniqueID() && - dstdfp.fDeviceSpaceOffset == fDeviceSpaceOffset && - dstdfp.fTextureDomain == fTextureDomain; -} - -/////////////////////////////////////////////////////////////////////////////// - -GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDeviceSpaceTextureDecalFragmentProcessor); - -#if GR_TEST_UTILS -std::unique_ptr GrDeviceSpaceTextureDecalFragmentProcessor::TestCreate( - GrProcessorTestData* d) { - auto [view, at, ct] = d->randomView(); - SkIRect subset; - subset.fLeft = d->fRandom->nextULessThan(view.width() - 1); - subset.fRight = d->fRandom->nextRangeU(subset.fLeft, view.width()); - subset.fTop = d->fRandom->nextULessThan(view.height() - 1); - subset.fBottom = d->fRandom->nextRangeU(subset.fTop, view.height()); - SkIPoint pt; - pt.fX = d->fRandom->nextULessThan(2048); - pt.fY = d->fRandom->nextULessThan(2048); - - return GrDeviceSpaceTextureDecalFragmentProcessor::Make(std::move(view), subset, pt); -} -#endif diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h index c9a563a756..e88c4c2ab8 100644 --- a/src/gpu/effects/GrTextureDomain.h +++ b/src/gpu/effects/GrTextureDomain.h @@ -231,47 +231,4 @@ protected: int fIndex; }; -class GrDeviceSpaceTextureDecalFragmentProcessor : public GrFragmentProcessor { -public: - static std::unique_ptr Make(GrSurfaceProxyView, - const SkIRect& subset, - const SkIPoint& deviceSpaceOffset); - - const char* name() const override { return "GrDeviceSpaceTextureDecalFragmentProcessor"; } - -#ifdef SK_DEBUG - SkString dumpInfo() const override { - SkString str; - str.appendf("Domain: [L: %.2f, T: %.2f, R: %.2f, B: %.2f] Offset: [%d %d]", - fTextureDomain.domain().fLeft, fTextureDomain.domain().fTop, - fTextureDomain.domain().fRight, fTextureDomain.domain().fBottom, - fDeviceSpaceOffset.fX, fDeviceSpaceOffset.fY); - str.append(INHERITED::dumpInfo()); - return str; - } -#endif - - std::unique_ptr clone() const override; - -private: - GrTextureDomain fTextureDomain; - TextureSampler fTextureSampler; - SkIPoint fDeviceSpaceOffset; - - GrDeviceSpaceTextureDecalFragmentProcessor(GrSurfaceProxyView, const SkIRect&, const SkIPoint&); - GrDeviceSpaceTextureDecalFragmentProcessor(const GrDeviceSpaceTextureDecalFragmentProcessor&); - - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; - - // Since we always use decal mode, there is no need for key data. - void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} - - bool onIsEqual(const GrFragmentProcessor& fp) const override; - - const TextureSampler& onTextureSampler(int) const override { return fTextureSampler; } - - GR_DECLARE_FRAGMENT_PROCESSOR_TEST - - typedef GrFragmentProcessor INHERITED; -}; #endif diff --git a/src/gpu/effects/generated/GrDeviceSpaceEffect.cpp b/src/gpu/effects/generated/GrDeviceSpaceEffect.cpp new file mode 100644 index 0000000000..8df3a1b853 --- /dev/null +++ b/src/gpu/effects/generated/GrDeviceSpaceEffect.cpp @@ -0,0 +1,71 @@ +/* + * Copyright 2020 Google LLC + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/************************************************************************************************** + *** This file was autogenerated from GrDeviceSpaceEffect.fp; do not modify. + **************************************************************************************************/ +#include "GrDeviceSpaceEffect.h" + +#include "include/gpu/GrTexture.h" +#include "src/gpu/glsl/GrGLSLFragmentProcessor.h" +#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" +#include "src/gpu/glsl/GrGLSLProgramBuilder.h" +#include "src/sksl/SkSLCPP.h" +#include "src/sksl/SkSLUtil.h" +class GrGLSLDeviceSpaceEffect : public GrGLSLFragmentProcessor { +public: + GrGLSLDeviceSpaceEffect() {} + void emitCode(EmitArgs& args) override { + GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; + const GrDeviceSpaceEffect& _outer = args.fFp.cast(); + (void)_outer; + SkString _input204 = SkStringPrintf("%s", args.fInputColor); + SkString _sample204; + SkString _coords204("sk_FragCoord.xy"); + _sample204 = + this->invokeChild(_outer.fp_index, _input204.c_str(), args, _coords204.c_str()); + fragBuilder->codeAppendf("%s = %s;\n", args.fOutputColor, _sample204.c_str()); + } + +private: + void onSetData(const GrGLSLProgramDataManager& pdman, + const GrFragmentProcessor& _proc) override {} +}; +GrGLSLFragmentProcessor* GrDeviceSpaceEffect::onCreateGLSLInstance() const { + return new GrGLSLDeviceSpaceEffect(); +} +void GrDeviceSpaceEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, + GrProcessorKeyBuilder* b) const {} +bool GrDeviceSpaceEffect::onIsEqual(const GrFragmentProcessor& other) const { + const GrDeviceSpaceEffect& that = other.cast(); + (void)that; + return true; +} +GrDeviceSpaceEffect::GrDeviceSpaceEffect(const GrDeviceSpaceEffect& src) + : INHERITED(kGrDeviceSpaceEffect_ClassID, src.optimizationFlags()), fp_index(src.fp_index) { + { + auto clone = src.childProcessor(fp_index).clone(); + clone->setSampledWithExplicitCoords( + src.childProcessor(fp_index).isSampledWithExplicitCoords()); + this->registerChildProcessor(std::move(clone)); + } +} +std::unique_ptr GrDeviceSpaceEffect::clone() const { + return std::unique_ptr(new GrDeviceSpaceEffect(*this)); +} +GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDeviceSpaceEffect); +#if GR_TEST_UTILS +std::unique_ptr GrDeviceSpaceEffect::TestCreate(GrProcessorTestData* d) { + std::unique_ptr fp; + // We have a restriction that explicit coords only work for FPs with exactly one + // coord transform. + do { + fp = GrProcessorUnitTest::MakeChildFP(d); + } while (fp->numCoordTransforms() != 1); + return GrDeviceSpaceEffect::Make(std::move(fp)); +} +#endif diff --git a/src/gpu/effects/generated/GrDeviceSpaceEffect.h b/src/gpu/effects/generated/GrDeviceSpaceEffect.h new file mode 100644 index 0000000000..fa51755d2a --- /dev/null +++ b/src/gpu/effects/generated/GrDeviceSpaceEffect.h @@ -0,0 +1,42 @@ +/* + * Copyright 2020 Google LLC + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/************************************************************************************************** + *** This file was autogenerated from GrDeviceSpaceEffect.fp; do not modify. + **************************************************************************************************/ +#ifndef GrDeviceSpaceEffect_DEFINED +#define GrDeviceSpaceEffect_DEFINED +#include "include/core/SkTypes.h" +#include "include/private/SkM44.h" + +#include "src/gpu/GrCoordTransform.h" +#include "src/gpu/GrFragmentProcessor.h" +class GrDeviceSpaceEffect : public GrFragmentProcessor { +public: + static std::unique_ptr Make(std::unique_ptr fp) { + return std::unique_ptr(new GrDeviceSpaceEffect(std::move(fp))); + } + GrDeviceSpaceEffect(const GrDeviceSpaceEffect& src); + std::unique_ptr clone() const override; + const char* name() const override { return "DeviceSpaceEffect"; } + int fp_index = -1; + +private: + GrDeviceSpaceEffect(std::unique_ptr fp) + : INHERITED(kGrDeviceSpaceEffect_ClassID, kNone_OptimizationFlags) { + SkASSERT(fp); + fp_index = this->numChildProcessors(); + fp->setSampledWithExplicitCoords(true); + this->registerChildProcessor(std::move(fp)); + } + GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; + void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; + bool onIsEqual(const GrFragmentProcessor&) const override; + GR_DECLARE_FRAGMENT_PROCESSOR_TEST + typedef GrFragmentProcessor INHERITED; +}; +#endif