aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorGravatar egdaniel <egdaniel@google.com>2014-12-09 11:15:43 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2014-12-09 11:15:44 -0800
commit9513143efa734bef0c1a0c7f945022572dbc8518 (patch)
tree767babf49d28d878f8eb29900115bfc54dd54917 /include
parent9f876a37d8b80ef04ccbc7755cf4572aecc33981 (diff)
Make all blending up to GrOptDrawState be handled by the xp/xp factory.
In this cl the blending information is extracted for the xp and stored in the ODS which is then used as it currently is. In the follow up cl, an XP backend will be added and at that point all blending work will take place inside XP's. BUG=skia: Committed: https://skia.googlesource.com/skia/+/7c66342a399b529634bed0fabfaa562db2c0dbd4 Review URL: https://codereview.chromium.org/759713002
Diffstat (limited to 'include')
-rw-r--r--include/core/SkXfermode.h4
-rw-r--r--include/gpu/GrPaint.h32
-rw-r--r--include/gpu/GrXferProcessor.h111
-rw-r--r--include/gpu/effects/GrPorterDuffXferProcessor.h50
4 files changed, 163 insertions, 34 deletions
diff --git a/include/core/SkXfermode.h b/include/core/SkXfermode.h
index 35e9837483..05fd81152a 100644
--- a/include/core/SkXfermode.h
+++ b/include/core/SkXfermode.h
@@ -217,10 +217,10 @@ public:
or a fragment processor. This helper calls the asCoeff(), asXPFactory(),
and asFragmentProcessor() virtuals. If the xfermode is NULL, it is treated as kSrcOver_Mode.
It is legal to call this with all params NULL to simply test the return value.
- fp, xpf, src, and dst must all be NULL or all non-NULL.
+ fp and xpf must both be NULL or all non-NULL.
*/
static bool AsFragmentProcessorOrXPFactory(SkXfermode*, GrFragmentProcessor**,
- GrXPFactory**, Coeff* src, Coeff* dst);
+ GrXPFactory**);
SK_TO_STRING_PUREVIRT()
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h
index f31830bb2b..49b95b8449 100644
--- a/include/gpu/GrPaint.h
+++ b/include/gpu/GrPaint.h
@@ -13,6 +13,7 @@
#include "GrColor.h"
#include "GrFragmentStage.h"
#include "GrXferProcessor.h"
+#include "effects/GrPorterDuffXferProcessor.h"
#include "SkXfermode.h"
@@ -51,17 +52,6 @@ public:
~GrPaint() {}
/**
- * Sets the blending coefficients to use to blend the final primitive color with the
- * destination color. Defaults to kOne for src and kZero for dst (i.e. src mode).
- */
- void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
- fSrcBlendCoeff = srcCoeff;
- fDstBlendCoeff = dstCoeff;
- }
- GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlendCoeff; }
- GrBlendCoeff getDstBlendCoeff() const { return fDstBlendCoeff; }
-
- /**
* The initial color of the drawn primitive. Defaults to solid white.
*/
void setColor(GrColor color) { fColor = color; }
@@ -84,6 +74,14 @@ public:
return xpFactory;
}
+ void setPorterDuffXPFactory(SkXfermode::Mode mode) {
+ fXPFactory.reset(GrPorterDuffXPFactory::Create(mode));
+ }
+
+ void setPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst) {
+ fXPFactory.reset(GrPorterDuffXPFactory::Create(src, dst));
+ }
+
/**
* Appends an additional color processor to the color computation.
*/
@@ -121,8 +119,6 @@ public:
const GrFragmentStage& getCoverageStage(int s) const { return fCoverageStages[s]; }
GrPaint& operator=(const GrPaint& paint) {
- fSrcBlendCoeff = paint.fSrcBlendCoeff;
- fDstBlendCoeff = paint.fDstBlendCoeff;
fAntiAlias = paint.fAntiAlias;
fDither = paint.fDither;
@@ -140,7 +136,6 @@ public:
* Resets the paint to the defaults.
*/
void reset() {
- this->resetBlend();
this->resetOptions();
this->resetColor();
this->resetStages();
@@ -211,18 +206,11 @@ private:
SkSTArray<4, GrFragmentStage> fColorStages;
SkSTArray<2, GrFragmentStage> fCoverageStages;
- GrBlendCoeff fSrcBlendCoeff;
- GrBlendCoeff fDstBlendCoeff;
bool fAntiAlias;
bool fDither;
GrColor fColor;
- void resetBlend() {
- fSrcBlendCoeff = kOne_GrBlendCoeff;
- fDstBlendCoeff = kZero_GrBlendCoeff;
- }
-
void resetOptions() {
fAntiAlias = false;
fDither = false;
@@ -232,7 +220,7 @@ private:
fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
}
- void resetStages();
+ void resetStages();
};
#endif
diff --git a/include/gpu/GrXferProcessor.h b/include/gpu/GrXferProcessor.h
index 10ecf54c75..b7d0bdd9fa 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;
diff --git a/include/gpu/effects/GrPorterDuffXferProcessor.h b/include/gpu/effects/GrPorterDuffXferProcessor.h
index 9ff3bea2ed..0ddfcdcd2a 100644
--- a/include/gpu/effects/GrPorterDuffXferProcessor.h
+++ b/include/gpu/effects/GrPorterDuffXferProcessor.h
@@ -17,8 +17,9 @@ class GrInvariantOutput;
class GrPorterDuffXferProcessor : public GrXferProcessor {
public:
- static GrXferProcessor* Create(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend) {
- return SkNEW_ARGS(GrPorterDuffXferProcessor, (srcBlend, dstBlend));
+ static GrXferProcessor* Create(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend,
+ GrColor constant = 0) {
+ return SkNEW_ARGS(GrPorterDuffXferProcessor, (srcBlend, dstBlend, constant));
}
virtual ~GrPorterDuffXferProcessor();
@@ -30,12 +31,28 @@ public:
virtual GrGLFragmentProcessor* createGLInstance() const SK_OVERRIDE;
+ virtual GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ bool isCoverageDrawing,
+ bool colorWriteDisabled,
+ bool doesStencilWrite,
+ GrColor* color,
+ uint8_t* coverage) SK_OVERRIDE;
+
+ virtual void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE {
+ blendInfo->fSrcBlend = fSrcBlend;
+ blendInfo->fDstBlend = fDstBlend;
+ blendInfo->fBlendConstant = fBlendConstant;
+ }
+
private:
- GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend);
+ GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColor constant);
virtual bool onIsEqual(const GrFragmentProcessor& fpBase) const SK_OVERRIDE {
const GrPorterDuffXferProcessor& xp = fpBase.cast<GrPorterDuffXferProcessor>();
- if (fSrcBlend != xp.fSrcBlend || fDstBlend != xp.fDstBlend) {
+ if (fSrcBlend != xp.fSrcBlend ||
+ fDstBlend != xp.fDstBlend ||
+ fBlendConstant != xp.fBlendConstant) {
return false;
}
return true;
@@ -45,7 +62,8 @@ private:
GrBlendCoeff fSrcBlend;
GrBlendCoeff fDstBlend;
-
+ GrColor fBlendConstant;
+
typedef GrXferProcessor INHERITED;
};
@@ -63,20 +81,34 @@ public:
return SkNEW_ARGS(GrPorterDuffXPFactory, (src, dst));
}
- const GrXferProcessor* createXferProcessor() const SK_OVERRIDE;
+ GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI) const SK_OVERRIDE;
bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE;
+ bool canApplyCoverage(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
+ bool isCoverageDrawing, bool colorWriteDisabled) const SK_OVERRIDE;
+
+ bool willBlendWithDst(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
+ bool isCoverageDrawing, bool colorWriteDisabled) const SK_OVERRIDE;
+
+ bool canTweakAlphaForCoverage(bool isCoverageDrawing) const SK_OVERRIDE;
+
+ bool getOpaqueAndKnownColor(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ GrColor* solidColor,
+ uint32_t* solidColorKnownComponents) const SK_OVERRIDE;
+
private:
GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst);
bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE {
const GrPorterDuffXPFactory& xpf = xpfBase.cast<GrPorterDuffXPFactory>();
- return (fSrc == xpf.fSrc && fDst == xpf.fDst);
+ return (fSrcCoeff == xpf.fSrcCoeff && fDstCoeff == xpf.fDstCoeff);
}
- GrBlendCoeff fSrc;
- GrBlendCoeff fDst;
+ GrBlendCoeff fSrcCoeff;
+ GrBlendCoeff fDstCoeff;
typedef GrXPFactory INHERITED;
};