aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--expectations/gm/ignored-tests.txt4
-rw-r--r--include/gpu/GrProcessorUnitTest.h32
-rw-r--r--include/gpu/GrXferProcessor.h44
-rw-r--r--include/gpu/effects/GrPorterDuffXferProcessor.h75
-rw-r--r--src/gpu/GrGeometryProcessor.h5
-rw-r--r--src/gpu/GrOptDrawState.cpp43
-rw-r--r--src/gpu/GrOptDrawState.h3
-rw-r--r--src/gpu/GrProcessor.cpp12
-rw-r--r--src/gpu/GrProgramDesc.h41
-rw-r--r--src/gpu/effects/GrPorterDuffXferProcessor.cpp123
-rw-r--r--src/gpu/gl/GrGLProcessor.h10
-rw-r--r--src/gpu/gl/GrGLProgram.cpp23
-rw-r--r--src/gpu/gl/GrGLProgram.h7
-rw-r--r--src/gpu/gl/GrGLProgramDesc.cpp15
-rw-r--r--src/gpu/gl/GrGLXferProcessor.h61
-rw-r--r--src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp49
-rw-r--r--src/gpu/gl/builders/GrGLFragmentShaderBuilder.h2
-rw-r--r--src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp3
-rw-r--r--src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp3
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp65
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.h24
-rw-r--r--tests/GLProgramsTest.cpp29
22 files changed, 228 insertions, 445 deletions
diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt
index 396ca20424..31b71225fa 100644
--- a/expectations/gm/ignored-tests.txt
+++ b/expectations/gm/ignored-tests.txt
@@ -51,10 +51,6 @@ imagemagnifier
#reed
modecolorfilters
-#egdaniel
-xfermodes3
-mixed_xfermodes
-
#humper skia:2049
dashcubics
diff --git a/include/gpu/GrProcessorUnitTest.h b/include/gpu/GrProcessorUnitTest.h
index 4b97483c0f..fbf4382d69 100644
--- a/include/gpu/GrProcessorUnitTest.h
+++ b/include/gpu/GrProcessorUnitTest.h
@@ -149,14 +149,6 @@ private:
const GrDrawTargetCaps&, \
GrTexture* dummyTextures[2])
-#define GR_DECLARE_XP_FACTORY_TEST \
- static GrProcessorTestFactory<GrXPFactory> gTestFactory SK_UNUSED; \
- static GrXPFactory* TestCreate(SkRandom*, \
- GrContext*, \
- const GrDrawTargetCaps&, \
- GrTexture* dummyTextures[2])
-
-
/** GrProcessor subclasses should insert this macro in their implementation file. They must then
* also implement this static function:
* GrProcessor* TestCreate(SkRandom*,
@@ -171,9 +163,6 @@ private:
#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect) \
GrProcessorTestFactory<GrFragmentProcessor> Effect :: gTestFactory(Effect :: TestCreate)
-#define GR_DEFINE_XP_FACTORY_TEST(Factory) \
- GrProcessorTestFactory<GrXPFactory> Factory :: gTestFactory(Factory :: TestCreate)
-
#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect) \
GrProcessorTestFactory<GrGeometryProcessor> Effect :: gTestFactory(Effect :: TestCreate)
@@ -183,27 +172,18 @@ private:
// its definitions will compile.
#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \
static GrFragmentProcessor* TestCreate(SkRandom*, \
- GrContext*, \
- const GrDrawTargetCaps&, \
- GrTexture* dummyTextures[2])
+ GrContext*, \
+ const GrDrawTargetCaps&, \
+ GrTexture* dummyTextures[2])
#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
// The unit test relies on static initializers. Just declare the TestCreate function so that
// its definitions will compile.
-#define GR_DECLARE_XP_FACTORY_TEST \
- static GrXPFactory* TestCreate(SkRandom*, \
- GrContext*, \
- const GrDrawTargetCaps&, \
- GrTexture* dummyTextures[2])
-#define GR_DEFINE_XP_FACTORY_TEST(X)
-
-// The unit test relies on static initializers. Just declare the TestCreate function so that
-// its definitions will compile.
#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \
static GrGeometryProcessor* TestCreate(SkRandom*, \
- GrContext*, \
- const GrDrawTargetCaps&, \
- GrTexture* dummyTextures[2])
+ GrContext*, \
+ const GrDrawTargetCaps&, \
+ GrTexture* dummyTextures[2])
#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
#endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
diff --git a/include/gpu/GrXferProcessor.h b/include/gpu/GrXferProcessor.h
index 696359b8b3..b7d0bdd9fa 100644
--- a/include/gpu/GrXferProcessor.h
+++ b/include/gpu/GrXferProcessor.h
@@ -9,13 +9,10 @@
#define GrXferProcessor_DEFINED
#include "GrColor.h"
-#include "GrProcessor.h"
+#include "GrFragmentProcessor.h"
#include "GrTypes.h"
#include "SkXfermode.h"
-class GrDrawTargetCaps;
-class GrGLCaps;
-class GrGLXferProcessor;
class GrProcOptInfo;
/**
@@ -31,21 +28,9 @@ class GrProcOptInfo;
* A GrXferProcessor is never installed directly into our draw state, but instead is created from a
* GrXPFactory once we have finalized the state of our draw.
*/
-class GrXferProcessor : public GrProcessor {
+class GrXferProcessor : public GrFragmentProcessor {
public:
/**
- * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this xfer
- * processor's GL backend implementation.
- */
- virtual void getGLProcessorKey(const GrGLCaps& caps,
- GrProcessorKeyBuilder* b) const = 0;
-
- /** Returns a new instance of the appropriate *GL* implementation class
- for the given GrXferProcessor; caller is responsible for deleting
- the object. */
- virtual GrGLXferProcessor* createGLInstance() const = 0;
-
- /**
* Optimizations for blending / coverage that an OptDrawState should apply to itself.
*/
enum OptFlags {
@@ -89,8 +74,7 @@ public:
bool colorWriteDisabled,
bool doesStencilWrite,
GrColor* color,
- uint8_t* coverage,
- const GrDrawTargetCaps& caps) = 0;
+ uint8_t* coverage) = 0;
struct BlendInfo {
GrBlendCoeff fSrcBlend;
@@ -103,27 +87,6 @@ public:
/** Will this prceossor read the destination pixel value? */
bool willReadDstColor() const { return fWillReadDstColor; }
- /**
- * Returns whether or not this xferProcossor will set a secondary output to be used with dual
- * source blending.
- */
- virtual bool hasSecondaryOutput() const { return false; }
-
- /** 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
- from getFactory()).
-
- A return value of true from isEqual() should not be used to test whether the processor would
- generate the same shader code. To test for identical code generation use getGLProcessorKey*/
-
- bool isEqual(const GrXferProcessor& that) const {
- if (this->classID() != that.classID()) {
- return false;
- }
- return this->onIsEqual(that);
- }
-
-
protected:
GrXferProcessor() : fWillReadDstColor(false) {}
@@ -135,7 +98,6 @@ protected:
void setWillReadDstColor() { fWillReadDstColor = true; }
private:
- virtual bool onIsEqual(const GrXferProcessor&) const = 0;
bool fWillReadDstColor;
diff --git a/include/gpu/effects/GrPorterDuffXferProcessor.h b/include/gpu/effects/GrPorterDuffXferProcessor.h
index 26800c7f8f..0ddfcdcd2a 100644
--- a/include/gpu/effects/GrPorterDuffXferProcessor.h
+++ b/include/gpu/effects/GrPorterDuffXferProcessor.h
@@ -26,44 +26,20 @@ public:
virtual const char* name() const { return "Porter Duff"; }
- void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
-
- GrGLXferProcessor* createGLInstance() const SK_OVERRIDE;
-
- virtual bool hasSecondaryOutput() const SK_OVERRIDE;
-
- ///////////////////////////////////////////////////////////////////////////
- /// @name Stage Output Types
- ////
-
- enum SecondaryOutputType {
- // There is no secondary output
- kNone_SecondaryOutputType,
- // Writes coverage as the secondary output. Only set if dual source blending is supported
- // and primary output is kModulate.
- kCoverage_SecondaryOutputType,
- // Writes coverage * (1 - colorA) as the secondary output. Only set if dual source blending
- // is supported and primary output is kModulate.
- kCoverageISA_SecondaryOutputType,
- // Writes coverage * (1 - colorRGBA) as the secondary output. Only set if dual source
- // blending is supported and primary output is kModulate.
- kCoverageISC_SecondaryOutputType,
-
- kSecondaryOutputTypeCnt,
- };
-
- SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputType; }
-
- GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI,
- bool isCoverageDrawing,
- bool colorWriteDisabled,
- bool doesStencilWrite,
- GrColor* color,
- uint8_t* coverage,
- const GrDrawTargetCaps& caps) SK_OVERRIDE;
-
- void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE {
+ virtual void getGLProcessorKey(const GrGLCaps& caps,
+ GrProcessorKeyBuilder* b) const SK_OVERRIDE;
+
+ 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;
@@ -72,34 +48,21 @@ public:
private:
GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColor constant);
- bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE {
- const GrPorterDuffXferProcessor& xp = xpBase.cast<GrPorterDuffXferProcessor>();
+ virtual bool onIsEqual(const GrFragmentProcessor& fpBase) const SK_OVERRIDE {
+ const GrPorterDuffXferProcessor& xp = fpBase.cast<GrPorterDuffXferProcessor>();
if (fSrcBlend != xp.fSrcBlend ||
fDstBlend != xp.fDstBlend ||
- fBlendConstant != xp.fBlendConstant ||
- fSecondaryOutputType != xp.fSecondaryOutputType) {
+ fBlendConstant != xp.fBlendConstant) {
return false;
}
return true;
}
- void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
-
- GrXferProcessor::OptFlags internalGetOptimizations(const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI,
- bool isCoverageDrawing,
- bool colorWriteDisabled,
- bool doesStencilWrite,
- GrColor* color,
- uint8_t* coverage);
-
- void calcOutputTypes(GrXferProcessor::OptFlags blendOpts, const GrDrawTargetCaps& caps,
- bool isCoverageDrawing, bool readDst);
+ virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
GrBlendCoeff fSrcBlend;
GrBlendCoeff fDstBlend;
GrColor fBlendConstant;
- SecondaryOutputType fSecondaryOutputType;
typedef GrXferProcessor INHERITED;
};
@@ -144,8 +107,6 @@ private:
return (fSrcCoeff == xpf.fSrcCoeff && fDstCoeff == xpf.fDstCoeff);
}
- GR_DECLARE_XP_FACTORY_TEST;
-
GrBlendCoeff fSrcCoeff;
GrBlendCoeff fDstCoeff;
diff --git a/src/gpu/GrGeometryProcessor.h b/src/gpu/GrGeometryProcessor.h
index a0cfc09d45..4801069005 100644
--- a/src/gpu/GrGeometryProcessor.h
+++ b/src/gpu/GrGeometryProcessor.h
@@ -62,10 +62,7 @@ public:
virtual const char* name() const = 0;
- /**
- * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
- * processor's GL backend implementation.
- */
+ /** Implemented using GLProcessor::GenKey as described in this class's comment. */
virtual void getGLProcessorKey(const GrBatchTracker& bt,
const GrGLCaps& caps,
GrProcessorKeyBuilder* b) const = 0;
diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp
index 9ebe551d6b..409305ce33 100644
--- a/src/gpu/GrOptDrawState.cpp
+++ b/src/gpu/GrOptDrawState.cpp
@@ -44,8 +44,7 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
drawState.isColorWriteDisabled(),
drawState.getStencil().doesWrite(),
&fColor,
- &fCoverage,
- caps);
+ &fCoverage);
}
// When path rendering the stencil settings are not always set on the draw state
@@ -147,6 +146,42 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
init.fCoverage = this->getCoverage();
fGeometryProcessor->initBatchTracker(&fBatchTracker, init);
}
+
+ this->setOutputStateInfo(drawState, coverageColor, optFlags, caps);
+}
+
+void GrOptDrawState::setOutputStateInfo(const GrDrawState& ds,
+ GrColor coverage,
+ GrXferProcessor::OptFlags optFlags,
+ const GrDrawTargetCaps& caps) {
+ // Set this default and then possibly change our mind if there is coverage.
+ fDescInfo.fPrimaryOutputType = GrProgramDesc::kModulate_PrimaryOutputType;
+ fDescInfo.fSecondaryOutputType = GrProgramDesc::kNone_SecondaryOutputType;
+
+ // Determine whether we should use dual source blending or shader code to keep coverage
+ // separate from color.
+ bool keepCoverageSeparate = !(optFlags & GrXferProcessor::kSetCoverageDrawing_OptFlag);
+ if (keepCoverageSeparate && !ds.hasSolidCoverage(coverage)) {
+ if (caps.dualSourceBlendingSupport()) {
+ if (kZero_GrBlendCoeff == fDstBlend) {
+ // write the coverage value to second color
+ fDescInfo.fSecondaryOutputType = GrProgramDesc::kCoverage_SecondaryOutputType;
+ fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+ } else if (kSA_GrBlendCoeff == fDstBlend) {
+ // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
+ fDescInfo.fSecondaryOutputType = GrProgramDesc::kCoverageISA_SecondaryOutputType;
+ fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+ } else if (kSC_GrBlendCoeff == fDstBlend) {
+ // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
+ fDescInfo.fSecondaryOutputType = GrProgramDesc::kCoverageISC_SecondaryOutputType;
+ fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+ }
+ } else if (fDescInfo.fReadsDst &&
+ kOne_GrBlendCoeff == fSrcBlend &&
+ kZero_GrBlendCoeff == fDstBlend) {
+ fDescInfo.fPrimaryOutputType = GrProgramDesc::kCombineWithDst_PrimaryOutputType;
+ }
+ }
}
void GrOptDrawState::adjustProgramFromOptimizations(const GrDrawState& ds,
@@ -227,10 +262,6 @@ bool GrOptDrawState::operator== (const GrOptDrawState& that) const {
return false;
}
- if (!this->getXferProcessor()->isEqual(*that.getXferProcessor())) {
- return false;
- }
-
// The program desc comparison should have already assured that the stage counts match.
SkASSERT(this->numFragmentStages() == that.numFragmentStages());
for (int i = 0; i < this->numFragmentStages(); i++) {
diff --git a/src/gpu/GrOptDrawState.h b/src/gpu/GrOptDrawState.h
index 55a5071d41..cf5737373c 100644
--- a/src/gpu/GrOptDrawState.h
+++ b/src/gpu/GrOptDrawState.h
@@ -79,8 +79,7 @@ public:
int numCoverageStages() const { return fFragmentStages.count() - fNumColorStages; }
int numFragmentStages() const { return fFragmentStages.count(); }
int numTotalStages() const {
- // the + 1 at the end is for the xferProcessor which will always be present
- return this->numFragmentStages() + (this->hasGeometryProcessor() ? 1 : 0) + 1;
+ return this->numFragmentStages() + (this->hasGeometryProcessor() ? 1 : 0);
}
bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index 2bcd9b46a2..ccd4d7f7e8 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -32,9 +32,9 @@ GrProcessorTestFactory<GrFragmentProcessor>::GetFactories() {
}
template<>
-SkTArray<GrProcessorTestFactory<GrXPFactory>*, true>*
-GrProcessorTestFactory<GrXPFactory>::GetFactories() {
- static SkTArray<GrProcessorTestFactory<GrXPFactory>*, true> gFactories;
+SkTArray<GrProcessorTestFactory<GrXferProcessor>*, true>*
+GrProcessorTestFactory<GrXferProcessor>::GetFactories() {
+ static SkTArray<GrProcessorTestFactory<GrXferProcessor>*, true> gFactories;
return &gFactories;
}
@@ -52,7 +52,7 @@ GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() {
*/
static const int kFPFactoryCount = 37;
static const int kGPFactoryCount = 14;
-static const int kXPFactoryCount = 1;
+static const int kXPFactoryCount = 0;
template<>
void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() {
@@ -69,9 +69,9 @@ void GrProcessorTestFactory<GrGeometryProcessor>::VerifyFactoryCount() {
}
template<>
-void GrProcessorTestFactory<GrXPFactory>::VerifyFactoryCount() {
+void GrProcessorTestFactory<GrXferProcessor>::VerifyFactoryCount() {
if (kXPFactoryCount != GetFactories()->count()) {
- SkFAIL("Wrong number of xp factory factories!");
+ SkFAIL("Wrong number of xfer processor factories!");
}
}
diff --git a/src/gpu/GrProgramDesc.h b/src/gpu/GrProgramDesc.h
index 3d53842e43..a20b99f749 100644
--- a/src/gpu/GrProgramDesc.h
+++ b/src/gpu/GrProgramDesc.h
@@ -55,6 +55,36 @@ public:
}
+ ///////////////////////////////////////////////////////////////////////////
+ /// @name Stage Output Types
+ ////
+
+ enum PrimaryOutputType {
+ // Modulate color and coverage, write result as the color output.
+ kModulate_PrimaryOutputType,
+ // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This
+ // can only be set if fDstReadKey is non-zero.
+ kCombineWithDst_PrimaryOutputType,
+
+ kPrimaryOutputTypeCnt,
+ };
+
+ enum SecondaryOutputType {
+ // There is no secondary output
+ kNone_SecondaryOutputType,
+ // Writes coverage as the secondary output. Only set if dual source blending is supported
+ // and primary output is kModulate.
+ kCoverage_SecondaryOutputType,
+ // Writes coverage * (1 - colorA) as the secondary output. Only set if dual source blending
+ // is supported and primary output is kModulate.
+ kCoverageISA_SecondaryOutputType,
+ // Writes coverage * (1 - colorRGBA) as the secondary output. Only set if dual source
+ // blending is supported and primary output is kModulate.
+ kCoverageISC_SecondaryOutputType,
+
+ kSecondaryOutputTypeCnt,
+ };
+
// Specifies where the initial color comes from before the stages are applied.
enum ColorInput {
kAllOnes_ColorInput,
@@ -75,6 +105,9 @@ public:
ColorInput fColorInput : 8;
ColorInput fCoverageInput : 8;
+ PrimaryOutputType fPrimaryOutputType : 8;
+ SecondaryOutputType fSecondaryOutputType : 8;
+
SkBool8 fHasGeometryProcessor;
int8_t fColorEffectCnt;
int8_t fCoverageEffectCnt;
@@ -107,7 +140,10 @@ public:
fInputCoverageIsUsed == that.fInputCoverageIsUsed &&
fReadsDst == that.fReadsDst &&
fReadsFragPosition == that.fReadsFragPosition &&
- fRequiresLocalCoordAttrib == that.fRequiresLocalCoordAttrib;
+ fRequiresLocalCoordAttrib == that.fRequiresLocalCoordAttrib &&
+ fPrimaryOutputType == that.fPrimaryOutputType &&
+ fSecondaryOutputType == that.fSecondaryOutputType;
+
}
bool operator!=(const DescInfo& that) const { return !(*this == that); };
// TODO when GPs control uniform / attribute handling of color / coverage, then we can
@@ -126,6 +162,9 @@ public:
bool fReadsFragPosition;
bool fRequiresLocalCoordAttrib;
+ // Fragment shader color outputs
+ GrProgramDesc::PrimaryOutputType fPrimaryOutputType : 8;
+ GrProgramDesc::SecondaryOutputType fSecondaryOutputType : 8;
};
private:
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index 097854622d..2b4b1334f8 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -9,12 +9,11 @@
#include "GrBlend.h"
#include "GrDrawState.h"
-#include "GrDrawTargetCaps.h"
#include "GrInvariantOutput.h"
#include "GrProcessor.h"
#include "GrTypes.h"
#include "GrXferProcessor.h"
-#include "gl/GrGLXferProcessor.h"
+#include "gl/GrGLProcessor.h"
#include "gl/builders/GrGLFragmentShaderBuilder.h"
#include "gl/builders/GrGLProgramBuilder.h"
@@ -43,40 +42,19 @@ public:
virtual ~GrGLPorterDuffXferProcessor() {}
- virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
- const GrPorterDuffXferProcessor& xp = args.fXP.cast<GrPorterDuffXferProcessor>();
- GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
- if (xp.hasSecondaryOutput()) {
- switch(xp.secondaryOutputType()) {
- case GrPorterDuffXferProcessor::kCoverage_SecondaryOutputType:
- fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, args.fInputCoverage);
- break;
- case GrPorterDuffXferProcessor::kCoverageISA_SecondaryOutputType:
- fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;",
- args.fOutputSecondary, args.fInputColor,
- args.fInputCoverage);
- break;
- case GrPorterDuffXferProcessor::kCoverageISC_SecondaryOutputType:
- fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;",
- args.fOutputSecondary, args.fInputColor,
- args.fInputCoverage);
- break;
- default:
- SkFAIL("Unexpected Secondary Output");
- }
- }
-
- fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor,
- args.fInputCoverage);
+ virtual void emitCode(GrGLFPBuilder* builder,
+ const GrFragmentProcessor& fp,
+ const char* outputColor,
+ const char* inputColor,
+ const TransformedCoordsArray& coords,
+ const TextureSamplerArray& samplers) SK_OVERRIDE {
+ GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppendf("%s = %s;", outputColor, inputColor);
}
- virtual void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {};
+ virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {};
- static void GenKey(const GrProcessor& processor, const GrGLCaps& caps,
- GrProcessorKeyBuilder* b) {
- const GrPorterDuffXferProcessor& xp = processor.cast<GrPorterDuffXferProcessor>();
- b->add32(xp.secondaryOutputType());
- };
+ static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b) {};
private:
typedef GrGLXferProcessor INHERITED;
@@ -86,10 +64,7 @@ private:
GrPorterDuffXferProcessor::GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend,
GrColor constant)
- : fSrcBlend(srcBlend)
- , fDstBlend(dstBlend)
- , fBlendConstant(constant)
- , fSecondaryOutputType(kNone_SecondaryOutputType) {
+ : fSrcBlend(srcBlend), fDstBlend(dstBlend), fBlendConstant(constant) {
this->initClassID<GrPorterDuffXferProcessor>();
}
@@ -101,7 +76,7 @@ void GrPorterDuffXferProcessor::getGLProcessorKey(const GrGLCaps& caps,
GrGLPorterDuffXferProcessor::GenKey(*this, caps, b);
}
-GrGLXferProcessor* GrPorterDuffXferProcessor::createGLInstance() const {
+GrGLFragmentProcessor* GrPorterDuffXferProcessor::createGLInstance() const {
return SkNEW_ARGS(GrGLPorterDuffXferProcessor, (*this));
}
@@ -115,54 +90,7 @@ GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI,
bool isCoverageDrawing,
bool colorWriteDisabled,
bool doesStencilWrite,
- GrColor* color, uint8_t* coverage,
- const GrDrawTargetCaps& caps) {
- GrXferProcessor::OptFlags optFlags = this->internalGetOptimizations(colorPOI,
- coveragePOI,
- isCoverageDrawing,
- colorWriteDisabled,
- doesStencilWrite,
- color,
- coverage);
-
- this->calcOutputTypes(optFlags, caps, isCoverageDrawing,
- colorPOI.readsDst() || coveragePOI.readsDst());
- return optFlags;
-}
-
-void GrPorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags,
- const GrDrawTargetCaps& caps,
- bool isCoverageDrawing, bool readsDst) {
- // If we do have coverage determine whether it matters. Dual source blending is expensive so
- // we don't do it if we are doing coverage drawing. If we aren't then We always do dual source
- // blending if we have any effective coverage stages OR the geometry processor doesn't emits
- // solid coverage.
- if (!(optFlags & kSetCoverageDrawing_OptFlag) && !isCoverageDrawing) {
- if (caps.dualSourceBlendingSupport()) {
- if (kZero_GrBlendCoeff == fDstBlend) {
- // write the coverage value to second color
- fSecondaryOutputType = kCoverage_SecondaryOutputType;
- fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
- } else if (kSA_GrBlendCoeff == fDstBlend) {
- // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
- fSecondaryOutputType = kCoverageISA_SecondaryOutputType;
- fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
- } else if (kSC_GrBlendCoeff == fDstBlend) {
- // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
- fSecondaryOutputType = kCoverageISC_SecondaryOutputType;
- fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
- }
- }
- }
-}
-
-GrXferProcessor::OptFlags
-GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI,
- bool isCoverageDrawing,
- bool colorWriteDisabled,
- bool doesStencilWrite,
- GrColor* color, uint8_t* coverage) {
+ GrColor* color, uint8_t* coverage) {
if (colorWriteDisabled) {
fSrcBlend = kZero_GrBlendCoeff;
fDstBlend = kOne_GrBlendCoeff;
@@ -264,11 +192,6 @@ GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
return GrXferProcessor::kNone_Opt;
}
-
-bool GrPorterDuffXferProcessor::hasSecondaryOutput() const {
- return kNone_SecondaryOutputType != fSecondaryOutputType;
-}
-
///////////////////////////////////////////////////////////////////////////////
GrPorterDuffXPFactory::GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst)
@@ -527,22 +450,4 @@ bool GrPorterDuffXPFactory::getOpaqueAndKnownColor(const GrProcOptInfo& colorPOI
return opaque;
}
-GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
-
-GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random,
- GrContext*,
- const GrDrawTargetCaps&,
- GrTexture*[]) {
- GrBlendCoeff src;
- do {
- src = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPublicGrBlendCoeff));
- } while (GrBlendCoeffRefsSrc(src));
-
- GrBlendCoeff dst;
- do {
- dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPublicGrBlendCoeff));
- } while (GrBlendCoeffRefsDst(dst));
-
- return GrPorterDuffXPFactory::Create(src, dst);
-}
diff --git a/src/gpu/gl/GrGLProcessor.h b/src/gpu/gl/GrGLProcessor.h
index a4fad753ec..6dccd33bac 100644
--- a/src/gpu/gl/GrGLProcessor.h
+++ b/src/gpu/gl/GrGLProcessor.h
@@ -117,4 +117,14 @@ private:
typedef GrGLProcessor INHERITED;
};
+class GrGLXferProcessor : public GrGLFragmentProcessor {
+public:
+ GrGLXferProcessor() {}
+
+ virtual ~GrGLXferProcessor() {}
+
+private:
+ typedef GrGLFragmentProcessor INHERITED;
+};
+
#endif
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index da687c1eb6..29c44ac56c 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -12,13 +12,11 @@
#include "GrCoordTransform.h"
#include "GrGLGeometryProcessor.h"
#include "GrGLProcessor.h"
-#include "GrGLXferProcessor.h"
#include "GrGpuGL.h"
#include "GrGLPathRendering.h"
#include "GrGLShaderVar.h"
#include "GrGLSL.h"
#include "GrOptDrawState.h"
-#include "GrXferProcessor.h"
#include "SkXfermode.h"
#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
@@ -59,7 +57,6 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu,
GrGLuint programID,
const UniformInfoArray& uniforms,
GrGLInstalledGeoProc* geometryProcessor,
- GrGLInstalledXferProc* xferProcessor,
GrGLInstalledFragProcs* fragmentProcessors)
: fColor(GrColor_ILLEGAL)
, fCoverage(0)
@@ -67,7 +64,6 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu,
, fBuiltinUniformHandles(builtinUniforms)
, fProgramID(programID)
, fGeometryProcessor(geometryProcessor)
- , fXferProcessor(xferProcessor)
, fFragmentProcessors(SkRef(fragmentProcessors))
, fDesc(desc)
, fGpu(gpu)
@@ -95,9 +91,6 @@ void GrGLProgram::initSamplerUniforms() {
if (fGeometryProcessor.get()) {
this->initSamplers(fGeometryProcessor.get(), &texUnitIdx);
}
- if (fXferProcessor.get()) {
- this->initSamplers(fXferProcessor.get(), &texUnitIdx);
- }
int numProcs = fFragmentProcessors->fProcs.count();
for (int i = 0; i < numProcs; i++) {
this->initSamplers(fFragmentProcessors->fProcs[i], &texUnitIdx);
@@ -169,11 +162,6 @@ void GrGLProgram::setData(const GrOptDrawState& optState) {
fGeometryProcessor->fGLProc->setData(fProgramDataManager, gp, bt);
this->bindTextures(fGeometryProcessor, gp);
}
- if (fXferProcessor.get()) {
- const GrXferProcessor& xp = *optState.getXferProcessor();
- fXferProcessor->fGLProc->setData(fProgramDataManager, xp);
- this->bindTextures(fXferProcessor, xp);
- }
this->setFragmentData(optState);
// Some of GrGLProgram subclasses need to update state here
@@ -296,10 +284,8 @@ GrGLNvprProgramBase::GrGLNvprProgramBase(GrGpuGL* gpu,
const BuiltinUniformHandles& builtinUniforms,
GrGLuint programID,
const UniformInfoArray& uniforms,
- GrGLInstalledXferProc* xferProcessor,
GrGLInstalledFragProcs* fragmentProcessors)
- : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, NULL,
- xferProcessor, fragmentProcessors) {
+ : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, NULL, fragmentProcessors) {
}
void GrGLNvprProgramBase::onSetMatrixAndRenderTargetHeight(const GrOptDrawState& optState) {
@@ -317,11 +303,9 @@ GrGLNvprProgram::GrGLNvprProgram(GrGpuGL* gpu,
const BuiltinUniformHandles& builtinUniforms,
GrGLuint programID,
const UniformInfoArray& uniforms,
- GrGLInstalledXferProc* xferProcessor,
GrGLInstalledFragProcs* fragmentProcessors,
const SeparableVaryingInfoArray& separableVaryings)
- : INHERITED(gpu, desc, builtinUniforms, programID, uniforms,
- xferProcessor, fragmentProcessors) {
+ : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, fragmentProcessors) {
int count = separableVaryings.count();
fVaryings.push_back_n(count);
for (int i = 0; i < count; i++) {
@@ -369,10 +353,9 @@ GrGLLegacyNvprProgram::GrGLLegacyNvprProgram(GrGpuGL* gpu,
const BuiltinUniformHandles& builtinUniforms,
GrGLuint programID,
const UniformInfoArray& uniforms,
- GrGLInstalledXferProc* xp,
GrGLInstalledFragProcs* fps,
int texCoordSetCnt)
- : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, xp, fps)
+ : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, fps)
, fTexCoordSetCnt(texCoordSetCnt) {
}
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index ea8be85251..36bf860233 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -141,7 +141,6 @@ protected:
GrGLuint programID,
const UniformInfoArray&,
GrGLInstalledGeoProc* geometryProcessor,
- GrGLInstalledXferProc* xferProcessor,
GrGLInstalledFragProcs* fragmentProcessors);
// Sets the texture units for samplers.
@@ -181,7 +180,6 @@ protected:
// the installed effects
SkAutoTDelete<GrGLInstalledGeoProc> fGeometryProcessor;
- SkAutoTDelete<GrGLInstalledXferProc> fXferProcessor;
SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
GrProgramDesc fDesc;
@@ -207,7 +205,6 @@ protected:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
- GrGLInstalledXferProc* xferProcessor,
GrGLInstalledFragProcs* fragmentProcessors);
virtual void onSetMatrixAndRenderTargetHeight(const GrOptDrawState&);
@@ -226,7 +223,6 @@ private:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
- GrGLInstalledXferProc* xferProcessor,
GrGLInstalledFragProcs* fragmentProcessors,
const SeparableVaryingInfoArray& separableVaryings);
virtual void didSetData(GrGpu::DrawType) SK_OVERRIDE;
@@ -256,8 +252,7 @@ private:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
- GrGLInstalledXferProc* xp,
- GrGLInstalledFragProcs* fps,
+ GrGLInstalledFragProcs* fragmentProcessors,
int texCoordSetCnt);
virtual void didSetData(GrGpu::DrawType) SK_OVERRIDE;
virtual void setTransformData(const GrPendingFragmentStage&,
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
index 2476c5532c..068386c3aa 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -189,21 +189,13 @@ bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState,
const GrFragmentProcessor& fp = *fps.getProcessor();
GrProcessorKeyBuilder b(&desc->fKey);
fp.getGLProcessorKey(gpu->glCaps(), &b);
- if (!get_meta_key(fp, gpu->glCaps(),
- gen_transform_key(fps, requiresLocalCoordAttrib), 0, &b)) {
+ if (!get_meta_key(*fps.getProcessor(), gpu->glCaps(),
+ gen_transform_key(fps, requiresLocalCoordAttrib), 0, &b)) {
desc->fKey.reset();
return false;
}
}
- const GrXferProcessor& xp = *optState.getXferProcessor();
- GrProcessorKeyBuilder b(&desc->fKey);
- xp.getGLProcessorKey(gpu->glCaps(), &b);
- if (!get_meta_key(xp, gpu->glCaps(), 0, 0, &b)) {
- desc->fKey.reset();
- return false;
- }
-
// --------DO NOT MOVE HEADER ABOVE THIS LINE--------------------------------------------------
// Because header is a pointer into the dynamic array, we can't push any new data into the key
// below here.
@@ -268,6 +260,9 @@ bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState,
header->fFragPosKey = 0;
}
+ header->fPrimaryOutputType = descInfo.fPrimaryOutputType;
+ header->fSecondaryOutputType = descInfo.fSecondaryOutputType;
+
header->fColorEffectCnt = optState.numColorStages();
header->fCoverageEffectCnt = optState.numCoverageStages();
desc->finalize();
diff --git a/src/gpu/gl/GrGLXferProcessor.h b/src/gpu/gl/GrGLXferProcessor.h
deleted file mode 100644
index 5c92559031..0000000000
--- a/src/gpu/gl/GrGLXferProcessor.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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 GrGLXferProcessor_DEFINED
-#define GrGLXferProcessor_DEFINED
-
-#include "GrGLProcessor.h"
-
-class GrGLXPBuilder;
-
-class GrGLXferProcessor {
-public:
- GrGLXferProcessor() {}
- virtual ~GrGLXferProcessor() {}
-
- typedef GrGLProcessor::TextureSamplerArray TextureSamplerArray;
- struct EmitArgs {
- EmitArgs(GrGLXPBuilder* pb,
- const GrXferProcessor& xp,
- const char* inputColor,
- const char* inputCoverage,
- const char* outputPrimary,
- const char* outputSecondary,
- const TextureSamplerArray& samplers)
- : fPB(pb)
- , fXP(xp)
- , fInputColor(inputColor)
- , fInputCoverage(inputCoverage)
- , fOutputPrimary(outputPrimary)
- , fOutputSecondary(outputSecondary)
- , fSamplers(samplers) {}
-
- GrGLXPBuilder* fPB;
- const GrXferProcessor& fXP;
- const char* fInputColor;
- const char* fInputCoverage;
- const char* fOutputPrimary;
- const char* fOutputSecondary;
- const TextureSamplerArray& fSamplers;
- };
- /**
- * This is similar to emitCode() in the base class, except it takes a full shader builder.
- * This allows the effect subclass to emit vertex code.
- */
- virtual void emitCode(const EmitArgs&) = 0;
-
- /** A GrGLXferProcessor instance can be reused with any GrGLXferProcessor that produces
- the same stage key; this function reads data from a GrGLXferProcessor and uploads any
- uniform variables required by the shaders created in emitCode(). The GrXferProcessor
- parameter is guaranteed to be of the same type that created this GrGLXferProcessor and
- to have an identical processor key as the one that created this GrGLXferProcessor. */
- virtual void setData(const GrGLProgramDataManager&,
- const GrXferProcessor&) = 0;
-private:
- typedef GrGLProcessor INHERITED;
-};
-#endif
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
index b6daca7978..49be12d8ba 100644
--- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
@@ -256,6 +256,55 @@ const char* GrGLFragmentShaderBuilder::getSecondaryColorOutputName() const {
return dual_source_output_name();
}
+void GrGLFragmentShaderBuilder::enableSecondaryOutput(const GrGLSLExpr4& inputColor,
+ const GrGLSLExpr4& inputCoverage) {
+ this->enableSecondaryOutput();
+ const char* secondaryOutputName = this->getSecondaryColorOutputName();
+ GrGLSLExpr4 coeff(1);
+ switch (fProgramBuilder->header().fSecondaryOutputType) {
+ case GrProgramDesc::kCoverage_SecondaryOutputType:
+ break;
+ case GrProgramDesc::kCoverageISA_SecondaryOutputType:
+ // Get (1-A) into coeff
+ coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
+ break;
+ case GrProgramDesc::kCoverageISC_SecondaryOutputType:
+ // Get (1-RGBA) into coeff
+ coeff = GrGLSLExpr4(1) - inputColor;
+ break;
+ default:
+ SkFAIL("Unexpected Secondary Output");
+ }
+ // Get coeff * coverage into modulate and then write that to the dual source output.
+ this->codeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inputCoverage).c_str());
+}
+
+void GrGLFragmentShaderBuilder::combineColorAndCoverage(const GrGLSLExpr4& inputColor,
+ const GrGLSLExpr4& inputCoverage) {
+ GrGLSLExpr4 fragColor = inputColor * inputCoverage;
+ switch (fProgramBuilder->header().fPrimaryOutputType) {
+ case GrProgramDesc::kModulate_PrimaryOutputType:
+ break;
+ case GrProgramDesc::kCombineWithDst_PrimaryOutputType:
+ {
+ // Tack on "+(1-coverage)dst onto the frag color.
+ GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;
+ GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(this->dstColor());
+ fragColor = fragColor + dstContribution;
+ }
+ break;
+ default:
+ SkFAIL("Unknown Primary Output");
+ }
+
+ // On any post 1.10 GLSL supporting GPU, we declare custom output
+ if (k110_GrGLSLGeneration != fProgramBuilder->gpu()->glslGeneration()) {
+ this->enableCustomOutput();
+ }
+
+ this->codeAppendf("\t%s = %s;\n", this->getPrimaryColorOutputName(), fragColor.c_str());
+}
+
bool GrGLFragmentShaderBuilder::compileAndAttachShaders(GrGLuint programId,
SkTDArray<GrGLuint>* shaderIds) const {
GrGpuGL* gpu = fProgramBuilder->gpu();
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
index 456ec4f27c..03f0e7f7a6 100644
--- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
@@ -100,6 +100,8 @@ private:
void enableSecondaryOutput();
const char* getPrimaryColorOutputName() const;
const char* getSecondaryColorOutputName() const;
+ void enableSecondaryOutput(const GrGLSLExpr4& inputColor, const GrGLSLExpr4& inputCoverage);
+ void combineColorAndCoverage(const GrGLSLExpr4& inputColor, const GrGLSLExpr4& inputCoverage);
bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
void bindFragmentShaderLocations(GrGLuint programID);
diff --git a/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp b/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp
index b90bab2c1d..b251593bfe 100644
--- a/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp
@@ -45,6 +45,5 @@ void GrGLLegacyNvprProgramBuilder::emitTransforms(const GrPendingFragmentStage&
GrGLProgram* GrGLLegacyNvprProgramBuilder::createProgram(GrGLuint programID) {
return SkNEW_ARGS(GrGLLegacyNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
- fXferProcessor, fFragmentProcessors.get(),
- fTexCoordSetCnt));
+ fFragmentProcessors.get(), fTexCoordSetCnt));
}
diff --git a/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp b/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
index ba19275f6f..f5a55866ee 100644
--- a/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
@@ -72,6 +72,5 @@ GrGLProgram* GrGLNvprProgramBuilder::createProgram(GrGLuint programID) {
// building
this->resolveSeparableVaryings(programID);
return SkNEW_ARGS(GrGLNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
- fXferProcessor, fFragmentProcessors.get(),
- fSeparableVaryingInfos));
+ fFragmentProcessors.get(), fSeparableVaryingInfos));
}
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index daa0b6ba06..7929801bbf 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -9,7 +9,6 @@
#include "gl/GrGLProgram.h"
#include "gl/GrGLSLPrettyPrint.h"
#include "gl/GrGLUniformHandle.h"
-#include "../GrGLXferProcessor.h"
#include "../GrGpuGL.h"
#include "GrCoordTransform.h"
#include "GrGLLegacyNvprProgramBuilder.h"
@@ -56,12 +55,20 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState, G
pb->emitAndInstallProcs(&inputColor, &inputCoverageVec4);
+ // write the secondary color output if necessary
+ if (GrProgramDesc::kNone_SecondaryOutputType != header.fSecondaryOutputType) {
+ pb->fFS.enableSecondaryOutput(inputColor, inputCoverageVec4);
+ }
+
+ pb->fFS.combineColorAndCoverage(inputColor, inputCoverageVec4);
+
return pb->finalize();
}
-GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const GrOptDrawState& optState,
- bool hasGeometryProcessor,
- GrGpuGL* gpu) {
+GrGLProgramBuilder*
+GrGLProgramBuilder::CreateProgramBuilder(const GrOptDrawState& optState,
+ bool hasGeometryProcessor,
+ GrGpuGL* gpu) {
const GrProgramDesc& desc = optState.programDesc();
if (GrGLProgramDescBuilder::GetHeader(desc).fUseNvpr) {
SkASSERT(gpu->glCaps().pathRenderingSupport());
@@ -88,7 +95,6 @@ GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu, const GrOptDrawState& optSt
, fOutOfStage(true)
, fStageIndex(-1)
, fGeometryProcessor(NULL)
- , fXferProcessor(NULL)
, fOptState(optState)
, fDesc(optState.programDesc())
, fGpu(gpu)
@@ -254,8 +260,6 @@ void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr
if (fOptState.hasGeometryProcessor()) {
fVS.transformToNormalizedDeviceSpace();
}
-
- this->emitAndInstallXferProc(*fOptState.getXferProcessor(), *inputColor, *inputCoverage);
}
void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset,
@@ -364,55 +368,10 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
verify(gp);
}
-void GrGLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
- const GrGLSLExpr4& colorIn,
- const GrGLSLExpr4& coverageIn) {
- // Program builders have a bit of state we need to clear with each effect
- AutoStageAdvance adv(this);
-
- SkASSERT(!fXferProcessor);
- fXferProcessor = SkNEW(GrGLInstalledXferProc);
-
- fXferProcessor->fGLProc.reset(xp.createGLInstance());
-
- // Enable dual source secondary output if we have one
- if (xp.hasSecondaryOutput()) {
- fFS.enableSecondaryOutput();
- }
-
- // On any post 1.10 GLSL supporting GPU, we declare custom output
- if (k110_GrGLSLGeneration != fFS.fProgramBuilder->gpu()->glslGeneration()) {
- fFS.enableCustomOutput();
- }
-
- SkString openBrace;
- openBrace.printf("{ // Xfer Processor: %s\n", xp.name());
- fFS.codeAppend(openBrace.c_str());
-
- SkSTArray<4, GrGLProcessor::TextureSampler> samplers(xp.numTextures());
- this->emitSamplers(xp, &samplers, fXferProcessor);
-
- GrGLXferProcessor::EmitArgs args(this, xp, colorIn.c_str(), coverageIn.c_str(),
- fFS.getPrimaryColorOutputName(),
- fFS.getSecondaryColorOutputName(), samplers);
- fXferProcessor->fGLProc->emitCode(args);
-
- // We have to check that effects and the code they emit are consistent, ie if an effect
- // asks for dst color, then the emit code needs to follow suit
- verify(xp);
- fFS.codeAppend("}");
-}
-
void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) {
SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition());
}
-void GrGLProgramBuilder::verify(const GrXferProcessor& xp) {
- // TODO: Once will readDst is only xp enable this assert and remove it from the
- // FragmentProcessor verify()
- //SkASSERT(fFS.hasReadDstColor() == xp.willReadDstColor());
-}
-
void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) {
SkASSERT(fFS.hasReadFragmentPosition() == fp.willReadFragmentPosition());
SkASSERT(fFS.hasReadDstColor() == fp.willReadDstColor());
@@ -584,7 +543,7 @@ void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
return SkNEW_ARGS(GrGLProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
- fGeometryProcessor, fXferProcessor, fFragmentProcessors.get()));
+ fGeometryProcessor, fFragmentProcessors.get()));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index 69eed27252..1798e604db 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -14,7 +14,6 @@
#include "../GrGLProgramDataManager.h"
#include "../GrGLUniformHandle.h"
#include "../GrGLGeometryProcessor.h"
-#include "../GrGLXferProcessor.h"
#include "../../GrOptDrawState.h"
#include "../../GrPendingFragmentStage.h"
@@ -112,7 +111,6 @@ private:
friend class GrGLVertexBuilder;
friend class GrGLGeometryBuilder;
- friend class GrGLXferBuilder;
friend class GrGLFragmentShaderBuilder;
};
@@ -172,18 +170,8 @@ public:
*/
};
-/* a specializations for XPs. Lets the user add uniforms and FS code */
-class GrGLXPBuilder : public virtual GrGLUniformBuilder {
-public:
- virtual GrGLFPFragmentBuilder* getFragmentShaderBuilder() = 0;
-
- /*
- * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
- */
-};
struct GrGLInstalledProc;
struct GrGLInstalledGeoProc;
-struct GrGLInstalledXferProc;
struct GrGLInstalledFragProc;
struct GrGLInstalledFragProcs;
@@ -195,8 +183,7 @@ struct GrGLInstalledFragProcs;
* respective builders
*/
class GrGLProgramBuilder : public GrGLGPBuilder,
- public GrGLFPBuilder,
- public GrGLXPBuilder {
+ public GrGLFPBuilder {
public:
/** Generates a shader program.
*
@@ -296,12 +283,8 @@ protected:
void emitAndInstallProc(const GrGeometryProcessor&,
const char* outColor,
const char* outCoverage);
- void emitAndInstallXferProc(const GrXferProcessor&,
- const GrGLSLExpr4& colorIn,
- const GrGLSLExpr4& coverageIn);
void verify(const GrGeometryProcessor&);
- void verify(const GrXferProcessor&);
void verify(const GrFragmentProcessor&);
void emitSamplers(const GrProcessor&,
GrGLProcessor::TextureSamplerArray* outSamplers,
@@ -375,7 +358,6 @@ protected:
int fStageIndex;
GrGLInstalledGeoProc* fGeometryProcessor;
- GrGLInstalledXferProc* fXferProcessor;
SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
const GrOptDrawState& fOptState;
@@ -409,10 +391,6 @@ struct GrGLInstalledGeoProc : public GrGLInstalledProc {
SkAutoTDelete<GrGLGeometryProcessor> fGLProc;
};
-struct GrGLInstalledXferProc : public GrGLInstalledProc {
- SkAutoTDelete<GrGLXferProcessor> fGLProc;
-};
-
struct GrGLInstalledFragProc : public GrGLInstalledProc {
GrGLInstalledFragProc() : fGLProc(NULL) {}
class ShaderVarHandle {
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 953b5e07cb..253e4aeccc 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -121,14 +121,6 @@ static GrRenderTarget* random_render_target(GrContext* context,
return SkRef(texture->asRenderTarget());
}
-static void set_random_xpf(GrContext* context, const GrDrawTargetCaps& caps, GrDrawState* ds,
- SkRandom* random, GrTexture* dummyTextures[]) {
- SkAutoTUnref<const GrXPFactory> xpf(
- GrProcessorTestFactory<GrXPFactory>::CreateStage(random, context, caps, dummyTextures));
- SkASSERT(xpf);
- ds->setXPFactory(xpf.get());
-}
-
static void set_random_gp(GrContext* context,
const GrDrawTargetCaps& caps,
GrDrawState* ds,
@@ -203,6 +195,22 @@ static void set_random_state(GrDrawState* ds, SkRandom* random) {
ds->enableState(state);
}
+// this function will randomly pick non-self referencing blend modes
+static void set_random_blend_func(GrDrawState* ds, SkRandom* random) {
+ GrBlendCoeff src;
+ do {
+ src = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPublicGrBlendCoeff));
+ } while (GrBlendCoeffRefsSrc(src));
+
+ GrBlendCoeff dst;
+ do {
+ dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPublicGrBlendCoeff));
+ } while (GrBlendCoeffRefsDst(dst));
+
+ GrXPFactory* xpFactory = GrPorterDuffXPFactory::Create(src, dst);
+ ds->setXPFactory(xpFactory)->unref();
+}
+
// right now, the only thing we seem to care about in drawState's stencil is 'doesWrite()'
static void set_random_stencil(GrDrawState* ds, SkRandom* random) {
GR_STATIC_CONST_SAME_STENCIL(kDoesWriteStencil,
@@ -302,12 +310,9 @@ bool GrDrawTarget::programUnitTest(int maxStages) {
usePathRendering,
&random,
dummyTextures);
-
- // creates a random xfer processor factory on the draw state
- set_random_xpf(fContext, gpu->glCaps(), &ds, &random, dummyTextures);
-
set_random_hints(&ds, &random);
set_random_state(&ds, &random);
+ set_random_blend_func(&ds, &random);
set_random_stencil(&ds, &random);
GrDeviceCoordTexture dstCopy;