diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/gpu/GrInvariantOutput.h | 148 | ||||
-rw-r--r-- | include/gpu/GrProcessor.h | 143 |
2 files changed, 151 insertions, 140 deletions
diff --git a/include/gpu/GrInvariantOutput.h b/include/gpu/GrInvariantOutput.h new file mode 100644 index 0000000000..8f38d1f8ac --- /dev/null +++ b/include/gpu/GrInvariantOutput.h @@ -0,0 +1,148 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrInvariantOutput_DEFINED +#define GrInvariantOutput_DEFINED + +#include "GrColor.h" + +class GrInvariantOutput { +public: + GrInvariantOutput(GrColor color, GrColorComponentFlags flags, bool isSingleComponent) + : fColor(color), fValidFlags(flags), fIsSingleComponent(isSingleComponent), + fNonMulStageFound(false), fWillUseInputColor(true) {} + + virtual ~GrInvariantOutput() {} + + enum ReadInput { + kWill_ReadInput, + kWillNot_ReadInput, + }; + + void mulByUnknownOpaqueColor() { + if (this->isOpaque()) { + fValidFlags = kA_GrColorComponentFlag; + fIsSingleComponent = false; + } else { + // Since the current state is not opaque we no longer care if the color being + // multiplied is opaque. + this->mulByUnknownColor(); + } + } + + void mulByUnknownColor() { + if (this->hasZeroAlpha()) { + this->internalSetToTransparentBlack(); + } else { + this->internalSetToUnknown(); + } + } + + void mulByUnknownAlpha() { + if (this->hasZeroAlpha()) { + this->internalSetToTransparentBlack(); + } else { + // We don't need to change fIsSingleComponent in this case + fValidFlags = 0; + } + } + + void mulByKnownAlpha(uint8_t alpha) { + if (this->hasZeroAlpha() || 0 == alpha) { + this->internalSetToTransparentBlack(); + } else { + if (alpha != 255) { + // Multiply color by alpha + fColor = GrColorPackRGBA(SkMulDiv255Round(GrColorUnpackR(fColor), alpha), + SkMulDiv255Round(GrColorUnpackG(fColor), alpha), + SkMulDiv255Round(GrColorUnpackB(fColor), alpha), + SkMulDiv255Round(GrColorUnpackA(fColor), alpha)); + } + } + } + + void invalidateComponents(uint8_t invalidateFlags, ReadInput readsInput) { + fValidFlags &= ~invalidateFlags; + fIsSingleComponent = false; + fNonMulStageFound = true; + if (kWillNot_ReadInput == readsInput) { + fWillUseInputColor = false; + } + } + + void setToOther(uint8_t validFlags, GrColor color, ReadInput readsInput) { + fValidFlags = validFlags; + fColor = color; + fIsSingleComponent = false; + fNonMulStageFound = true; + if (kWillNot_ReadInput == readsInput) { + fWillUseInputColor = false; + } + } + + void setToUnknown(ReadInput readsInput) { + this->internalSetToUnknown(); + fNonMulStageFound= true; + if (kWillNot_ReadInput == readsInput) { + fWillUseInputColor = false; + } + } + + bool isOpaque() const { + return ((fValidFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(fColor)); + } + + bool isSolidWhite() const { + return (fValidFlags == kRGBA_GrColorComponentFlags && 0xFFFFFFFF == fColor); + } + + GrColor color() const { return fColor; } + uint8_t validFlags() const { return fValidFlags; } + + bool willUseInputColor() const { return fWillUseInputColor; } + void resetWillUseInputColor() { fWillUseInputColor = true; } + + void resetNonMulStageFound() { fNonMulStageFound = false; } + + /** + * If isSingleComponent is true, then the flag values for r, g, b, and a must all be the + * same. If the flags are all set then all color components must be equal. + */ + SkDEBUGCODE(void validate() const;) + +protected: + GrColor fColor; + uint32_t fValidFlags; + bool fIsSingleComponent; + bool fNonMulStageFound; + bool fWillUseInputColor; + +private: + void internalSetToTransparentBlack() { + fValidFlags = kRGBA_GrColorComponentFlags; + fColor = 0; + fIsSingleComponent = true; + } + + void internalSetToUnknown() { + fValidFlags = 0; + fIsSingleComponent = false; + } + + bool hasZeroAlpha() const { + return ((fValidFlags & kA_GrColorComponentFlag) && 0 == GrColorUnpackA(fColor)); + } + + SkDEBUGCODE(bool colorComponentsAllEqual() const;) + /** + * If alpha is valid, check that any valid R,G,B values are <= A + */ + SkDEBUGCODE(bool validPreMulColor() const;) +}; + +#endif + diff --git a/include/gpu/GrProcessor.h b/include/gpu/GrProcessor.h index 96ce288404..20123754e2 100644 --- a/include/gpu/GrProcessor.h +++ b/include/gpu/GrProcessor.h @@ -17,6 +17,7 @@ class GrContext; class GrCoordTransform; +class GrInvariantOutput; /** Provides custom shader code to the Ganesh shading pipeline. GrProcessor objects *must* be immutable: after being constructed, their fields may not change. @@ -31,137 +32,6 @@ public: virtual ~GrProcessor(); - struct InvariantOutput{ - InvariantOutput() : fColor(0), fValidFlags(0), fIsSingleComponent(false), - fNonMulStageFound(false), fWillUseInputColor(true) {} - - enum ReadInput { - kWill_ReadInput, - kWillNot_ReadInput, - }; - - void mulByUnknownOpaqueColor() { - if (this->isOpaque()) { - fValidFlags = kA_GrColorComponentFlag; - fIsSingleComponent = false; - } else { - // Since the current state is not opaque we no longer care if the color being - // multiplied is opaque. - this->mulByUnknownColor(); - } - } - - void mulByUnknownColor() { - if (this->hasZeroAlpha()) { - this->internalSetToTransparentBlack(); - } else { - this->internalSetToUnknown(); - } - } - - void mulByUnknownAlpha() { - if (this->hasZeroAlpha()) { - this->internalSetToTransparentBlack(); - } else { - // We don't need to change fIsSingleComponent in this case - fValidFlags = 0; - } - } - - void mulByKnownAlpha(uint8_t alpha) { - if (this->hasZeroAlpha() || 0 == alpha) { - this->internalSetToTransparentBlack(); - } else { - if (alpha != 255) { - // Multiply color by alpha - fColor = GrColorPackRGBA(SkMulDiv255Round(GrColorUnpackR(fColor), alpha), - SkMulDiv255Round(GrColorUnpackG(fColor), alpha), - SkMulDiv255Round(GrColorUnpackB(fColor), alpha), - SkMulDiv255Round(GrColorUnpackA(fColor), alpha)); - } - } - } - - void invalidateComponents(uint8_t invalidateFlags, ReadInput readsInput) { - fValidFlags &= ~invalidateFlags; - fIsSingleComponent = false; - if (kWillNot_ReadInput == readsInput) { - fWillUseInputColor = false; - } - } - - void setToOther(uint8_t validFlags, GrColor color, ReadInput readsInput) { - fValidFlags = validFlags; - fColor = color; - fIsSingleComponent = false; - fNonMulStageFound = true; - if (kWillNot_ReadInput == readsInput) { - fWillUseInputColor = false; - } - } - - void setToUnknown(ReadInput readsInput) { - this->internalSetToUnknown(); - fNonMulStageFound= true; - if (kWillNot_ReadInput == readsInput) { - fWillUseInputColor = false; - } - } - - bool isOpaque() const { - return ((fValidFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(fColor)); - } - - bool isSolidWhite() const { - return (fValidFlags == kRGBA_GrColorComponentFlags && 0xFFFFFFFF == fColor); - } - - GrColor color() const { return fColor; } - uint8_t validFlags() const { return fValidFlags; } - - /** - * If isSingleComponent is true, then the flag values for r, g, b, and a must all be the - * same. If the flags are all set then all color components must be equal. - */ - SkDEBUGCODE(void validate() const;) - - private: - void internalSetToTransparentBlack() { - fValidFlags = kRGBA_GrColorComponentFlags; - fColor = 0; - fIsSingleComponent = true; - } - - void internalSetToUnknown() { - fValidFlags = 0; - fIsSingleComponent = false; - } - - bool hasZeroAlpha() const { - return ((fValidFlags & kA_GrColorComponentFlag) && 0 == GrColorUnpackA(fColor)); - } - - SkDEBUGCODE(bool colorComponentsAllEqual() const;) - /** - * If alpha is valid, check that any valid R,G,B values are <= A - */ - SkDEBUGCODE(bool validPreMulColor() const;) - - // Friended class that have "controller" code which loop over stages calling - // computeInvarianteOutput(). These controllers may need to manually adjust the internal - // members of InvariantOutput - friend class GrDrawState; - friend class GrOptDrawState; - friend class GrPaint; - friend class GrProcessor; - - GrColor fColor; - uint32_t fValidFlags; - bool fIsSingleComponent; - bool fNonMulStageFound; - bool fWillUseInputColor; - }; - /** * This function is used to perform optimizations. When called the invarientOuput param * indicate whether the input components to this processor in the FS will have known values. @@ -170,13 +40,7 @@ public: * inout to indicate known values of its output. A component of the color member only has * meaning if the corresponding bit in validFlags is set. */ - void computeInvariantOutput(InvariantOutput* inout) const { - inout->fWillUseInputColor = true; - this->onComputeInvariantOutput(inout); -#ifdef SK_DEBUG - inout->validate(); -#endif - } + void computeInvariantOutput(GrInvariantOutput* inout) const; /** This object, besides creating back-end-specific helper objects, is used for run-time-type- identification. The factory should be an instance of templated class, @@ -247,11 +111,10 @@ protected: void setWillReadFragmentPosition() { fWillReadFragmentPosition = true; } private: - /** * Subclass implements this to support getConstantColorComponents(...). */ - virtual void onComputeInvariantOutput(InvariantOutput* inout) const = 0; + virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const = 0; SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses; bool fWillReadFragmentPosition; |