diff options
author | Brian Salomon <bsalomon@google.com> | 2017-01-27 10:59:27 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-01-27 16:43:38 +0000 |
commit | 587e08f361ee3e775a6bbc6dca761dbba82e422c (patch) | |
tree | 9f64e10d50fab820419d29dea30a6c978c86c8c9 /src/gpu/effects | |
parent | 4d3adb6b0dea1c9f74fc00b007dfb1af425fc727 (diff) |
Revert "Revert "Start of rewrite of GrFragmentProcessor optimizations.""
This reverts commit 052fd5158f7f85e478a9f87c45fecaacf7d0f5f3.
Disables the test (of unused code) until platform-specific issues are addressed.
Change-Id: I7aa23a07954fccf382aa07d28afcbffb0bebcd6d
Reviewed-on: https://skia-review.googlesource.com/7656
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/gpu/effects')
20 files changed, 269 insertions, 124 deletions
diff --git a/src/gpu/effects/Gr1DKernelEffect.h b/src/gpu/effects/Gr1DKernelEffect.h index 29e0e5dec2..67cc771c61 100644 --- a/src/gpu/effects/Gr1DKernelEffect.h +++ b/src/gpu/effects/Gr1DKernelEffect.h @@ -28,12 +28,11 @@ public: kY_Direction, }; - Gr1DKernelEffect(GrTexture* texture, - Direction direction, - int radius) - : INHERITED(texture, nullptr, SkMatrix::I()) - , fDirection(direction) - , fRadius(radius) {} + Gr1DKernelEffect(GrTexture* texture, Direction direction, int radius, + OptimizationFlags optFlags) + : INHERITED(texture, nullptr, SkMatrix::I(), optFlags) + , fDirection(direction) + , fRadius(radius) {} virtual ~Gr1DKernelEffect() {} @@ -51,7 +50,6 @@ public: } private: - Direction fDirection; int fRadius; diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp index 07d1c53011..cf3d2b5e79 100644 --- a/src/gpu/effects/GrBicubicEffect.cpp +++ b/src/gpu/effects/GrBicubicEffect.cpp @@ -132,21 +132,23 @@ void GrGLBicubicEffect::onSetData(const GrGLSLProgramDataManager& pdman, GrBicubicEffect::GrBicubicEffect(GrTexture* texture, sk_sp<GrColorSpaceXform> colorSpaceXform, - const SkMatrix &matrix, + const SkMatrix& matrix, const SkShader::TileMode tileModes[2]) - : INHERITED(texture, std::move(colorSpaceXform), matrix, - GrSamplerParams(tileModes, GrSamplerParams::kNone_FilterMode)) - , fDomain(GrTextureDomain::IgnoredDomain()) { + : INHERITED(texture, std::move(colorSpaceXform), matrix, + GrSamplerParams(tileModes, GrSamplerParams::kNone_FilterMode), + ModulationFlags(texture->config())) + , fDomain(GrTextureDomain::IgnoredDomain()) { this->initClassID<GrBicubicEffect>(); } GrBicubicEffect::GrBicubicEffect(GrTexture* texture, sk_sp<GrColorSpaceXform> colorSpaceXform, - const SkMatrix &matrix, + const SkMatrix& matrix, const SkRect& domain) - : INHERITED(texture, std::move(colorSpaceXform), matrix, - GrSamplerParams(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode)) - , fDomain(texture, domain, GrTextureDomain::kClamp_Mode) { + : INHERITED(texture, std::move(colorSpaceXform), matrix, + GrSamplerParams(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode), + ModulationFlags(texture->config())) + , fDomain(texture, domain, GrTextureDomain::kClamp_Mode) { this->initClassID<GrBicubicEffect>(); } diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp index 2380ad3435..74cf2ca44f 100644 --- a/src/gpu/effects/GrConfigConversionEffect.cpp +++ b/src/gpu/effects/GrConfigConversionEffect.cpp @@ -98,9 +98,9 @@ GrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture, const GrSwizzle& swizzle, PMConversion pmConversion, const SkMatrix& matrix) - : INHERITED(texture, nullptr, matrix) - , fSwizzle(swizzle) - , fPMConversion(pmConversion) { + : INHERITED(texture, nullptr, matrix, ModulationFlags(texture->config())) + , fSwizzle(swizzle) + , fPMConversion(pmConversion) { this->initClassID<GrConfigConversionEffect>(); // We expect to get here with non-BGRA/RGBA only if we're doing not doing a premul/unpremul // conversion. @@ -116,7 +116,7 @@ GrConfigConversionEffect::GrConfigConversionEffect(GrContext* context, const GrSwizzle& swizzle, PMConversion pmConversion, const SkMatrix& matrix) - : INHERITED(context, proxy, nullptr, matrix) + : INHERITED(context, ModulationFlags(proxy->config()), proxy, nullptr, matrix) , fSwizzle(swizzle) , fPMConversion(pmConversion) { this->initClassID<GrConfigConversionEffect>(); diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h index 46180bb2f2..151365b9b0 100644 --- a/src/gpu/effects/GrConfigConversionEffect.h +++ b/src/gpu/effects/GrConfigConversionEffect.h @@ -52,7 +52,6 @@ public: static void TestForPreservingPMConversions(GrContext* context, PMConversion* PMToUPMRule, PMConversion* UPMToPMRule); - private: GrConfigConversionEffect(GrTexture*, const GrSwizzle&, PMConversion, const SkMatrix& matrix); diff --git a/src/gpu/effects/GrConstColorProcessor.cpp b/src/gpu/effects/GrConstColorProcessor.cpp index e6568793df..3875ffcaa0 100644 --- a/src/gpu/effects/GrConstColorProcessor.cpp +++ b/src/gpu/effects/GrConstColorProcessor.cpp @@ -85,6 +85,19 @@ void GrConstColorProcessor::onComputeInvariantOutput(GrInvariantOutput* inout) c } } +GrColor4f GrConstColorProcessor::constantOutputForConstantInput(GrColor4f input) const { + switch (fMode) { + case kIgnore_InputMode: + return fColor; + case kModulateA_InputMode: + return fColor.mulByScalar(input.fRGBA[3]); + case kModulateRGBA_InputMode: + return fColor.modulate(input); + } + SkFAIL("Unexpected mode"); + return GrColor4f::TransparentBlack(); +} + void GrConstColorProcessor::onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const { b->add32(fMode); diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp index 65ed87b687..4100a0fce2 100644 --- a/src/gpu/effects/GrConvexPolyEffect.cpp +++ b/src/gpu/effects/GrConvexPolyEffect.cpp @@ -32,7 +32,7 @@ public: private: AARectEffect(GrPrimitiveEdgeType edgeType, const SkRect& rect) - : fRect(rect), fEdgeType(edgeType) { + : INHERITED(kModulatesInput_OptimizationFlag), fRect(rect), fEdgeType(edgeType) { this->initClassID<AARectEffect>(); } @@ -339,8 +339,7 @@ GrGLSLFragmentProcessor* GrConvexPolyEffect::onCreateGLSLInstance() const { } GrConvexPolyEffect::GrConvexPolyEffect(GrPrimitiveEdgeType edgeType, int n, const SkScalar edges[]) - : fEdgeType(edgeType) - , fEdgeCount(n) { + : INHERITED(kModulatesInput_OptimizationFlag), fEdgeType(edgeType), fEdgeCount(n) { this->initClassID<GrConvexPolyEffect>(); // Factory function should have already ensured this. SkASSERT(n <= kMaxEdges); diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp index 2ba47d2e09..24e3ba6d50 100644 --- a/src/gpu/effects/GrDitherEffect.cpp +++ b/src/gpu/effects/GrDitherEffect.cpp @@ -26,9 +26,7 @@ public: const char* name() const override { return "Dither"; } private: - DitherEffect() { - this->initClassID<DitherEffect>(); - } + DitherEffect() : INHERITED(kNone_OptimizationFlags) { this->initClassID<DitherEffect>(); } GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; diff --git a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp index 91301ff9ac..be6d4d8302 100644 --- a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp +++ b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp @@ -150,7 +150,8 @@ GrGaussianConvolutionFragmentProcessor::GrGaussianConvolutionFragmentProcessor(G float gaussianSigma, bool useBounds, float bounds[2]) - : INHERITED(texture, direction, radius), fUseBounds(useBounds) { + : INHERITED(texture, direction, radius, ModulationFlags(texture->config())) + , fUseBounds(useBounds) { this->initClassID<GrGaussianConvolutionFragmentProcessor>(); SkASSERT(radius <= kMaxKernelRadius); int width = this->width(); diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp index 01fc6cec9c..9b670e120f 100644 --- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp +++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp @@ -156,12 +156,14 @@ GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture, const SkIPoint& kernelOffset, GrTextureDomain::Mode tileMode, bool convolveAlpha) - : INHERITED(texture, nullptr, SkMatrix::I()), - fKernelSize(kernelSize), - fGain(SkScalarToFloat(gain)), - fBias(SkScalarToFloat(bias) / 255.0f), - fConvolveAlpha(convolveAlpha), - fDomain(texture, GrTextureDomain::MakeTexelDomainForMode(bounds, tileMode), tileMode) { + // To advertise either the modulation or opaqueness optimizations we'd have to examine the + // parameters. + : INHERITED(texture, nullptr, SkMatrix::I(), kNone_OptimizationFlags) + , fKernelSize(kernelSize) + , fGain(SkScalarToFloat(gain)) + , fBias(SkScalarToFloat(bias) / 255.0f) + , fConvolveAlpha(convolveAlpha) + , fDomain(texture, GrTextureDomain::MakeTexelDomainForMode(bounds, tileMode), tileMode) { this->initClassID<GrMatrixConvolutionEffect>(); for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) { fKernel[i] = SkScalarToFloat(kernel[i]); diff --git a/src/gpu/effects/GrOvalEffect.cpp b/src/gpu/effects/GrOvalEffect.cpp index 21a4ba00e5..3b0a8871c4 100644 --- a/src/gpu/effects/GrOvalEffect.cpp +++ b/src/gpu/effects/GrOvalEffect.cpp @@ -64,9 +64,7 @@ void CircleEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { } CircleEffect::CircleEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar r) - : fCenter(c) - , fRadius(r) - , fEdgeType(edgeType) { + : INHERITED(kModulatesInput_OptimizationFlag), fCenter(c), fRadius(r), fEdgeType(edgeType) { this->initClassID<CircleEffect>(); } @@ -230,10 +228,12 @@ void EllipseEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { inout->mulByUnknownSingleComponent(); } -EllipseEffect::EllipseEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar rx, SkScalar ry) - : fCenter(c) - , fRadii(SkVector::Make(rx, ry)) - , fEdgeType(edgeType) { +EllipseEffect::EllipseEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar rx, + SkScalar ry) + : INHERITED(kModulatesInput_OptimizationFlag) + , fCenter(c) + , fRadii(SkVector::Make(rx, ry)) + , fEdgeType(edgeType) { this->initClassID<EllipseEffect>(); } diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp index adebc245a6..4397fcf930 100644 --- a/src/gpu/effects/GrRRectEffect.cpp +++ b/src/gpu/effects/GrRRectEffect.cpp @@ -95,9 +95,10 @@ void CircularRRectEffect::onComputeInvariantOutput(GrInvariantOutput* inout) con CircularRRectEffect::CircularRRectEffect(GrPrimitiveEdgeType edgeType, uint32_t circularCornerFlags, const SkRRect& rrect) - : fRRect(rrect) - , fEdgeType(edgeType) - , fCircularCornerFlags(circularCornerFlags) { + : INHERITED(kModulatesInput_OptimizationFlag) + , fRRect(rrect) + , fEdgeType(edgeType) + , fCircularCornerFlags(circularCornerFlags) { this->initClassID<CircularRRectEffect>(); } @@ -410,8 +411,8 @@ private: void onComputeInvariantOutput(GrInvariantOutput* inout) const override; - SkRRect fRRect; - GrPrimitiveEdgeType fEdgeType; + SkRRect fRRect; + GrPrimitiveEdgeType fEdgeType; GR_DECLARE_FRAGMENT_PROCESSOR_TEST; @@ -431,8 +432,7 @@ void EllipticalRRectEffect::onComputeInvariantOutput(GrInvariantOutput* inout) c } EllipticalRRectEffect::EllipticalRRectEffect(GrPrimitiveEdgeType edgeType, const SkRRect& rrect) - : fRRect(rrect) - , fEdgeType(edgeType) { + : INHERITED(kModulatesInput_OptimizationFlag), fRRect(rrect), fEdgeType(edgeType) { this->initClassID<EllipticalRRectEffect>(); } diff --git a/src/gpu/effects/GrSRGBEffect.cpp b/src/gpu/effects/GrSRGBEffect.cpp index 67600ef320..9279586584 100644 --- a/src/gpu/effects/GrSRGBEffect.cpp +++ b/src/gpu/effects/GrSRGBEffect.cpp @@ -71,7 +71,9 @@ private: /////////////////////////////////////////////////////////////////////////////// GrSRGBEffect::GrSRGBEffect(Mode mode) - : fMode(mode) { + : INHERITED(kPreservesOpaqueInput_OptimizationFlag | + kConstantOutputForConstantInput_OptimizationFlag) + , fMode(mode) { this->initClassID<GrSRGBEffect>(); } @@ -84,6 +86,26 @@ void GrSRGBEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { inout->setToUnknown(); } +static inline float srgb_to_linear(float srgb) { + return (srgb <= 0.04045f) ? srgb / 12.92f : powf((srgb + 0.055f) / 1.055f, 2.4f); +} +static inline float linear_to_srgb(float linear) { + return (linear <= 0.0031308) ? linear * 12.92f : 1.055f * powf(linear, 1.f / 2.4f) - 0.055f; +} + +GrColor4f GrSRGBEffect::constantOutputForConstantInput(GrColor4f input) const { + switch (fMode) { + case Mode::kLinearToSRGB: + return GrColor4f(linear_to_srgb(input.fRGBA[0]), linear_to_srgb(input.fRGBA[1]), + linear_to_srgb(input.fRGBA[2]), input.fRGBA[3]); + case Mode::kSRGBToLinear: + return GrColor4f(srgb_to_linear(input.fRGBA[0]), srgb_to_linear(input.fRGBA[1]), + srgb_to_linear(input.fRGBA[2]), input.fRGBA[3]); + } + SkFAIL("Unexpected mode"); + return GrColor4f::TransparentBlack(); +} + /////////////////////////////////////////////////////////////////////////////// GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSRGBEffect); diff --git a/src/gpu/effects/GrSRGBEffect.h b/src/gpu/effects/GrSRGBEffect.h index 2952689c4e..3d05dd646b 100644 --- a/src/gpu/effects/GrSRGBEffect.h +++ b/src/gpu/effects/GrSRGBEffect.h @@ -33,6 +33,7 @@ private: void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; bool onIsEqual(const GrFragmentProcessor&) const override; void onComputeInvariantOutput(GrInvariantOutput* inout) const override; + GrColor4f constantOutputForConstantInput(GrColor4f input) const override; Mode fMode; diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h index bf013e9c83..c44ce44121 100644 --- a/src/gpu/effects/GrSimpleTextureEffect.h +++ b/src/gpu/effects/GrSimpleTextureEffect.h @@ -13,6 +13,29 @@ class GrInvariantOutput; +// In a few places below we rely on braced initialization order being defined by the C++ spec (left +// to right). We use operator-> on a sk_sp and then in a later argument std::move() the sk_sp. GCC +// 4.9.0 and earlier has a bug where the left to right order evaluation isn't implemented correctly. +#if defined(__GNUC__) && !defined(__clang__) +# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +# if (GCC_VERSION > 40900) +# define GCC_EVAL_ORDER_BUG 0 +# else +# define GCC_EVAL_ORDER_BUG 1 +# endif +# undef GCC_VERSION +#else +# define GCC_EVAL_ORDER_BUG 0 +#endif + +#if GCC_EVAL_ORDER_BUG +# define PROXY_MOVE(X) (X) +#else +# define PROXY_MOVE(X) (std::move(X)) +#endif + +#undef GCC_EVAL_ORDER_BUG + /** * The output color of this effect is a modulation of the input color and a sample from a texture. * It allows explicit specification of the filtering and wrap modes (GrSamplerParams) and accepts @@ -81,32 +104,41 @@ private: sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& matrix, GrSamplerParams::FilterMode filterMode) - : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, filterMode) { + : INHERITED(texture, std::move(colorSpaceXform), matrix, filterMode, + ModulationFlags(texture->config())) { this->initClassID<GrSimpleTextureEffect>(); } GrSimpleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy, - sk_sp<GrColorSpaceXform> colorSpaceXform, - const SkMatrix& matrix, + sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& matrix, GrSamplerParams::FilterMode filterMode) - : GrSingleTextureEffect(ctx, std::move(proxy), std::move(colorSpaceXform), - matrix, filterMode) { + : INHERITED{ctx, + ModulationFlags(proxy->config()), + PROXY_MOVE(proxy), + std::move(colorSpaceXform), + matrix, + filterMode} { this->initClassID<GrSimpleTextureEffect>(); } GrSimpleTextureEffect(GrTexture* texture, - sk_sp<GrColorSpaceXform> colorSpaceXform, + sk_sp<GrColorSpaceXform>colorSpaceXform, const SkMatrix& matrix, const GrSamplerParams& params) - : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, params) { + : INHERITED(texture, std::move(colorSpaceXform), matrix, params, + ModulationFlags(texture->config())) { this->initClassID<GrSimpleTextureEffect>(); } GrSimpleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy, - sk_sp<GrColorSpaceXform> colorSpaceXform, - const SkMatrix& matrix, + sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& matrix, const GrSamplerParams& params) - : GrSingleTextureEffect(ctx, std::move(proxy), std::move(colorSpaceXform), matrix, params) { + : INHERITED{ctx, + ModulationFlags(proxy->config()), + PROXY_MOVE(proxy), + std::move(colorSpaceXform), + matrix, + params} { this->initClassID<GrSimpleTextureEffect>(); } @@ -123,4 +155,6 @@ private: typedef GrSingleTextureEffect INHERITED; }; +#undef PROXY_MOVE + #endif diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp index c493920d3d..acfc0d142d 100644 --- a/src/gpu/effects/GrSingleTextureEffect.cpp +++ b/src/gpu/effects/GrSingleTextureEffect.cpp @@ -12,10 +12,11 @@ GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, sk_sp<GrColorSpaceXform> colorSpaceXform, - const SkMatrix& m) - : fCoordTransform(m, texture, GrSamplerParams::kNone_FilterMode) - , fTextureSampler(texture) - , fColorSpaceXform(std::move(colorSpaceXform)) { + const SkMatrix& m, OptimizationFlags optFlags) + : INHERITED(optFlags) + , fCoordTransform(m, texture, GrSamplerParams::kNone_FilterMode) + , fTextureSampler(texture) + , fColorSpaceXform(std::move(colorSpaceXform)) { this->addCoordTransform(&fCoordTransform); this->addTextureSampler(&fTextureSampler); } @@ -23,56 +24,61 @@ GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& m, - GrSamplerParams::FilterMode filterMode) - : fCoordTransform(m, texture, filterMode) - , fTextureSampler(texture, filterMode) - , fColorSpaceXform(std::move(colorSpaceXform)) { + GrSamplerParams::FilterMode filterMode, + OptimizationFlags optFlags) + : INHERITED(optFlags) + , fCoordTransform(m, texture, filterMode) + , fTextureSampler(texture, filterMode) + , fColorSpaceXform(std::move(colorSpaceXform)) { this->addCoordTransform(&fCoordTransform); this->addTextureSampler(&fTextureSampler); } GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, sk_sp<GrColorSpaceXform> colorSpaceXform, - const SkMatrix& m, - const GrSamplerParams& params) - : fCoordTransform(m, texture, params.filterMode()) - , fTextureSampler(texture, params) - , fColorSpaceXform(std::move(colorSpaceXform)) { + const SkMatrix& m, const GrSamplerParams& params, + OptimizationFlags optFlags) + : INHERITED(optFlags) + , fCoordTransform(m, texture, params.filterMode()) + , fTextureSampler(texture, params) + , fColorSpaceXform(std::move(colorSpaceXform)) { this->addCoordTransform(&fCoordTransform); this->addTextureSampler(&fTextureSampler); } -GrSingleTextureEffect::GrSingleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy, +GrSingleTextureEffect::GrSingleTextureEffect(GrContext* ctx, OptimizationFlags optFlags, + sk_sp<GrTextureProxy> proxy, sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& m) - : fCoordTransform(ctx, m, proxy.get(), GrSamplerParams::kNone_FilterMode) - , fTextureSampler(ctx->textureProvider(), std::move(proxy)) - , fColorSpaceXform(std::move(colorSpaceXform)) { + : INHERITED(optFlags) + , fCoordTransform(ctx, m, proxy.get(), GrSamplerParams::kNone_FilterMode) + , fTextureSampler(ctx->textureProvider(), std::move(proxy)) + , fColorSpaceXform(std::move(colorSpaceXform)) { this->addCoordTransform(&fCoordTransform); this->addTextureSampler(&fTextureSampler); } -GrSingleTextureEffect::GrSingleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy, +GrSingleTextureEffect::GrSingleTextureEffect(GrContext* ctx, OptimizationFlags optFlags, + sk_sp<GrTextureProxy> proxy, sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& m, GrSamplerParams::FilterMode filterMode) - : fCoordTransform(ctx, m, proxy.get(), filterMode) - , fTextureSampler(ctx->textureProvider(), std::move(proxy), filterMode) - , fColorSpaceXform(std::move(colorSpaceXform)) { + : INHERITED(optFlags) + , fCoordTransform(ctx, m, proxy.get(), filterMode) + , fTextureSampler(ctx->textureProvider(), std::move(proxy), filterMode) + , fColorSpaceXform(std::move(colorSpaceXform)) { this->addCoordTransform(&fCoordTransform); this->addTextureSampler(&fTextureSampler); } -GrSingleTextureEffect::GrSingleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy, +GrSingleTextureEffect::GrSingleTextureEffect(GrContext* ctx, OptimizationFlags optFlags, + sk_sp<GrTextureProxy> proxy, sk_sp<GrColorSpaceXform> colorSpaceXform, - const SkMatrix& m, - const GrSamplerParams& params) - : fCoordTransform(ctx, m, proxy.get(), params.filterMode()) - , fTextureSampler(ctx->textureProvider(), std::move(proxy), params) - , fColorSpaceXform(std::move(colorSpaceXform)) { + const SkMatrix& m, const GrSamplerParams& params) + : INHERITED(optFlags) + , fCoordTransform(ctx, m, proxy.get(), params.filterMode()) + , fTextureSampler(ctx->textureProvider(), std::move(proxy), params) + , fColorSpaceXform(std::move(colorSpaceXform)) { this->addCoordTransform(&fCoordTransform); this->addTextureSampler(&fTextureSampler); } - -GrSingleTextureEffect::~GrSingleTextureEffect() { -} diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h index 1d0f27a4ff..29105b5cda 100644 --- a/src/gpu/effects/GrSingleTextureEffect.h +++ b/src/gpu/effects/GrSingleTextureEffect.h @@ -23,8 +23,6 @@ class GrTextureProxy; */ class GrSingleTextureEffect : public GrFragmentProcessor { public: - ~GrSingleTextureEffect() override; - SkString dumpInfo() const override { SkString str; str.appendf("Texture: %d", fTextureSampler.texture()->uniqueID().asUInt()); @@ -35,25 +33,26 @@ public: protected: /** unfiltered, clamp mode */ - GrSingleTextureEffect(GrTexture*, sk_sp<GrColorSpaceXform>, const SkMatrix&); + GrSingleTextureEffect(GrTexture*, sk_sp<GrColorSpaceXform>, const SkMatrix&, + OptimizationFlags optFlags); /** clamp mode */ GrSingleTextureEffect(GrTexture*, sk_sp<GrColorSpaceXform>, const SkMatrix&, - GrSamplerParams::FilterMode filterMode); + GrSamplerParams::FilterMode filterMode, OptimizationFlags optFlags); GrSingleTextureEffect(GrTexture*, sk_sp<GrColorSpaceXform>, const SkMatrix&, - const GrSamplerParams&); + const GrSamplerParams&, + OptimizationFlags optFlags); /** unfiltered, clamp mode */ - GrSingleTextureEffect(GrContext*, - sk_sp<GrTextureProxy>, sk_sp<GrColorSpaceXform>, const SkMatrix&); + GrSingleTextureEffect(GrContext*, OptimizationFlags, sk_sp<GrTextureProxy>, + sk_sp<GrColorSpaceXform>, const SkMatrix&); /** clamp mode */ - GrSingleTextureEffect(GrContext*, - sk_sp<GrTextureProxy>, sk_sp<GrColorSpaceXform>, const SkMatrix&, + GrSingleTextureEffect(GrContext*, OptimizationFlags, sk_sp<GrTextureProxy>, + sk_sp<GrColorSpaceXform>, const SkMatrix&, GrSamplerParams::FilterMode filterMode); - GrSingleTextureEffect(GrContext*, - sk_sp<GrTextureProxy>, sk_sp<GrColorSpaceXform>, const SkMatrix&, - const GrSamplerParams&); + GrSingleTextureEffect(GrContext*, OptimizationFlags, sk_sp<GrTextureProxy>, + sk_sp<GrColorSpaceXform>, const SkMatrix&, const GrSamplerParams&); /** * Can be used as a helper to implement subclass onComputeInvariantOutput(). It assumes that @@ -71,6 +70,19 @@ protected: } } + /** + * Can be used as a helper to implement subclass onOptimizationFlags(). It assumes that + * the subclass output color will be a modulation of the input color with a value read from the + * texture. + */ + static OptimizationFlags ModulationFlags(GrPixelConfig config) { + if (GrPixelConfigIsOpaque(config)) { + return kModulatesInput_OptimizationFlag | kPreservesOpaqueInput_OptimizationFlag; + } else { + return kModulatesInput_OptimizationFlag; + } + } + private: GrCoordTransform fCoordTransform; TextureSampler fTextureSampler; diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp index 095f100593..7ab598fd1f 100644 --- a/src/gpu/effects/GrTextureDomain.cpp +++ b/src/gpu/effects/GrTextureDomain.cpp @@ -208,14 +208,25 @@ sk_sp<GrFragmentProcessor> GrTextureDomainEffect::Make(GrTexture* texture, } } +inline GrFragmentProcessor::OptimizationFlags GrTextureDomainEffect::OptFlags( + GrTexture* texture, GrTextureDomain::Mode mode) { + if (mode == GrTextureDomain::kDecal_Mode || !GrPixelConfigIsOpaque(texture->config())) { + return GrFragmentProcessor::kModulatesInput_OptimizationFlag; + } else { + return GrFragmentProcessor::kModulatesInput_OptimizationFlag | + GrFragmentProcessor::kPreservesOpaqueInput_OptimizationFlag; + } +} + GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& matrix, const SkRect& domain, GrTextureDomain::Mode mode, GrSamplerParams::FilterMode filterMode) - : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, filterMode) - , fTextureDomain(texture, domain, mode) { + : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, filterMode, + OptFlags(texture, mode)) + , fTextureDomain(texture, domain, mode) { SkASSERT(mode != GrTextureDomain::kRepeat_Mode || filterMode == GrSamplerParams::kNone_FilterMode); this->initClassID<GrTextureDomainEffect>(); @@ -323,7 +334,8 @@ sk_sp<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::Make(GrTe GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentProcessor( GrTexture* texture, const SkIRect& subset, const SkIPoint& deviceSpaceOffset) - : fTextureSampler(texture, GrSamplerParams::ClampNoFilter()) + : INHERITED(kModulatesInput_OptimizationFlag) + , fTextureSampler(texture, GrSamplerParams::ClampNoFilter()) , fTextureDomain(texture, GrTextureDomain::MakeTexelDomain(subset), GrTextureDomain::kDecal_Mode) { this->addTextureSampler(&fTextureSampler); diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h index 66bd2201e3..6758d9045e 100644 --- a/src/gpu/effects/GrTextureDomain.h +++ b/src/gpu/effects/GrTextureDomain.h @@ -178,6 +178,8 @@ private: GrTextureDomain::Mode, GrSamplerParams::FilterMode); + static OptimizationFlags OptFlags(GrTexture* texture, GrTextureDomain::Mode mode); + GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; diff --git a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp index d98478747a..af32adec8b 100644 --- a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp +++ b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp @@ -19,7 +19,7 @@ class ComposeTwoFragmentProcessor : public GrFragmentProcessor { public: ComposeTwoFragmentProcessor(sk_sp<GrFragmentProcessor> src, sk_sp<GrFragmentProcessor> dst, SkBlendMode mode) - : fMode(mode) { + : INHERITED(OptFlags(src.get(), dst.get(), mode)), fMode(mode) { this->initClassID<ComposeTwoFragmentProcessor>(); SkDEBUGCODE(int shaderAChildIndex = )this->registerChildProcessor(std::move(src)); SkDEBUGCODE(int shaderBChildIndex = )this->registerChildProcessor(std::move(dst)); @@ -35,7 +35,18 @@ public: SkBlendMode getMode() const { return fMode; } -protected: +private: + static OptimizationFlags OptFlags(const GrFragmentProcessor* src, + const GrFragmentProcessor* dst, SkBlendMode mode) { + // We only attempt the constant output optimization. + // The CPU and GPU implementations differ significantly for the advanced modes. + if (mode <= SkBlendMode::kLastSeparableMode && src->hasConstantOutputForConstantInput() && + dst->hasConstantOutputForConstantInput()) { + return kConstantOutputForConstantInput_OptimizationFlag; + } + return kNone_OptimizationFlags; + } + bool onIsEqual(const GrFragmentProcessor& other) const override { const ComposeTwoFragmentProcessor& cs = other.cast<ComposeTwoFragmentProcessor>(); return fMode == cs.fMode; @@ -45,7 +56,17 @@ protected: inout->setToUnknown(); } -private: + GrColor4f constantOutputForConstantInput(GrColor4f input) const override { + float alpha = input.fRGBA[3]; + input = input.opaque(); + GrColor4f srcColor = ConstantOutputForConstantInput(this->childProcessor(0), input); + GrColor4f dstColor = ConstantOutputForConstantInput(this->childProcessor(1), input); + SkPM4f src = GrColor4fToSkPM4f(srcColor); + SkPM4f dst = GrColor4fToSkPM4f(dstColor); + auto proc = SkXfermode::GetProc4f(fMode); + return SkPM4fToGrColor4f(proc(src, dst)).mulByScalar(alpha); + } + GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; SkBlendMode fMode; @@ -145,8 +166,7 @@ public: }; ComposeOneFragmentProcessor(sk_sp<GrFragmentProcessor> dst, SkBlendMode mode, Child child) - : fMode(mode) - , fChild(child) { + : INHERITED(OptFlags(dst.get(), mode)), fMode(mode), fChild(child) { this->initClassID<ComposeOneFragmentProcessor>(); SkDEBUGCODE(int dstIndex = )this->registerChildProcessor(std::move(dst)); SkASSERT(0 == dstIndex); @@ -172,7 +192,16 @@ public: Child child() const { return fChild; } -protected: +private: + OptimizationFlags OptFlags(const GrFragmentProcessor* child, SkBlendMode mode) { + // We only attempt the constant output optimization. + // The CPU and GPU implementations differ significantly for the advanced modes. + if (mode <= SkBlendMode::kLastSeparableMode && child->hasConstantOutputForConstantInput()) { + return kConstantOutputForConstantInput_OptimizationFlag; + } + return kNone_OptimizationFlags; + } + bool onIsEqual(const GrFragmentProcessor& that) const override { return fMode == that.cast<ComposeOneFragmentProcessor>().fMode; } @@ -203,6 +232,21 @@ protected: } } + GrColor4f constantOutputForConstantInput(GrColor4f inputColor) const override { + GrColor4f childColor = + ConstantOutputForConstantInput(this->childProcessor(0), GrColor4f::OpaqueWhite()); + SkPM4f src, dst; + if (kSrc_Child == fChild) { + src = GrColor4fToSkPM4f(childColor); + dst = GrColor4fToSkPM4f(inputColor); + } else { + src = GrColor4fToSkPM4f(inputColor); + dst = GrColor4fToSkPM4f(childColor); + } + auto proc = SkXfermode::GetProc4f(fMode); + return SkPM4fToGrColor4f(proc(src, dst)); + } + private: GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; diff --git a/src/gpu/effects/GrYUVEffect.cpp b/src/gpu/effects/GrYUVEffect.cpp index 254cdffd2b..6d917f36d5 100644 --- a/src/gpu/effects/GrYUVEffect.cpp +++ b/src/gpu/effects/GrYUVEffect.cpp @@ -155,19 +155,17 @@ public: }; private: - YUVtoRGBEffect(GrContext* ctx, - sk_sp<GrTextureProxy> yProxy, - sk_sp<GrTextureProxy> uProxy, - sk_sp<GrTextureProxy> vProxy, - const SkMatrix yuvMatrix[3], GrSamplerParams::FilterMode uvFilterMode, - SkYUVColorSpace colorSpace, bool nv12) - : fYTransform(ctx, yuvMatrix[0], yProxy.get(), GrSamplerParams::kNone_FilterMode) - , fYSampler(ctx->textureProvider(), std::move(yProxy)) - , fUTransform(ctx, yuvMatrix[1], uProxy.get(), uvFilterMode) - , fUSampler(ctx->textureProvider(), std::move(uProxy), uvFilterMode) - , fVSampler(ctx->textureProvider(), vProxy, uvFilterMode) - , fColorSpace(colorSpace) - , fNV12(nv12) { + YUVtoRGBEffect(GrContext* ctx, sk_sp<GrTextureProxy> yProxy, sk_sp<GrTextureProxy> uProxy, + sk_sp<GrTextureProxy> vProxy, const SkMatrix yuvMatrix[3], + GrSamplerParams::FilterMode uvFilterMode, SkYUVColorSpace colorSpace, bool nv12) + : INHERITED(kPreservesOpaqueInput_OptimizationFlag) + , fYTransform(ctx, yuvMatrix[0], yProxy.get(), GrSamplerParams::kNone_FilterMode) + , fYSampler(ctx->textureProvider(), std::move(yProxy)) + , fUTransform(ctx, yuvMatrix[1], uProxy.get(), uvFilterMode) + , fUSampler(ctx->textureProvider(), std::move(uProxy), uvFilterMode) + , fVSampler(ctx->textureProvider(), vProxy, uvFilterMode) + , fColorSpace(colorSpace) + , fNV12(nv12) { this->initClassID<YUVtoRGBEffect>(); this->addCoordTransform(&fYTransform); this->addTextureSampler(&fYSampler); @@ -228,8 +226,10 @@ public: RGBToYUVEffect(sk_sp<GrFragmentProcessor> rgbFP, SkYUVColorSpace colorSpace, OutputChannels output) - : fColorSpace(colorSpace) - , fOutputChannels(output) { + // This could advertise kConstantOutputForConstantInput, but doesn't seem useful. + : INHERITED(kPreservesOpaqueInput_OptimizationFlag) + , fColorSpace(colorSpace) + , fOutputChannels(output) { this->initClassID<RGBToYUVEffect>(); this->registerChildProcessor(std::move(rgbFP)); } |