aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/effects
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-01-27 10:59:27 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-01-27 16:43:38 +0000
commit587e08f361ee3e775a6bbc6dca761dbba82e422c (patch)
tree9f64e10d50fab820419d29dea30a6c978c86c8c9 /src/gpu/effects
parent4d3adb6b0dea1c9f74fc00b007dfb1af425fc727 (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')
-rw-r--r--src/gpu/effects/Gr1DKernelEffect.h12
-rw-r--r--src/gpu/effects/GrBicubicEffect.cpp18
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.cpp8
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.h1
-rw-r--r--src/gpu/effects/GrConstColorProcessor.cpp13
-rw-r--r--src/gpu/effects/GrConvexPolyEffect.cpp5
-rw-r--r--src/gpu/effects/GrDitherEffect.cpp4
-rw-r--r--src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp3
-rw-r--r--src/gpu/effects/GrMatrixConvolutionEffect.cpp14
-rw-r--r--src/gpu/effects/GrOvalEffect.cpp14
-rw-r--r--src/gpu/effects/GrRRectEffect.cpp14
-rw-r--r--src/gpu/effects/GrSRGBEffect.cpp24
-rw-r--r--src/gpu/effects/GrSRGBEffect.h1
-rw-r--r--src/gpu/effects/GrSimpleTextureEffect.h54
-rw-r--r--src/gpu/effects/GrSingleTextureEffect.cpp66
-rw-r--r--src/gpu/effects/GrSingleTextureEffect.h36
-rw-r--r--src/gpu/effects/GrTextureDomain.cpp18
-rw-r--r--src/gpu/effects/GrTextureDomain.h2
-rw-r--r--src/gpu/effects/GrXfermodeFragmentProcessor.cpp56
-rw-r--r--src/gpu/effects/GrYUVEffect.cpp30
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));
}