* A caller who calls this function on a XP is required to honor the returned OptFlags
* and color values for its draw.
*/
- virtual OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI,
- bool doesStencilWrite,
- GrColor* overrideColor,
- const GrDrawTargetCaps& caps) = 0;
+ OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ bool doesStencilWrite,
+ GrColor* overrideColor,
+ const GrDrawTargetCaps& caps);
/**
* Returns whether this XP will require an Xfer barrier on the given rt. If true, outBarrierType
return fDstCopyTextureOffset;
}
+ /**
+ * Returns whether or not the XP will look at coverage when doing its blending.
+ */
+ bool readsCoverage() const { return fReadsCoverage; }
+
/**
* Returns whether or not this xferProcossor will set a secondary output to be used with dual
* source blending.
if (this->fWillReadDstColor != that.fWillReadDstColor) {
return false;
}
+ if (this->fReadsCoverage != that.fReadsCoverage) {
+ return false;
+ }
if (this->fDstCopy.getTexture() != that.fDstCopy.getTexture()) {
return false;
}
GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
private:
+ virtual OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ bool doesStencilWrite,
+ GrColor* overrideColor,
+ const GrDrawTargetCaps& caps) = 0;
+
/**
* Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this xfer
* processor's GL backend implementation.
virtual bool onIsEqual(const GrXferProcessor&) const = 0;
bool fWillReadDstColor;
+ bool fReadsCoverage;
SkIPoint fDstCopyTextureOffset;
GrTextureAccess fDstCopy;
bool hasSecondaryOutput() const override { return false; }
- GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI,
- bool doesStencilWrite,
- GrColor* overrideColor,
- const GrDrawTargetCaps& caps) override;
-
float k1() const { return fK1; }
float k2() const { return fK2; }
float k3() const { return fK3; }
ArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor,
const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
+ GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ bool doesStencilWrite,
+ GrColor* overrideColor,
+ const GrDrawTargetCaps& caps) override;
+
void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
bool onIsEqual(const GrXferProcessor& xpBase) const override {
return SkNEW_ARGS(GLArithmeticXP, (*this));
}
-GrXferProcessor::OptFlags ArithmeticXP::getOptimizations(const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI,
- bool doesStencilWrite,
- GrColor* overrideColor,
- const GrDrawTargetCaps& caps) {
+GrXferProcessor::OptFlags ArithmeticXP::onGetOptimizations(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ bool doesStencilWrite,
+ GrColor* overrideColor,
+ const GrDrawTargetCaps& caps) {
return GrXferProcessor::kNone_Opt;
}
#include "GrXferProcessor.h"
#include "gl/GrGLCaps.h"
-GrXferProcessor::GrXferProcessor() : fWillReadDstColor(false), fDstCopyTextureOffset() {
+GrXferProcessor::GrXferProcessor()
+ : fWillReadDstColor(false), fReadsCoverage(true), fDstCopyTextureOffset() {
}
GrXferProcessor::GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willReadDstColor)
: fWillReadDstColor(willReadDstColor)
+ , fReadsCoverage(true)
, fDstCopyTextureOffset() {
if (dstCopy && dstCopy->texture()) {
fDstCopy.reset(dstCopy->texture());
}
}
+GrXferProcessor::OptFlags GrXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ bool doesStencilWrite,
+ GrColor* overrideColor,
+ const GrDrawTargetCaps& caps) {
+ GrXferProcessor::OptFlags flags = this->onGetOptimizations(colorPOI,
+ coveragePOI,
+ doesStencilWrite,
+ overrideColor,
+ caps);
+
+ if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
+ fReadsCoverage = false;
+ }
+ return flags;
+}
+
void GrXferProcessor::getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const {
uint32_t key = this->willReadDstColor() ? 0x1 : 0x0;
if (this->getDstCopyTexture() &&
bool hasSecondaryOutput() const override { return false; }
- GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI,
- bool doesStencilWrite,
- GrColor* color,
- const GrDrawTargetCaps& caps) override;
-
bool invertCoverage() const { return fInvertCoverage; }
private:
CoverageSetOpXP(SkRegion::Op regionOp, bool fInvertCoverage);
+ GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ bool doesStencilWrite,
+ GrColor* color,
+ const GrDrawTargetCaps& caps) override;
+
void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override;
}
GrXferProcessor::OptFlags
-CoverageSetOpXP::getOptimizations(const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI,
- bool doesStencilWrite,
- GrColor* color,
- const GrDrawTargetCaps& caps) {
+CoverageSetOpXP::onGetOptimizations(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ bool doesStencilWrite,
+ GrColor* color,
+ const GrDrawTargetCaps& caps) {
// We never look at the color input
return GrXferProcessor::kIgnoreColor_OptFlag;
}
bool hasSecondaryOutput() const override { return false; }
- GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI,
- bool doesStencilWrite,
- GrColor* overrideColor,
- const GrDrawTargetCaps& caps) override;
-
SkXfermode::Mode mode() const { return fMode; }
- bool hasCoverage() const { return fHasCoverage; }
bool hasHWBlendEquation() const { return kInvalid_GrBlendEquation != fHWBlendEquation; }
GrBlendEquation hwBlendEquation() const {
private:
CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
+ GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ bool doesStencilWrite,
+ GrColor* overrideColor,
+ const GrDrawTargetCaps& caps) override;
+
void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
bool onWillNeedXferBarrier(const GrRenderTarget* rt,
bool onIsEqual(const GrXferProcessor& xpBase) const override;
SkXfermode::Mode fMode;
- bool fHasCoverage;
GrBlendEquation fHWBlendEquation;
typedef GrXferProcessor INHERITED;
const CustomXP& xp = p.cast<CustomXP>();
uint32_t key = xp.numTextures();
SkASSERT(key <= 1);
- key |= xp.hasCoverage() << 1;
+ key |= xp.readsCoverage() << 1;
if (xp.hasHWBlendEquation()) {
SkASSERT(caps.advBlendEqInteraction() > 0); // 0 will mean !xp.hasHWBlendEquation().
key |= caps.advBlendEqInteraction() << 2;
if (xp.hasHWBlendEquation()) {
// The blend mode will be implemented in hardware; only output the src color.
fsBuilder->enableAdvancedBlendEquationIfNeeded(xp.hwBlendEquation());
- if (xp.hasCoverage()) {
+ if (xp.readsCoverage()) {
// Do coverage modulation by multiplying it into the src color before blending.
// (See getOptimizations())
fsBuilder->codeAppendf("%s = %s * %s;",
const char* dstColor = fsBuilder->dstColor();
emit_custom_xfermode_code(xp.mode(), fsBuilder, args.fOutputPrimary, args.fInputColor,
dstColor);
- if (xp.hasCoverage()) {
+ if (xp.readsCoverage()) {
fsBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;",
args.fOutputPrimary, args.fOutputPrimary,
args.fInputCoverage, args.fInputCoverage, dstColor);
bool willReadDstColor)
: INHERITED(dstCopy, willReadDstColor),
fMode(mode),
- fHasCoverage(true),
fHWBlendEquation(kInvalid_GrBlendEquation) {
this->initClassID<CustomXP>();
}
bool CustomXP::onIsEqual(const GrXferProcessor& other) const {
const CustomXP& s = other.cast<CustomXP>();
- return fMode == s.fMode &&
- fHasCoverage == s.fHasCoverage &&
- fHWBlendEquation == s.fHWBlendEquation;
+ return fMode == s.fMode && fHWBlendEquation == s.fHWBlendEquation;
}
-GrXferProcessor::OptFlags CustomXP::getOptimizations(const GrProcOptInfo& colorPOI,
+GrXferProcessor::OptFlags CustomXP::onGetOptimizations(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
bool doesStencilWrite,
GrColor* overrideColor,
}
if (coveragePOI.isSolidWhite()) {
flags = flags | kIgnoreCoverage_OptFlag;
- fHasCoverage = false;
}
if (caps.advancedBlendEquationSupport() && !coveragePOI.isFourChannelOutput()) {
// This blend mode can be implemented in hardware.
bool hasSecondaryOutput() const override { return false; }
- GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI,
- bool doesStencilWrite,
- GrColor* color,
- const GrDrawTargetCaps& caps) override {
- return GrXferProcessor::kIgnoreColor_OptFlag | GrXferProcessor::kIgnoreCoverage_OptFlag;
- }
-
private:
DisableColorXP();
+ GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ bool doesStencilWrite,
+ GrColor* color,
+ const GrDrawTargetCaps& caps) override {
+ return GrXferProcessor::kIgnoreColor_OptFlag | GrXferProcessor::kIgnoreCoverage_OptFlag;
+ }
+
void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override;
PrimaryOutputType primaryOutputType() const { return fPrimaryOutputType; }
SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputType; }
- GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI,
- bool doesStencilWrite,
- GrColor* overrideColor,
- const GrDrawTargetCaps& caps) override;
-
GrBlendCoeff getSrcBlend() const { return fSrcBlend; }
GrBlendCoeff getDstBlend() const { return fDstBlend; }
PorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColor constant,
const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
+ GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ bool doesStencilWrite,
+ GrColor* overrideColor,
+ const GrDrawTargetCaps& caps) override;
+
void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override {
}
GrXferProcessor::OptFlags
-PorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI,
- bool doesStencilWrite,
- GrColor* overrideColor,
- const GrDrawTargetCaps& caps) {
+PorterDuffXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ bool doesStencilWrite,
+ GrColor* overrideColor,
+ const GrDrawTargetCaps& caps) {
GrXferProcessor::OptFlags optFlags;
// Optimizations when doing RGB Coverage
if (coveragePOI.isFourChannelOutput()) {
GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
- // We don't think any shaders actually output negative coverage, but just as a safety check
- // for floating point precision errors we compare with <= here
- fsBuilder->codeAppendf("if (all(lessThanEqual(%s, vec4(0)))) {"
- " discard;"
- "}", args.fInputCoverage);
+ if (args.fXP.readsCoverage()) {
+ // We don't think any shaders actually output negative coverage, but just as a safety
+ // check for floating point precision errors we compare with <= here
+ fsBuilder->codeAppendf("if (all(lessThanEqual(%s, vec4(0)))) {"
+ " discard;"
+ "}", args.fInputCoverage);
+ }
+
const char* dstColor = fsBuilder->dstColor();
const char* dstCopyTopLeftName;