diff options
author | 2014-12-10 07:43:49 -0800 | |
---|---|---|
committer | 2014-12-10 07:43:50 -0800 | |
commit | 4dffc940c430eec66d4707490eace19c9b3f7904 (patch) | |
tree | cce5e8c525a5acec67c4398c95c165223320d679 /src/gpu/gl | |
parent | 28828d00b20d90b6caf91e4b0b31e80acadf2d57 (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.h | 10 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 23 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 7 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDesc.cpp | 15 | ||||
-rw-r--r-- | src/gpu/gl/GrGLXferProcessor.h | 61 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp | 49 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLFragmentShaderBuilder.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp | 3 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp | 3 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.cpp | 65 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.h | 24 |
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 { |