| Index: include/gpu/GrXferProcessor.h
|
| diff --git a/include/gpu/GrXferProcessor.h b/include/gpu/GrXferProcessor.h
|
| index 10ecf54c758c25e938cb9b1b7fe549f016a9e727..b7d0bdd9fa9ef7717471a3857b9e788e95793378 100644
|
| --- a/include/gpu/GrXferProcessor.h
|
| +++ b/include/gpu/GrXferProcessor.h
|
| @@ -13,6 +13,8 @@
|
| #include "GrTypes.h"
|
| #include "SkXfermode.h"
|
|
|
| +class GrProcOptInfo;
|
| +
|
| /**
|
| * GrXferProcessor is responsible for implementing the xfer mode that blends the src color and dst
|
| * color. It does this by emitting fragment shader code and controlling the fixed-function blend
|
| @@ -27,11 +29,83 @@
|
| * GrXPFactory once we have finalized the state of our draw.
|
| */
|
| class GrXferProcessor : public GrFragmentProcessor {
|
| +public:
|
| + /**
|
| + * Optimizations for blending / coverage that an OptDrawState should apply to itself.
|
| + */
|
| + enum OptFlags {
|
| + /**
|
| + * No optimizations needed
|
| + */
|
| + kNone_Opt = 0,
|
| + /**
|
| + * The draw can be skipped completely.
|
| + */
|
| + kSkipDraw_OptFlag = 0x1,
|
| + /**
|
| + * Clear color stages, remove color vertex attribs, and use input color
|
| + */
|
| + kClearColorStages_OptFlag = 0x2,
|
| + /**
|
| + * Clear coverage stages, remove coverage vertex attribs, and use input coverage
|
| + */
|
| + kClearCoverageStages_OptFlag = 0x4,
|
| + /**
|
| + * Set CoverageDrawing_StateBit
|
| + */
|
| + kSetCoverageDrawing_OptFlag = 0x8,
|
| + };
|
| +
|
| + GR_DECL_BITFIELD_OPS_FRIENDS(OptFlags);
|
| +
|
| + /**
|
| + * Determines which optimizations (as described by the ptFlags above) can be performed by
|
| + * the draw with this xfer processor. If this function is called, the xfer processor may change
|
| + * its state to reflected the given blend optimizations. It will also set the output parameters,
|
| + * color and coverage, to specific values if it decides to remove all color or coverage stages.
|
| + * A caller who calls this function on a XP is required to honor the returned OptFlags
|
| + * and color/coverage values for its draw.
|
| + */
|
| + // TODO: remove need for isCoverageDrawing once coverageDrawing is its own XP.
|
| + // TODO: remove need for colorWriteDisabled once colorWriteDisabled is its own XP.
|
| + virtual OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
|
| + const GrProcOptInfo& coveragePOI,
|
| + bool isCoverageDrawing,
|
| + bool colorWriteDisabled,
|
| + bool doesStencilWrite,
|
| + GrColor* color,
|
| + uint8_t* coverage) = 0;
|
| +
|
| + struct BlendInfo {
|
| + GrBlendCoeff fSrcBlend;
|
| + GrBlendCoeff fDstBlend;
|
| + GrColor fBlendConstant;
|
| + };
|
| +
|
| + virtual void getBlendInfo(BlendInfo* blendInfo) const = 0;
|
| +
|
| + /** Will this prceossor read the destination pixel value? */
|
| + bool willReadDstColor() const { return fWillReadDstColor; }
|
| +
|
| +protected:
|
| + GrXferProcessor() : fWillReadDstColor(false) {}
|
| +
|
| + /**
|
| + * If the prceossor subclass will read the destination pixel value then it must call this
|
| + * function from its constructor. Otherwise, when its generated backend-specific prceossor class
|
| + * attempts to generate code that reads the destination pixel it will fail.
|
| + */
|
| + void setWillReadDstColor() { fWillReadDstColor = true; }
|
| +
|
| private:
|
|
|
| + bool fWillReadDstColor;
|
| +
|
| typedef GrFragmentProcessor INHERITED;
|
| };
|
|
|
| +GR_MAKE_BITFIELD_OPS(GrXferProcessor::OptFlags);
|
| +
|
| /**
|
| * We install a GrXPFactory (XPF) early on in the pipeline before all the final draw information is
|
| * known (e.g. whether there is fractional pixel coverage, will coverage be 1 or 4 channel, is the
|
| @@ -45,7 +119,8 @@ private:
|
| */
|
| class GrXPFactory : public SkRefCnt {
|
| public:
|
| - virtual const GrXferProcessor* createXferProcessor() const = 0;
|
| + virtual GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI,
|
| + const GrProcOptInfo& coveragePOI) const = 0;
|
|
|
| /**
|
| * This function returns true if the GrXferProcessor generated from this factory will be able to
|
| @@ -54,6 +129,40 @@ public:
|
| */
|
| virtual bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const = 0;
|
|
|
| + /**
|
| + * Depending on color blend mode requested it may or may not be possible to correctly blend with
|
| + * fractional pixel coverage generated by the fragment shader.
|
| + *
|
| + * This function considers the known color and coverage input into the xfer processor and
|
| + * certain state information (isCoverageDrawing and colorWriteDisabled) to determine whether
|
| + * coverage can be handled correctly.
|
| + */
|
| + // TODO: remove need for isCoverageDrawing once coverageDrawing is its own XP.
|
| + // TODO: remove need for colorWriteDisabled once colorWriteDisabled is its own XP.
|
| + virtual bool canApplyCoverage(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
|
| + bool isCoverageDrawing, bool colorWriteDisabled) const = 0;
|
| +
|
| + /**
|
| + * This function returns true if the destination pixel values will be read for blending during
|
| + * draw.
|
| + */
|
| + // TODO: remove need for isCoverageDrawing once coverageDrawing is its own XP.
|
| + // TODO: remove need for colorWriteDisabled once only XP can read dst.
|
| + virtual bool willBlendWithDst(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
|
| + bool isCoverageDrawing, bool colorWriteDisabled) const = 0;
|
| +
|
| + /**
|
| + * Determines whether multiplying the computed per-pixel color by the pixel's fractional
|
| + * coverage before the blend will give the correct final destination color. In general it
|
| + * will not as coverage is applied after blending.
|
| + */
|
| + // TODO: remove need for isCoverageDrawing once coverageDrawing is its own XP.
|
| + virtual bool canTweakAlphaForCoverage(bool isCoverageDrawing) const = 0;
|
| +
|
| + virtual bool getOpaqueAndKnownColor(const GrProcOptInfo& colorPOI,
|
| + const GrProcOptInfo& coveragePOI, GrColor* solidColor,
|
| + uint32_t* solidColorKnownComponents) const = 0;
|
| +
|
| bool isEqual(const GrXPFactory& that) const {
|
| if (this->classID() != that.classID()) {
|
| return false;
|
|
|