aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
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 /include
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 'include')
-rw-r--r--include/gpu/GrColor.h15
-rw-r--r--include/gpu/GrFragmentProcessor.h93
-rw-r--r--include/gpu/GrProcessorUnitTest.h6
-rw-r--r--include/gpu/GrTypes.h37
-rw-r--r--include/gpu/effects/GrConstColorProcessor.h15
5 files changed, 133 insertions, 33 deletions
diff --git a/include/gpu/GrColor.h b/include/gpu/GrColor.h
index cebceea2d0..64368b9ef9 100644
--- a/include/gpu/GrColor.h
+++ b/include/gpu/GrColor.h
@@ -213,6 +213,17 @@ struct GrColor4f {
return GrColor4f(color.fR, color.fG, color.fB, color.fA);
}
+ GrColor4f modulate(const GrColor4f& x) const {
+ return GrColor4f(fRGBA[0] * x.fRGBA[0],
+ fRGBA[1] * x.fRGBA[1],
+ fRGBA[2] * x.fRGBA[2],
+ fRGBA[3] * x.fRGBA[3]);
+ }
+
+ GrColor4f mulByScalar(float x) const {
+ return GrColor4f(fRGBA[0] * x, fRGBA[1] * x, fRGBA[2] * x, fRGBA[3] * x);
+ }
+
bool operator==(const GrColor4f& other) const {
return
fRGBA[0] == other.fRGBA[0] &&
@@ -240,6 +251,10 @@ struct GrColor4f {
return GrColor4f(fRGBA[0], fRGBA[1], fRGBA[2], 1.0f);
}
+ bool isOpaque() const {
+ return fRGBA[3] >= 1.f; // just in case precision causes a superopaque value.
+ }
+
GrColor4f premul() const {
float a = fRGBA[3];
return GrColor4f(fRGBA[0] * a, fRGBA[1] * a, fRGBA[2] * a, a);
diff --git a/include/gpu/GrFragmentProcessor.h b/include/gpu/GrFragmentProcessor.h
index 49ccceabae..0d41a267de 100644
--- a/include/gpu/GrFragmentProcessor.h
+++ b/include/gpu/GrFragmentProcessor.h
@@ -64,11 +64,6 @@ public:
*/
static sk_sp<GrFragmentProcessor> RunInSeries(sk_sp<GrFragmentProcessor>*, int cnt);
- GrFragmentProcessor()
- : INHERITED()
- , fUsesDistanceVectorField(false)
- , fUsesLocalCoords(false) {}
-
~GrFragmentProcessor() override;
GrGLSLFragmentProcessor* createGLSLInstance() const;
@@ -95,10 +90,42 @@ public:
const GrFragmentProcessor& childProcessor(int index) const { return *fChildProcessors[index]; }
/** Do any of the coordtransforms for this processor require local coords? */
- bool usesLocalCoords() const { return fUsesLocalCoords; }
+ bool usesLocalCoords() const { return SkToBool(fFlags & kUsesLocalCoords_Flag); }
/** Does this FP need a vector to the nearest edge? */
- bool usesDistanceVectorField() const { return fUsesDistanceVectorField; }
+ bool usesDistanceVectorField() const {
+ return SkToBool(fFlags & kUsesDistanceVectorField_Flag);
+ }
+
+ /**
+ * True if the processor's output is a modulation of its input color or alpha with a computed
+ * color or alpha in the 0..1 range. If true and the blend mode allows it we may fold coverage
+ * into the first color fragment processor's input.
+ */
+ bool modulatesInput() const { return SkToBool(fFlags & kModulatesInput_OptimizationFlag); }
+
+ /**
+ * If this is true then all opaque input colors to the processor produce opaque output colors.
+ */
+ bool preservesOpaqueInput() const {
+ return SkToBool(fFlags & kPreservesOpaqueInput_OptimizationFlag);
+ }
+
+ /**
+ * Tests whether given a constant input color the processor produces a constant output color
+ * (for all fragments). If true outputColor will contain the constant color produces for
+ * inputColor.
+ */
+ bool hasConstantOutputForConstantInput(GrColor4f inputColor, GrColor4f* outputColor) const {
+ if (fFlags & kConstantOutputForConstantInput_OptimizationFlag) {
+ *outputColor = this->constantOutputForConstantInput(inputColor);
+ return true;
+ }
+ return false;
+ }
+ bool hasConstantOutputForConstantInput() const {
+ return SkToBool(fFlags & kConstantOutputForConstantInput_OptimizationFlag);
+ }
/** Returns true if this and other processor conservatively draw identically. It can only return
true when the two processor are of the same subclass (i.e. they return the same object from
@@ -189,6 +216,36 @@ public:
&GrProcessor::textureSampler>;
protected:
+ enum OptimizationFlags : uint32_t {
+ kNone_OptimizationFlags,
+ kModulatesInput_OptimizationFlag = 0x1,
+ kPreservesOpaqueInput_OptimizationFlag = 0x2,
+ kConstantOutputForConstantInput_OptimizationFlag = 0x4,
+ kAll_OptimizationFlags = kModulatesInput_OptimizationFlag |
+ kPreservesOpaqueInput_OptimizationFlag |
+ kConstantOutputForConstantInput_OptimizationFlag
+ };
+ GR_DECL_BITFIELD_OPS_FRIENDS(OptimizationFlags)
+
+ GrFragmentProcessor(OptimizationFlags optimizationFlags) : fFlags(optimizationFlags) {
+ SkASSERT((fFlags & ~kAll_OptimizationFlags) == 0);
+ }
+
+ OptimizationFlags optimizationFlags() const {
+ return static_cast<OptimizationFlags>(kAll_OptimizationFlags & fFlags);
+ }
+
+ /**
+ * This allows one subclass to access another subclass's implementation of
+ * constantOutputForConstantInput. It must only be called when
+ * hasConstantOutputForConstantInput() is known to be true.
+ */
+ static GrColor4f ConstantOutputForConstantInput(const GrFragmentProcessor& fp,
+ GrColor4f input) {
+ SkASSERT(fp.hasConstantOutputForConstantInput());
+ return fp.constantOutputForConstantInput(input);
+ }
+
/**
* Fragment Processor subclasses call this from their constructor to register coordinate
* transformations. Coord transforms provide a mechanism for a processor to receive coordinates
@@ -227,14 +284,20 @@ protected:
*/
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const = 0;
- /* Sub-classes should set this to true in their constructors if they need access to a distance
+ /**
+ * Sub-classes should call this in their constructors if they need access to a distance
* vector field to the nearest edge
*/
- bool fUsesDistanceVectorField;
+ void setWillUseDistanceVectorField() { fFlags |= kUsesDistanceVectorField_Flag; }
private:
void notifyRefCntIsZero() const final;
+ virtual GrColor4f constantOutputForConstantInput(GrColor4f /* inputColor */) const {
+ SkFAIL("Subclass must override this if advertising this optimization.");
+ return GrColor4f::TransparentBlack();
+ }
+
/** Returns a new instance of the appropriate *GL* implementation class
for the given GrFragmentProcessor; caller is responsible for deleting
the object. */
@@ -253,7 +316,13 @@ private:
bool hasSameTransforms(const GrFragmentProcessor&) const;
- bool fUsesLocalCoords;
+ enum PrivateFlags {
+ kFirstPrivateFlag = kAll_OptimizationFlags + 1,
+ kUsesLocalCoords_Flag = kFirstPrivateFlag,
+ kUsesDistanceVectorField_Flag = kFirstPrivateFlag << 1,
+ };
+
+ mutable uint32_t fFlags = 0;
SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
@@ -261,9 +330,11 @@ private:
* This is not SkSTArray<1, sk_sp<GrFragmentProcessor>> because this class holds strong
* references until notifyRefCntIsZero and then it holds pending executions.
*/
- SkSTArray<1, GrFragmentProcessor*, true> fChildProcessors;
+ SkSTArray<1, GrFragmentProcessor*, true> fChildProcessors;
typedef GrProcessor INHERITED;
};
+GR_MAKE_BITFIELD_OPS(GrFragmentProcessor::OptimizationFlags)
+
#endif
diff --git a/include/gpu/GrProcessorUnitTest.h b/include/gpu/GrProcessorUnitTest.h
index 7cec307f28..a56db8188b 100644
--- a/include/gpu/GrProcessorUnitTest.h
+++ b/include/gpu/GrProcessorUnitTest.h
@@ -46,10 +46,8 @@ struct GrProcessorTestData {
GrProcessorTestData(SkRandom* random,
GrContext* context,
const GrRenderTargetContext* renderTargetContext,
- GrTexture* textures[2])
- : fRandom(random)
- , fContext(context)
- , fRenderTargetContext(renderTargetContext) {
+ GrTexture* const textures[2])
+ : fRandom(random), fContext(context), fRenderTargetContext(renderTargetContext) {
fTextures[0] = textures[0];
fTextures[1] = textures[1];
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index b3f1c19ebb..8da7f71e62 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -19,56 +19,59 @@
* bitfield.
*/
#define GR_MAKE_BITFIELD_OPS(X) \
- inline X operator | (X a, X b) { \
+ inline X operator |(X a, X b) { \
return (X) (+a | +b); \
} \
- inline X& operator |= (X& a, X b) { \
+ inline X& operator |=(X& a, X b) { \
return (a = a | b); \
} \
- \
- inline X operator & (X a, X b) { \
+ inline X operator &(X a, X b) { \
return (X) (+a & +b); \
} \
+ inline X& operator &=(X& a, X b) { \
+ return (a = a & b); \
+ } \
template <typename T> \
- inline X operator & (T a, X b) { \
+ inline X operator &(T a, X b) { \
return (X) (+a & +b); \
} \
template <typename T> \
- inline X operator & (X a, T b) { \
+ inline X operator &(X a, T b) { \
return (X) (+a & +b); \
} \
#define GR_DECL_BITFIELD_OPS_FRIENDS(X) \
- friend X operator | (X a, X b); \
- friend X& operator |= (X& a, X b); \
+ friend X operator |(X a, X b); \
+ friend X& operator |=(X& a, X b); \
\
- friend X operator & (X a, X b); \
+ friend X operator &(X a, X b); \
+ friend X& operator &=(X& a, X b); \
\
template <typename T> \
- friend X operator & (T a, X b); \
+ friend X operator &(T a, X b); \
\
template <typename T> \
- friend X operator & (X a, T b); \
+ friend X operator &(X a, T b); \
/**
* Defines bitwise operators that make it possible to use an enum class as a
* very basic bitfield.
*/
#define GR_MAKE_BITFIELD_CLASS_OPS(X) \
- inline X operator | (X a, X b) { \
+ inline X operator |(X a, X b) { \
return (X) ((int)a | (int)b); \
} \
- inline X& operator |= (X& a, X b) { \
+ inline X& operator |=(X& a, X b) { \
return (a = a | b); \
} \
- inline bool operator & (X a, X b) { \
+ inline bool operator &(X a, X b) { \
return SkToBool((int)a & (int)b); \
}
#define GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(X) \
- friend X operator | (X a, X b); \
- friend X& operator |= (X& a, X b); \
- friend bool operator & (X a, X b);
+ friend X operator |(X a, X b); \
+ friend X& operator |=(X& a, X b); \
+ friend bool operator &(X a, X b);
////////////////////////////////////////////////////////////////////////////////
diff --git a/include/gpu/effects/GrConstColorProcessor.h b/include/gpu/effects/GrConstColorProcessor.h
index 73ea9eb196..b32421bd55 100644
--- a/include/gpu/effects/GrConstColorProcessor.h
+++ b/include/gpu/effects/GrConstColorProcessor.h
@@ -43,7 +43,19 @@ public:
InputMode inputMode() const { return fMode; }
private:
- GrConstColorProcessor(GrColor4f color, InputMode mode) : fColor(color), fMode(mode) {
+ static OptimizationFlags OptFlags(GrColor4f color, InputMode mode) {
+ OptimizationFlags flags = kConstantOutputForConstantInput_OptimizationFlag;
+ if (mode != kIgnore_InputMode) {
+ flags |= kModulatesInput_OptimizationFlag;
+ }
+ if (color.isOpaque()) {
+ flags |= kPreservesOpaqueInput_OptimizationFlag;
+ }
+ return flags;
+ }
+
+ GrConstColorProcessor(GrColor4f color, InputMode mode)
+ : INHERITED(OptFlags(color, mode)), fColor(color), fMode(mode) {
this->initClassID<GrConstColorProcessor>();
}
@@ -54,6 +66,7 @@ private:
bool onIsEqual(const GrFragmentProcessor&) const override;
void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
+ GrColor4f constantOutputForConstantInput(GrColor4f input) const override;
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;