aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
authorGravatar egdaniel <egdaniel@google.com>2014-12-10 07:43:49 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2014-12-10 07:43:50 -0800
commit4dffc940c430eec66d4707490eace19c9b3f7904 (patch)
treecce5e8c525a5acec67c4398c95c165223320d679 /src/gpu/gl
parent28828d00b20d90b6caf91e4b0b31e80acadf2d57 (diff)
Create xfer processor backend.
This includes: -Having an actual XP stage at the end of the gl pipeline. -All Blending work is handled by XP until actually setting GL blend states -GLPrograms test to test XP BUG=skia: Review URL: https://codereview.chromium.org/764643004
Diffstat (limited to 'src/gpu/gl')
-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
11 files changed, 177 insertions, 85 deletions
diff --git a/src/gpu/gl/GrGLProcessor.h b/src/gpu/gl/GrGLProcessor.h
index 6dccd33bac..a4fad753ec 100644
--- a/src/gpu/gl/GrGLProcessor.h
+++ b/src/gpu/gl/GrGLProcessor.h
@@ -117,14 +117,4 @@ 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 29c44ac56c..da687c1eb6 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -12,11 +12,13 @@
#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)
@@ -57,6 +59,7 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu,
GrGLuint programID,
const UniformInfoArray& uniforms,
GrGLInstalledGeoProc* geometryProcessor,
+ GrGLInstalledXferProc* xferProcessor,
GrGLInstalledFragProcs* fragmentProcessors)
: fColor(GrColor_ILLEGAL)
, fCoverage(0)
@@ -64,6 +67,7 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu,
, fBuiltinUniformHandles(builtinUniforms)
, fProgramID(programID)
, fGeometryProcessor(geometryProcessor)
+ , fXferProcessor(xferProcessor)
, fFragmentProcessors(SkRef(fragmentProcessors))
, fDesc(desc)
, fGpu(gpu)
@@ -91,6 +95,9 @@ 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);
@@ -162,6 +169,11 @@ 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
@@ -284,8 +296,10 @@ GrGLNvprProgramBase::GrGLNvprProgramBase(GrGpuGL* gpu,
const BuiltinUniformHandles& builtinUniforms,
GrGLuint programID,
const UniformInfoArray& uniforms,
+ GrGLInstalledXferProc* xferProcessor,
GrGLInstalledFragProcs* fragmentProcessors)
- : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, NULL, fragmentProcessors) {
+ : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, NULL,
+ xferProcessor, fragmentProcessors) {
}
void GrGLNvprProgramBase::onSetMatrixAndRenderTargetHeight(const GrOptDrawState& optState) {
@@ -303,9 +317,11 @@ 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, fragmentProcessors) {
+ : INHERITED(gpu, desc, builtinUniforms, programID, uniforms,
+ xferProcessor, fragmentProcessors) {
int count = separableVaryings.count();
fVaryings.push_back_n(count);
for (int i = 0; i < count; i++) {
@@ -353,9 +369,10 @@ GrGLLegacyNvprProgram::GrGLLegacyNvprProgram(GrGpuGL* gpu,
const BuiltinUniformHandles& builtinUniforms,
GrGLuint programID,
const UniformInfoArray& uniforms,
+ GrGLInstalledXferProc* xp,
GrGLInstalledFragProcs* fps,
int texCoordSetCnt)
- : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, fps)
+ : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, xp, fps)
, fTexCoordSetCnt(texCoordSetCnt) {
}
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 36bf860233..ea8be85251 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -141,6 +141,7 @@ protected:
GrGLuint programID,
const UniformInfoArray&,
GrGLInstalledGeoProc* geometryProcessor,
+ GrGLInstalledXferProc* xferProcessor,
GrGLInstalledFragProcs* fragmentProcessors);
// Sets the texture units for samplers.
@@ -180,6 +181,7 @@ protected:
// the installed effects
SkAutoTDelete<GrGLInstalledGeoProc> fGeometryProcessor;
+ SkAutoTDelete<GrGLInstalledXferProc> fXferProcessor;
SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
GrProgramDesc fDesc;
@@ -205,6 +207,7 @@ protected:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
+ GrGLInstalledXferProc* xferProcessor,
GrGLInstalledFragProcs* fragmentProcessors);
virtual void onSetMatrixAndRenderTargetHeight(const GrOptDrawState&);
@@ -223,6 +226,7 @@ private:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
+ GrGLInstalledXferProc* xferProcessor,
GrGLInstalledFragProcs* fragmentProcessors,
const SeparableVaryingInfoArray& separableVaryings);
virtual void didSetData(GrGpu::DrawType) SK_OVERRIDE;
@@ -252,7 +256,8 @@ private:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
- GrGLInstalledFragProcs* fragmentProcessors,
+ GrGLInstalledXferProc* xp,
+ GrGLInstalledFragProcs* fps,
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 068386c3aa..2476c5532c 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -189,13 +189,21 @@ bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState,
const GrFragmentProcessor& fp = *fps.getProcessor();
GrProcessorKeyBuilder b(&desc->fKey);
fp.getGLProcessorKey(gpu->glCaps(), &b);
- if (!get_meta_key(*fps.getProcessor(), gpu->glCaps(),
- gen_transform_key(fps, requiresLocalCoordAttrib), 0, &b)) {
+ if (!get_meta_key(fp, 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.
@@ -260,9 +268,6 @@ 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
new file mode 100644
index 0000000000..5c92559031
--- /dev/null
+++ b/src/gpu/gl/GrGLXferProcessor.h
@@ -0,0 +1,61 @@
+/*
+ * 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 49be12d8ba..b6daca7978 100644
--- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
@@ -256,55 +256,6 @@ 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 03f0e7f7a6..456ec4f27c 100644
--- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
@@ -100,8 +100,6 @@ 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 b251593bfe..b90bab2c1d 100644
--- a/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp
@@ -45,5 +45,6 @@ void GrGLLegacyNvprProgramBuilder::emitTransforms(const GrPendingFragmentStage&
GrGLProgram* GrGLLegacyNvprProgramBuilder::createProgram(GrGLuint programID) {
return SkNEW_ARGS(GrGLLegacyNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
- fFragmentProcessors.get(), fTexCoordSetCnt));
+ fXferProcessor, fFragmentProcessors.get(),
+ fTexCoordSetCnt));
}
diff --git a/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp b/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
index f5a55866ee..ba19275f6f 100644
--- a/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
@@ -72,5 +72,6 @@ GrGLProgram* GrGLNvprProgramBuilder::createProgram(GrGLuint programID) {
// building
this->resolveSeparableVaryings(programID);
return SkNEW_ARGS(GrGLNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
- fFragmentProcessors.get(), fSeparableVaryingInfos));
+ fXferProcessor, fFragmentProcessors.get(),
+ fSeparableVaryingInfos));
}
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index ab77e05938..8ea03fbba7 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -9,6 +9,7 @@
#include "gl/GrGLProgram.h"
#include "gl/GrGLSLPrettyPrint.h"
#include "gl/GrGLUniformHandle.h"
+#include "../GrGLXferProcessor.h"
#include "../GrGpuGL.h"
#include "GrCoordTransform.h"
#include "GrGLLegacyNvprProgramBuilder.h"
@@ -55,20 +56,12 @@ 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());
@@ -95,6 +88,7 @@ GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu, const GrOptDrawState& optSt
, fOutOfStage(true)
, fStageIndex(-1)
, fGeometryProcessor(NULL)
+ , fXferProcessor(NULL)
, fOptState(optState)
, fDesc(optState.programDesc())
, fGpu(gpu)
@@ -256,6 +250,8 @@ void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr
if (fOptState.hasGeometryProcessor()) {
fVS.transformToNormalizedDeviceSpace();
}
+
+ this->emitAndInstallXferProc(*fOptState.getXferProcessor(), *inputColor, *inputCoverage);
}
void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset,
@@ -364,10 +360,55 @@ 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());
@@ -539,7 +580,7 @@ void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
return SkNEW_ARGS(GrGLProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
- fGeometryProcessor, fFragmentProcessors.get()));
+ fGeometryProcessor, fXferProcessor, fFragmentProcessors.get()));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index 1798e604db..69eed27252 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -14,6 +14,7 @@
#include "../GrGLProgramDataManager.h"
#include "../GrGLUniformHandle.h"
#include "../GrGLGeometryProcessor.h"
+#include "../GrGLXferProcessor.h"
#include "../../GrOptDrawState.h"
#include "../../GrPendingFragmentStage.h"
@@ -111,6 +112,7 @@ private:
friend class GrGLVertexBuilder;
friend class GrGLGeometryBuilder;
+ friend class GrGLXferBuilder;
friend class GrGLFragmentShaderBuilder;
};
@@ -170,8 +172,18 @@ 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;
@@ -183,7 +195,8 @@ struct GrGLInstalledFragProcs;
* respective builders
*/
class GrGLProgramBuilder : public GrGLGPBuilder,
- public GrGLFPBuilder {
+ public GrGLFPBuilder,
+ public GrGLXPBuilder {
public:
/** Generates a shader program.
*
@@ -283,8 +296,12 @@ 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,
@@ -358,6 +375,7 @@ protected:
int fStageIndex;
GrGLInstalledGeoProc* fGeometryProcessor;
+ GrGLInstalledXferProc* fXferProcessor;
SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
const GrOptDrawState& fOptState;
@@ -391,6 +409,10 @@ struct GrGLInstalledGeoProc : public GrGLInstalledProc {
SkAutoTDelete<GrGLGeometryProcessor> fGLProc;
};
+struct GrGLInstalledXferProc : public GrGLInstalledProc {
+ SkAutoTDelete<GrGLXferProcessor> fGLProc;
+};
+
struct GrGLInstalledFragProc : public GrGLInstalledProc {
GrGLInstalledFragProc() : fGLProc(NULL) {}
class ShaderVarHandle {