From 294738268d3a9317282224f03063eb38ad19717c Mon Sep 17 00:00:00 2001 From: joshualitt Date: Wed, 10 Dec 2014 15:03:00 -0800 Subject: Revert of Create xfer processor backend. (patchset #6 id:100001 of https://codereview.chromium.org/764643004/) Reason for revert: CL breaks windows DM Original issue's description: > 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: > > Committed: https://skia.googlesource.com/skia/+/4dffc940c430eec66d4707490eace19c9b3f7904 TBR=bsalomon@google.com,joshualitt@chromium.org,egdaniel@google.com NOTREECHECKS=true NOTRY=true BUG=skia: Review URL: https://codereview.chromium.org/789343002 --- src/gpu/GrGeometryProcessor.h | 5 +- src/gpu/GrOptDrawState.cpp | 43 ++++++- src/gpu/GrOptDrawState.h | 3 +- src/gpu/GrProcessor.cpp | 12 +- src/gpu/GrProgramDesc.h | 41 ++++++- src/gpu/effects/GrPorterDuffXferProcessor.cpp | 123 +++------------------ src/gpu/gl/GrGLProcessor.h | 10 ++ src/gpu/gl/GrGLProgram.cpp | 23 +--- src/gpu/gl/GrGLProgram.h | 7 +- src/gpu/gl/GrGLProgramDesc.cpp | 15 +-- src/gpu/gl/GrGLXferProcessor.h | 61 ---------- src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp | 49 ++++++++ src/gpu/gl/builders/GrGLFragmentShaderBuilder.h | 2 + .../gl/builders/GrGLLegacyNvprProgramBuilder.cpp | 3 +- src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp | 3 +- src/gpu/gl/builders/GrGLProgramBuilder.cpp | 65 ++--------- src/gpu/gl/builders/GrGLProgramBuilder.h | 24 +--- 17 files changed, 184 insertions(+), 305 deletions(-) delete mode 100644 src/gpu/gl/GrGLXferProcessor.h (limited to 'src') 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::GetFactories() { } template<> -SkTArray*, true>* -GrProcessorTestFactory::GetFactories() { - static SkTArray*, true> gFactories; +SkTArray*, true>* +GrProcessorTestFactory::GetFactories() { + static SkTArray*, true> gFactories; return &gFactories; } @@ -52,7 +52,7 @@ GrProcessorTestFactory::GetFactories() { */ static const int kFPFactoryCount = 37; static const int kGPFactoryCount = 14; -static const int kXPFactoryCount = 1; +static const int kXPFactoryCount = 0; template<> void GrProcessorTestFactory::VerifyFactoryCount() { @@ -69,9 +69,9 @@ void GrProcessorTestFactory::VerifyFactoryCount() { } template<> -void GrProcessorTestFactory::VerifyFactoryCount() { +void GrProcessorTestFactory::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(); - 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(); - 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(); } @@ -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 fGeometryProcessor; - SkAutoTDelete fXferProcessor; SkAutoTUnref 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* 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* 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& 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 fFragmentProcessors; const GrOptDrawState& fOptState; @@ -409,10 +391,6 @@ struct GrGLInstalledGeoProc : public GrGLInstalledProc { SkAutoTDelete fGLProc; }; -struct GrGLInstalledXferProc : public GrGLInstalledProc { - SkAutoTDelete fGLProc; -}; - struct GrGLInstalledFragProc : public GrGLInstalledProc { GrGLInstalledFragProc() : fGLProc(NULL) {} class ShaderVarHandle { -- cgit v1.2.3