| Index: src/gpu/gl/builders/GrGLProgramBuilder.cpp
|
| diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
|
| index 0c4178197913d1c741a33713bac2f335a4e10130..147723b9d3bb4cf8656ca030493cacd5005d3bb9 100644
|
| --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
|
| +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
|
| @@ -12,8 +12,6 @@
|
| #include "../GrGLXferProcessor.h"
|
| #include "../GrGLGpu.h"
|
| #include "GrCoordTransform.h"
|
| -#include "GrGLLegacyNvprProgramBuilder.h"
|
| -#include "GrGLNvprProgramBuilder.h"
|
| #include "GrGLProgramBuilder.h"
|
| #include "GrTexture.h"
|
| #include "SkRTConf.h"
|
| @@ -22,6 +20,30 @@
|
| #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
|
| #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
|
|
|
| +///////////////////////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +class GrGLNvprProgramBuilder : public GrGLProgramBuilder {
|
| +public:
|
| + GrGLNvprProgramBuilder(GrGLGpu* gpu, const GrOptDrawState& optState)
|
| + : INHERITED(gpu, optState) {}
|
| +
|
| + GrGLProgram* createProgram(GrGLuint programID) SK_OVERRIDE {
|
| + // this is just for nvpr es, which has separable varyings that are plugged in after
|
| + // building
|
| + GrGLPathProcessor* pathProc =
|
| + static_cast<GrGLPathProcessor*>(fGeometryProcessor->fGLProc.get());
|
| + pathProc->resolveSeparableVaryings(fGpu, programID);
|
| + return SkNEW_ARGS(GrGLNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
|
| + fGeometryProcessor,
|
| + fXferProcessor, fFragmentProcessors.get()));
|
| + }
|
| +
|
| +private:
|
| + typedef GrGLProgramBuilder INHERITED;
|
| +};
|
| +
|
| +
|
| +
|
| //////////////////////////////////////////////////////////////////////////////
|
|
|
| const int GrGLProgramBuilder::kVarsPerBlock = 8;
|
| @@ -29,12 +51,11 @@ const int GrGLProgramBuilder::kVarsPerBlock = 8;
|
| GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState, GrGLGpu* gpu) {
|
| // create a builder. This will be handed off to effects so they can use it to add
|
| // uniforms, varyings, textures, etc
|
| - SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(optState,
|
| - optState.hasGeometryProcessor(),
|
| - gpu));
|
| + SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(optState, gpu));
|
|
|
| GrGLProgramBuilder* pb = builder.get();
|
| - const GrGLProgramDescBuilder::GLKeyHeader& header = GrGLProgramDescBuilder::GetHeader(pb->desc());
|
| + const GrGLProgramDescBuilder::GLKeyHeader& header =
|
| + GrGLProgramDescBuilder::GetHeader(pb->desc());
|
|
|
| // emit code to read the dst copy texture, if necessary
|
| if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != header.fDstReadKey &&
|
| @@ -53,18 +74,12 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState, G
|
| }
|
|
|
| GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const GrOptDrawState& optState,
|
| - bool hasGeometryProcessor,
|
| GrGLGpu* gpu) {
|
| const GrProgramDesc& desc = optState.programDesc();
|
| if (GrGLProgramDescBuilder::GetHeader(desc).fUseNvpr) {
|
| SkASSERT(gpu->glCaps().pathRenderingSupport());
|
| - SkASSERT(!hasGeometryProcessor);
|
| - if (gpu->glPathRendering()->texturingMode() ==
|
| - GrGLPathRendering::FixedFunction_TexturingMode) {
|
| - return SkNEW_ARGS(GrGLLegacyNvprProgramBuilder, (gpu, optState));
|
| - } else {
|
| - return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, optState));
|
| - }
|
| + SkASSERT(!optState.hasGeometryProcessor());
|
| + return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, optState));
|
| } else {
|
| return SkNEW_ARGS(GrGLProgramBuilder, (gpu, optState));
|
| }
|
| @@ -177,19 +192,15 @@ const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const {
|
| }
|
|
|
| void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage) {
|
| - if (fOptState.hasGeometryProcessor()) {
|
| - fVS.codeAppend("gl_PointSize = 1.0;");
|
| -
|
| - // Setup position
|
| - // TODO it'd be possible to remove these from the vertexshader builder and have them
|
| - // be outputs from the emit call. We don't do this because emitargs is constant. It would
|
| - // be easy to change this though
|
| - fVS.codeAppendf("vec3 %s;", fVS.glPosition());
|
| - fVS.codeAppendf("vec2 %s;", fVS.positionCoords());
|
| - fVS.codeAppendf("vec2 %s;", fVS.localCoords());
|
| -
|
| - const GrGeometryProcessor& gp = *fOptState.getGeometryProcessor();
|
| - fVS.emitAttributes(gp);
|
| + // First we loop over all of the installed processors and collect coord transforms. These will
|
| + // be sent to the GrGLPrimitiveProcessor in its emitCode function
|
| + SkSTArray<8, GrGLProcessor::TransformedCoordsArray> outCoords;
|
| + for (int i = 0; i < fOptState.numFragmentStages(); i++) {
|
| + const GrFragmentProcessor* processor = fOptState.getFragmentStage(i).processor();
|
| + SkSTArray<2, const GrCoordTransform*, true>& procCoords = fCoordTransforms.push_back();
|
| + for (int t = 0; t < processor->numTransforms(); t++) {
|
| + procCoords.push_back(&processor->coordTransform(t));
|
| + }
|
| }
|
|
|
| const GrPrimitiveProcessor& primProc = *fOptState.getPrimitiveProcessor();
|
| @@ -199,11 +210,6 @@ void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr
|
| int numProcs = fOptState.numFragmentStages();
|
| this->emitAndInstallFragProcs(0, fOptState.numColorStages(), inputColor);
|
| this->emitAndInstallFragProcs(fOptState.numColorStages(), numProcs, inputCoverage);
|
| -
|
| - if (fOptState.hasGeometryProcessor()) {
|
| - fVS.transformToNormalizedDeviceSpace();
|
| - }
|
| -
|
| this->emitAndInstallXferProc(*fOptState.getXferProcessor(), *inputColor, *inputCoverage);
|
| }
|
|
|
| @@ -247,7 +253,7 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrPendingFragmentStage& proc,
|
| openBrace.printf("{ // Stage %d, %s\n", fStageIndex, proc.name());
|
| fFS.codeAppend(openBrace.c_str());
|
|
|
| - this->emitAndInstallProc(proc, output->c_str(), input.isOnes() ? NULL : input.c_str());
|
| + this->emitAndInstallProc(proc, index, output->c_str(), input.isOnes() ? NULL : input.c_str());
|
|
|
| fFS.codeAppend("}");
|
| }
|
| @@ -271,6 +277,7 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrPrimitiveProcessor& proc,
|
| }
|
|
|
| void GrGLProgramBuilder::emitAndInstallProc(const GrPendingFragmentStage& fs,
|
| + int index,
|
| const char* outColor,
|
| const char* inColor) {
|
| GrGLInstalledFragProc* ifp = SkNEW(GrGLInstalledFragProc);
|
| @@ -281,11 +288,7 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrPendingFragmentStage& fs,
|
| SkSTArray<4, GrGLProcessor::TextureSampler> samplers(fp.numTextures());
|
| this->emitSamplers(fp, &samplers, ifp);
|
|
|
| - // Fragment processors can have coord transforms
|
| - SkSTArray<2, GrGLProcessor::TransformedCoords> coords(fp.numTransforms());
|
| - this->emitTransforms(fs, &coords, ifp);
|
| -
|
| - ifp->fGLProc->emitCode(this, fp, outColor, inColor, coords, samplers);
|
| + ifp->fGLProc->emitCode(this, fp, outColor, inColor, fOutCoords[index], samplers);
|
|
|
| // 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
|
| @@ -300,12 +303,13 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrPrimitiveProcessor& gp,
|
| fGeometryProcessor = SkNEW(GrGLInstalledGeoProc);
|
|
|
| const GrBatchTracker& bt = fOptState.getBatchTracker();
|
| - fGeometryProcessor->fGLProc.reset(gp.createGLInstance(bt));
|
| + fGeometryProcessor->fGLProc.reset(gp.createGLInstance(bt, fGpu->glCaps()));
|
|
|
| SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures());
|
| this->emitSamplers(gp, &samplers, fGeometryProcessor);
|
|
|
| - GrGLGeometryProcessor::EmitArgs args(this, gp, bt, outColor, outCoverage, samplers);
|
| + GrGLGeometryProcessor::EmitArgs args(this, gp, bt, outColor, outCoverage, samplers,
|
| + fCoordTransforms, &fOutCoords);
|
| fGeometryProcessor->fGLProc->emitCode(args);
|
|
|
| // We have to check that effects and the code they emit are consistent, ie if an effect
|
| @@ -367,59 +371,10 @@ void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) {
|
| SkASSERT(fFS.hasReadDstColor() == fp.willReadDstColor());
|
| }
|
|
|
| -void GrGLProgramBuilder::emitTransforms(const GrPendingFragmentStage& stage,
|
| - GrGLProcessor::TransformedCoordsArray* outCoords,
|
| - GrGLInstalledFragProc* ifp) {
|
| - const GrFragmentProcessor* processor = stage.processor();
|
| - int numTransforms = processor->numTransforms();
|
| - ifp->fTransforms.push_back_n(numTransforms);
|
| -
|
| - for (int t = 0; t < numTransforms; t++) {
|
| - const char* uniName = "StageMatrix";
|
| - GrSLType varyingType;
|
| -
|
| - GrCoordSet coordType = processor->coordTransform(t).sourceCoords();
|
| - const SkMatrix& localMatrix = fOptState.getPrimitiveProcessor()->localMatrix();
|
| - uint32_t type = processor->coordTransform(t).getMatrix().getType();
|
| - if (kLocal_GrCoordSet == coordType) {
|
| - type |= localMatrix.getType();
|
| - }
|
| - varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType :
|
| - kVec2f_GrSLType;
|
| - GrSLPrecision precision = processor->coordTransform(t).precision();
|
| -
|
| - SkString suffixedUniName;
|
| - if (0 != t) {
|
| - suffixedUniName.append(uniName);
|
| - suffixedUniName.appendf("_%i", t);
|
| - uniName = suffixedUniName.c_str();
|
| - }
|
| - ifp->fTransforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
|
| - kMat33f_GrSLType, precision,
|
| - uniName,
|
| - &uniName).toShaderBuilderIndex();
|
| -
|
| - const char* varyingName = "MatrixCoord";
|
| - SkString suffixedVaryingName;
|
| - if (0 != t) {
|
| - suffixedVaryingName.append(varyingName);
|
| - suffixedVaryingName.appendf("_%i", t);
|
| - varyingName = suffixedVaryingName.c_str();
|
| - }
|
| -
|
| - GrGLVertToFrag v(varyingType);
|
| - this->addVarying(varyingName, &v, precision);
|
| - fCoordVaryings.push_back(TransformVarying(v, uniName, coordType));
|
| -
|
| - SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
|
| - SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
|
| - (SkString(v.fsIn()), varyingType));
|
| - }
|
| -}
|
| -
|
| +template <class Proc>
|
| void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor,
|
| GrGLProcessor::TextureSamplerArray* outSamplers,
|
| - GrGLInstalledProc* ip) {
|
| + GrGLInstalledProc<Proc>* ip) {
|
| int numTextures = processor.numTextures();
|
| ip->fSamplers.push_back_n(numTextures);
|
| SkString name;
|
|
|