diff options
32 files changed, 916 insertions, 928 deletions
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index 5be7f4bb3d..90896b32c7 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -272,10 +272,6 @@ '<(skia_src_path)/gpu/gl/GrGLVertexBuffer.h', # Files for building GLSL shaders - '<(skia_src_path)/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp', - '<(skia_src_path)/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.h', - '<(skia_src_path)/gpu/gl/builders/GrGLNvprProgramBuilder.cpp', - '<(skia_src_path)/gpu/gl/builders/GrGLNvprProgramBuilder.h', '<(skia_src_path)/gpu/gl/builders/GrGLProgramBuilder.cpp', '<(skia_src_path)/gpu/gl/builders/GrGLProgramBuilder.h', '<(skia_src_path)/gpu/gl/builders/GrGLShaderBuilder.cpp', diff --git a/include/gpu/GrFragmentProcessor.h b/include/gpu/GrFragmentProcessor.h index fe6e6faf14..341b3fb338 100644 --- a/include/gpu/GrFragmentProcessor.h +++ b/include/gpu/GrFragmentProcessor.h @@ -47,6 +47,10 @@ public: numTransforms(). */ const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; } + const SkTArray<const GrCoordTransform*, true>& coordTransforms() const { + return fCoordTransforms; + } + /** Will this prceossor read the destination pixel value? */ bool willReadDstColor() const { return fWillReadDstColor; } diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index 784f685f64..0690175151 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -535,11 +535,14 @@ public: const GrBatchTracker&) : fColor(GrColor_ILLEGAL) {} - void emitCode(const EmitArgs& args) SK_OVERRIDE { + void onEmitCode(EmitArgs& args) SK_OVERRIDE { const QuadEdgeEffect& qe = args.fGP.cast<QuadEdgeEffect>(); GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); + // emit attributes + vsBuilder->emitAttributes(qe); + GrGLVertToFrag v(kVec4f_GrSLType); args.fPB->addVarying("QuadEdge", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), qe.inQuadEdge()->fName); @@ -550,16 +553,16 @@ public: this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, &fColorUniform); - // setup coord outputs - vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), qe.inPosition()->fName); - vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), qe.inPosition()->fName); - // setup uniform viewMatrix this->addUniformViewMatrix(pb); - // setup position varying - vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), - this->uViewM(), qe.inPosition()->fName); + // Setup position + vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uViewM(), + qe.inPosition()->fName); + + // emit transforms + this->emitTransforms(args.fPB, this->position(), qe.inPosition()->fName, + qe.localMatrix(), args.fTransformsIn, args.fTransformsOut); GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); @@ -622,7 +625,8 @@ public: GLProcessor::GenKey(*this, bt, caps, b); } - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE { + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const SK_OVERRIDE { return SkNEW_ARGS(GLProcessor, (*this, bt)); } diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp index 49c663dcec..a6eaa6d14d 100644 --- a/src/gpu/GrDefaultGeoProcFactory.cpp +++ b/src/gpu/GrDefaultGeoProcFactory.cpp @@ -83,33 +83,37 @@ public: GLProcessor(const GrGeometryProcessor& gp, const GrBatchTracker&) : fColor(GrColor_ILLEGAL), fCoverage(0xff) {} - void emitCode(const EmitArgs& args) SK_OVERRIDE { + void onEmitCode(EmitArgs& args) SK_OVERRIDE { const DefaultGeoProc& gp = args.fGP.cast<DefaultGeoProc>(); GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vs = pb->getVertexShaderBuilder(); GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder(); const BatchTracker& local = args.fBT.cast<BatchTracker>(); - vs->codeAppendf("%s = %s;", vs->positionCoords(), gp.inPosition()->fName); + // emit attributes + vs->emitAttributes(gp); // Setup pass through color this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, gp.inColor(), &fColorUniform); - // Setup local coords if needed - if (gp.inLocalCoords()) { - vs->codeAppendf("%s = %s;", vs->localCoords(), gp.inLocalCoords()->fName); - } else { - vs->codeAppendf("%s = %s;", vs->localCoords(), gp.inPosition()->fName); - } - // setup uniform viewMatrix this->addUniformViewMatrix(pb); - // setup position varying - vs->codeAppendf("%s = %s * vec3(%s, 1);", vs->glPosition(), this->uViewM(), + // Setup position + vs->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uViewM(), gp.inPosition()->fName); + if (gp.inLocalCoords()) { + // emit transforms with explicit local coords + this->emitTransforms(pb, this->position(), gp.inLocalCoords()->fName, + gp.localMatrix(), args.fTransformsIn, args.fTransformsOut); + } else { + // emit transforms with position + this->emitTransforms(pb, this->position(), gp.inPosition()->fName, + gp.localMatrix(), args.fTransformsIn, args.fTransformsOut); + } + // Setup coverage as pass through if (kUniform_GrGPInput == local.fInputCoverageType) { const char* fragCoverage; @@ -174,7 +178,8 @@ public: GLProcessor::GenKey(*this, bt, caps, b); } - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE { + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const SK_OVERRIDE { return SkNEW_ARGS(GLProcessor, (*this, bt)); } diff --git a/src/gpu/GrGeometryProcessor.cpp b/src/gpu/GrGeometryProcessor.cpp index 6bd6b2b54b..e8ffc7b3a7 100644 --- a/src/gpu/GrGeometryProcessor.cpp +++ b/src/gpu/GrGeometryProcessor.cpp @@ -7,8 +7,68 @@ #include "GrGeometryProcessor.h" -#include "gl/GrGLGeometryProcessor.h" +#include "GrCoordTransform.h" #include "GrInvariantOutput.h" +#include "gl/GrGLGeometryProcessor.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * The key for an individual coord transform is made up of a matrix type, a precision, and a bit + * that indicates the source of the input coords. + */ +enum { + kMatrixTypeKeyBits = 1, + kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1, + + kPrecisionBits = 2, + kPrecisionShift = kMatrixTypeKeyBits, + + kPositionCoords_Flag = (1 << (kPrecisionShift + kPrecisionBits)), + kDeviceCoords_Flag = kPositionCoords_Flag + kPositionCoords_Flag, + + kTransformKeyBits = kMatrixTypeKeyBits + kPrecisionBits + 2, +}; + +GR_STATIC_ASSERT(kHigh_GrSLPrecision < (1 << kPrecisionBits)); + +/** + * We specialize the vertex code for each of these matrix types. + */ +enum MatrixType { + kNoPersp_MatrixType = 0, + kGeneral_MatrixType = 1, +}; + +uint32_t +GrPrimitiveProcessor::getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords) const { + uint32_t totalKey = 0; + for (int t = 0; t < coords.count(); ++t) { + uint32_t key = 0; + const GrCoordTransform* coordTransform = coords[t]; + if (coordTransform->getMatrix().hasPerspective()) { + key |= kGeneral_MatrixType; + } else { + key |= kNoPersp_MatrixType; + } + + if (kLocal_GrCoordSet == coordTransform->sourceCoords() && + !this->hasExplicitLocalCoords()) { + key |= kPositionCoords_Flag; + } else if (kDevice_GrCoordSet == coordTransform->sourceCoords()) { + key |= kDeviceCoords_Flag; + } + + GR_STATIC_ASSERT(kGrSLPrecisionCount <= (1 << kPrecisionBits)); + key |= (coordTransform->precision() << kPrecisionShift); + + key <<= kTransformKeyBits * t; + + SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to overlap + totalKey |= key; + } + return totalKey; +} /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -33,11 +93,34 @@ void GrGeometryProcessor::getInvariantOutputCoverage(GrInitInvariantOutput* out) #include "gl/builders/GrGLProgramBuilder.h" -void GrGLGeometryProcessor::setupColorPassThrough(GrGLGPBuilder* pb, - GrGPInput inputType, - const char* outputName, - const GrGeometryProcessor::GrAttribute* colorAttr, - UniformHandle* colorUniform) { +SkMatrix GrGLPrimitiveProcessor::GetTransformMatrix(const SkMatrix& localMatrix, + const GrCoordTransform& coordTransform) { + SkMatrix combined; + // We only apply the localmatrix to localcoords + if (kLocal_GrCoordSet == coordTransform.sourceCoords()) { + combined.setConcat(coordTransform.getMatrix(), localMatrix); + } else { + combined = coordTransform.getMatrix(); + } + if (coordTransform.reverseY()) { + // combined.postScale(1,-1); + // combined.postTranslate(0,1); + combined.set(SkMatrix::kMSkewY, + combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]); + combined.set(SkMatrix::kMScaleY, + combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]); + combined.set(SkMatrix::kMTransY, + combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]); + } + return combined; +} + +void +GrGLPrimitiveProcessor::setupColorPassThrough(GrGLGPBuilder* pb, + GrGPInput inputType, + const char* outputName, + const GrGeometryProcessor::GrAttribute* colorAttr, + UniformHandle* colorUniform) { GrGLGPFragmentBuilder* fs = pb->getFragmentShaderBuilder(); if (kUniform_GrGPInput == inputType) { SkASSERT(colorUniform); @@ -56,15 +139,15 @@ void GrGLGeometryProcessor::setupColorPassThrough(GrGLGPBuilder* pb, } } -void GrGLGeometryProcessor::addUniformViewMatrix(GrGLGPBuilder* pb) { +void GrGLPrimitiveProcessor::addUniformViewMatrix(GrGLGPBuilder* pb) { fViewMatrixUniform = pb->addUniform(GrGLProgramBuilder::kVertex_Visibility, kMat33f_GrSLType, kDefault_GrSLPrecision, "uViewM", &fViewMatrixName); } -void GrGLGeometryProcessor::setUniformViewMatrix(const GrGLProgramDataManager& pdman, - const SkMatrix& viewMatrix) { +void GrGLPrimitiveProcessor::setUniformViewMatrix(const GrGLProgramDataManager& pdman, + const SkMatrix& viewMatrix) { if (!fViewMatrix.cheapEqualTo(viewMatrix)) { SkASSERT(fViewMatrixUniform.isValid()); fViewMatrix = viewMatrix; @@ -77,6 +160,98 @@ void GrGLGeometryProcessor::setUniformViewMatrix(const GrGLProgramDataManager& p /////////////////////////////////////////////////////////////////////////////////////////////////// + +void GrGLGeometryProcessor::emitCode(EmitArgs& args) { + GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); + vsBuilder->codeAppendf("vec3 %s;", this->position()); + this->onEmitCode(args); + vsBuilder->transformToNormalizedDeviceSpace(this->position()); +} + +void GrGLGeometryProcessor::emitTransforms(GrGLGPBuilder* pb, + const char* position, + const char* localCoords, + const SkMatrix& localMatrix, + const TransformsIn& tin, + TransformsOut* tout) { + GrGLVertexBuilder* vb = pb->getVertexShaderBuilder(); + tout->push_back_n(tin.count()); + fInstalledTransforms.push_back_n(tin.count()); + for (int i = 0; i < tin.count(); i++) { + const ProcCoords& coordTransforms = tin[i]; + fInstalledTransforms[i].push_back_n(coordTransforms.count()); + for (int t = 0; t < coordTransforms.count(); t++) { + SkString strUniName("StageMatrix"); + strUniName.appendf("_%i_%i", i, t); + GrSLType varyingType; + + GrCoordSet coordType = coordTransforms[t]->sourceCoords(); + uint32_t type = coordTransforms[t]->getMatrix().getType(); + if (kLocal_GrCoordSet == coordType) { + type |= localMatrix.getType(); + } + varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType : + kVec2f_GrSLType; + GrSLPrecision precision = coordTransforms[t]->precision(); + + const char* uniName; + fInstalledTransforms[i][t].fHandle = + pb->addUniform(GrGLProgramBuilder::kVertex_Visibility, + kMat33f_GrSLType, precision, + strUniName.c_str(), + &uniName).toShaderBuilderIndex(); + + SkString strVaryingName("MatrixCoord"); + strVaryingName.appendf("_%i_%i", i, t); + + GrGLVertToFrag v(varyingType); + pb->addVarying(strVaryingName.c_str(), &v, precision); + + SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType); + SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLProcessor::TransformedCoords, + (SkString(v.fsIn()), varyingType)); + + // varying = matrix * coords (logically) + if (kDevice_GrCoordSet == coordType) { + if (kVec2f_GrSLType == varyingType) { + vb->codeAppendf("%s = (%s * %s).xy;", v.vsOut(), uniName, position); + } else { + vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, position); + } + } else { + if (kVec2f_GrSLType == varyingType) { + vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.vsOut(), uniName, localCoords); + } else { + vb->codeAppendf("%s = %s * vec3(%s, 1);", v.vsOut(), uniName, localCoords); + } + } + } + } +} + + +void +GrGLGeometryProcessor::setTransformData(const GrPrimitiveProcessor* primProc, + const GrGLProgramDataManager& pdman, + int index, + const SkTArray<const GrCoordTransform*, true>& transforms) { + SkSTArray<2, Transform, true>& procTransforms = fInstalledTransforms[index]; + int numTransforms = transforms.count(); + for (int t = 0; t < numTransforms; ++t) { + SkASSERT(procTransforms[t].fHandle.isValid()); + const SkMatrix& transform = GetTransformMatrix(primProc->localMatrix(), *transforms[t]); + if (!procTransforms[t].fCurrentValue.cheapEqualTo(transform)) { + pdman.setSkMatrix(procTransforms[t].fHandle.convertToUniformHandle(), transform); + procTransforms[t].fCurrentValue = transform; + } + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "gl/GrGLGpu.h" +#include "gl/GrGLPathRendering.h" + struct PathBatchTracker { GrGPInput fInputColorType; GrGPInput fInputCoverageType; @@ -84,58 +259,214 @@ struct PathBatchTracker { bool fUsesLocalCoords; }; -class GrGLPathProcessor : public GrGLGeometryProcessor { +GrGLPathProcessor::GrGLPathProcessor(const GrPathProcessor&, const GrBatchTracker&) + : fColor(GrColor_ILLEGAL) {} + +void GrGLPathProcessor::emitCode(EmitArgs& args) { + GrGLGPBuilder* pb = args.fPB; + GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder(); + const PathBatchTracker& local = args.fBT.cast<PathBatchTracker>(); + + // emit transforms + this->emitTransforms(args.fPB, args.fTransformsIn, args.fTransformsOut); + + // Setup uniform color + if (kUniform_GrGPInput == local.fInputColorType) { + const char* stagedLocalVarName; + fColorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, + kVec4f_GrSLType, + kDefault_GrSLPrecision, + "Color", + &stagedLocalVarName); + fs->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName); + } + + // setup constant solid coverage + if (kAllOnes_GrGPInput == local.fInputCoverageType) { + fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage); + } +} + +void GrGLPathProcessor::GenKey(const GrPathProcessor&, + const GrBatchTracker& bt, + const GrGLCaps&, + GrProcessorKeyBuilder* b) { + const PathBatchTracker& local = bt.cast<PathBatchTracker>(); + b->add32(local.fInputColorType | local.fInputCoverageType << 16); +} + +void GrGLPathProcessor::setData(const GrGLProgramDataManager& pdman, + const GrPrimitiveProcessor& primProc, + const GrBatchTracker& bt) { + const PathBatchTracker& local = bt.cast<PathBatchTracker>(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { + GrGLfloat c[4]; + GrColorToRGBAFloat(local.fColor, c); + pdman.set4fv(fColorUniform, 1, c); + fColor = local.fColor; + } +} + +class GrGLLegacyPathProcessor : public GrGLPathProcessor { public: - GrGLPathProcessor(const GrPathProcessor&, const GrBatchTracker&) - : fColor(GrColor_ILLEGAL) {} - - void emitCode(const EmitArgs& args) SK_OVERRIDE { - GrGLGPBuilder* pb = args.fPB; - GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder(); - const PathBatchTracker& local = args.fBT.cast<PathBatchTracker>(); - - // Setup uniform color - if (kUniform_GrGPInput == local.fInputColorType) { - const char* stagedLocalVarName; - fColorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, - kVec4f_GrSLType, - kDefault_GrSLPrecision, - "Color", - &stagedLocalVarName); - fs->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName); + GrGLLegacyPathProcessor(const GrPathProcessor& pathProc, const GrBatchTracker& bt, + int maxTexCoords) + : INHERITED(pathProc, bt) + , fMaxTexCoords(maxTexCoords) + , fTexCoordSetCnt(0) {} + + int addTexCoordSets(int count) { + int firstFreeCoordSet = fTexCoordSetCnt; + fTexCoordSetCnt += count; + SkASSERT(fMaxTexCoords >= fTexCoordSetCnt); + return firstFreeCoordSet; + } + + void emitTransforms(GrGLGPBuilder*, const TransformsIn& tin, TransformsOut* tout) SK_OVERRIDE { + tout->push_back_n(tin.count()); + fInstalledTransforms.push_back_n(tin.count()); + for (int i = 0; i < tin.count(); i++) { + const ProcCoords& coordTransforms = tin[i]; + int texCoordIndex = this->addTexCoordSets(coordTransforms.count()); + + // Use the first uniform location as the texcoord index. + fInstalledTransforms[i].push_back_n(1); + fInstalledTransforms[i][0].fHandle = ShaderVarHandle(texCoordIndex); + + SkString name; + for (int t = 0; t < coordTransforms.count(); ++t) { + GrSLType type = coordTransforms[t]->getMatrix().hasPerspective() ? kVec3f_GrSLType : + kVec2f_GrSLType; + + name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCoordIndex++); + SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLProcessor::TransformedCoords, (name, type)); + } + } + } + + void setTransformData(const GrPrimitiveProcessor* primProc, + int index, + const SkTArray<const GrCoordTransform*, true>& transforms, + GrGLPathRendering* glpr, + GrGLuint) SK_OVERRIDE { + // We've hidden the texcoord index in the first entry of the transforms array for each + // effect + int texCoordIndex = fInstalledTransforms[index][0].fHandle.handle(); + for (int t = 0; t < transforms.count(); ++t) { + const SkMatrix& transform = GetTransformMatrix(primProc->localMatrix(), *transforms[t]); + GrGLPathRendering::PathTexGenComponents components = + GrGLPathRendering::kST_PathTexGenComponents; + if (transform.hasPerspective()) { + components = GrGLPathRendering::kSTR_PathTexGenComponents; + } + glpr->enablePathTexGen(texCoordIndex++, components, transform); } + } + + void didSetData(GrGLPathRendering* glpr) SK_OVERRIDE { + glpr->flushPathTexGenSettings(fTexCoordSetCnt); + } + +private: + int fMaxTexCoords; + int fTexCoordSetCnt; + + typedef GrGLPathProcessor INHERITED; +}; - // setup constant solid coverage - if (kAllOnes_GrGPInput == local.fInputCoverageType) { - fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage); +class GrGLNormalPathProcessor : public GrGLPathProcessor { +public: + GrGLNormalPathProcessor(const GrPathProcessor& pathProc, const GrBatchTracker& bt) + : INHERITED(pathProc, bt) {} + + void emitTransforms(GrGLGPBuilder* pb, const TransformsIn& tin, + TransformsOut* tout) SK_OVERRIDE { + tout->push_back_n(tin.count()); + fInstalledTransforms.push_back_n(tin.count()); + for (int i = 0; i < tin.count(); i++) { + const ProcCoords& coordTransforms = tin[i]; + fInstalledTransforms[i].push_back_n(coordTransforms.count()); + for (int t = 0; t < coordTransforms.count(); t++) { + GrSLType varyingType = + coordTransforms[t]->getMatrix().hasPerspective() ? kVec3f_GrSLType : + kVec2f_GrSLType; + + const char* varyingName = "MatrixCoord"; + SkString suffixedVaryingName; + if (0 != t) { + suffixedVaryingName.append(varyingName); + suffixedVaryingName.appendf("_%i", t); + varyingName = suffixedVaryingName.c_str(); + } + GrGLVertToFrag v(varyingType); + pb->addVarying(varyingName, &v); + SeparableVaryingInfo& varyingInfo = fSeparableVaryingInfos.push_back(); + varyingInfo.fVariable = pb->getFragmentShaderBuilder()->fInputs.back(); + varyingInfo.fLocation = fSeparableVaryingInfos.count() - 1; + varyingInfo.fType = varyingType; + fInstalledTransforms[i][t].fHandle = ShaderVarHandle(varyingInfo.fLocation); + fInstalledTransforms[i][t].fType = varyingType; + + SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLProcessor::TransformedCoords, + (SkString(v.fsIn()), varyingType)); + } } } - static inline void GenKey(const GrPathProcessor&, - const GrBatchTracker& bt, - const GrGLCaps&, - GrProcessorKeyBuilder* b) { - const PathBatchTracker& local = bt.cast<PathBatchTracker>(); - b->add32(local.fInputColorType | local.fInputCoverageType << 16); + void resolveSeparableVaryings(GrGLGpu* gpu, GrGLuint programId) { + int count = fSeparableVaryingInfos.count(); + for (int i = 0; i < count; ++i) { + GrGLint location; + GR_GL_CALL_RET(gpu->glInterface(), + location, + GetProgramResourceLocation(programId, + GR_GL_FRAGMENT_INPUT, + fSeparableVaryingInfos[i].fVariable.c_str())); + fSeparableVaryingInfos[i].fLocation = location; + } } - void setData(const GrGLProgramDataManager& pdman, - const GrPrimitiveProcessor& primProc, - const GrBatchTracker& bt) SK_OVERRIDE { - const PathBatchTracker& local = bt.cast<PathBatchTracker>(); - if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { - GrGLfloat c[4]; - GrColorToRGBAFloat(local.fColor, c); - pdman.set4fv(fColorUniform, 1, c); - fColor = local.fColor; + void setTransformData(const GrPrimitiveProcessor* primProc, + int index, + const SkTArray<const GrCoordTransform*, true>& coordTransforms, + GrGLPathRendering* glpr, + GrGLuint programID) SK_OVERRIDE { + SkSTArray<2, Transform, true>& transforms = fInstalledTransforms[index]; + int numTransforms = transforms.count(); + for (int t = 0; t < numTransforms; ++t) { + SkASSERT(transforms[t].fHandle.isValid()); + const SkMatrix& transform = GetTransformMatrix(primProc->localMatrix(), + *coordTransforms[t]); + if (transforms[t].fCurrentValue.cheapEqualTo(transform)) { + continue; + } + transforms[t].fCurrentValue = transform; + const SeparableVaryingInfo& fragmentInput = + fSeparableVaryingInfos[transforms[t].fHandle.handle()]; + SkASSERT(transforms[t].fType == kVec2f_GrSLType || + transforms[t].fType == kVec3f_GrSLType); + unsigned components = transforms[t].fType == kVec2f_GrSLType ? 2 : 3; + glpr->setProgramPathFragmentInputTransform(programID, + fragmentInput.fLocation, + GR_GL_OBJECT_LINEAR, + components, + transform); } } private: - UniformHandle fColorUniform; - GrColor fColor; + struct SeparableVaryingInfo { + GrSLType fType; + GrGLShaderVar fVariable; + GrGLint fLocation; + }; - typedef GrGLGeometryProcessor INHERITED; + + typedef SkSTArray<8, SeparableVaryingInfo, true> SeparableVaryingInfoArray; + + SeparableVaryingInfoArray fSeparableVaryingInfos; + + typedef GrGLPathProcessor INHERITED; }; GrPathProcessor::GrPathProcessor(GrColor color, @@ -196,6 +527,14 @@ void GrPathProcessor::getGLProcessorKey(const GrBatchTracker& bt, GrGLPathProcessor::GenKey(*this, bt, caps, b); } -GrGLGeometryProcessor* GrPathProcessor::createGLInstance(const GrBatchTracker& bt) const { - return SkNEW_ARGS(GrGLPathProcessor, (*this, bt)); +GrGLPrimitiveProcessor* GrPathProcessor::createGLInstance(const GrBatchTracker& bt, + const GrGLCaps& caps) const { + SkASSERT(caps.nvprSupport() != GrGLCaps::kNone_NvprSupport); + if (caps.nvprSupport() == GrGLCaps::kLegacy_NvprSupport) { + return SkNEW_ARGS(GrGLLegacyPathProcessor, (*this, bt, + caps.maxFixedFunctionTextureCoords())); + } else { + return SkNEW_ARGS(GrGLNormalPathProcessor, (*this, bt)); + } } + diff --git a/src/gpu/GrGeometryProcessor.h b/src/gpu/GrGeometryProcessor.h index ad75d23768..074fffcfb0 100644 --- a/src/gpu/GrGeometryProcessor.h +++ b/src/gpu/GrGeometryProcessor.h @@ -66,7 +66,7 @@ private: }; class GrGLCaps; -class GrGLGeometryProcessor; +class GrGLPrimitiveProcessor; class GrOptDrawState; struct GrInitInvariantOutput; @@ -122,6 +122,11 @@ public: virtual void getInvariantOutputCoverage(GrInitInvariantOutput* out) const = 0; /** + * Gets a transformKey from an array of coord transforms + */ + uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>&) const; + + /** * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry * processor's GL backend implementation. */ @@ -133,7 +138,8 @@ public: /** Returns a new instance of the appropriate *GL* implementation class for the given GrProcessor; caller is responsible for deleting the object. */ - virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const = 0; + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps& caps) const = 0; protected: GrPrimitiveProcessor(const SkMatrix& viewMatrix, const SkMatrix& localMatrix) @@ -171,6 +177,8 @@ protected: } private: + virtual bool hasExplicitLocalCoords() const = 0; + SkMatrix fViewMatrix; SkMatrix fLocalMatrix; @@ -261,7 +269,6 @@ public: return this->onCanMakeEqual(mine, other, theirs); } - // TODO we can remove color from the GrGeometryProcessor base class once we have bundles of // primitive data @@ -270,9 +277,6 @@ public: // TODO this is a total hack until the gp can do deferred geometry bool hasVertexColor() const { return fHasVertexColor; } - // TODO this is a total hack until gp can setup and manage local coords - bool hasLocalCoords() const { return fHasLocalCoords; } - void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE; void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE; @@ -332,9 +336,12 @@ private: virtual bool onCanMakeEqual(const GrBatchTracker& mine, const GrGeometryProcessor& that, const GrBatchTracker& theirs) const = 0; + // TODO delete this when we have more advanced equality testing via bundles and the BT virtual bool onIsEqual(const GrGeometryProcessor&) const = 0; + bool hasExplicitLocalCoords() const SK_OVERRIDE { return fHasLocalCoords; } + SkSTArray<kMaxVertexAttribs, GrAttribute, true> fAttribs; size_t fVertexStride; GrColor fColor; @@ -375,12 +382,18 @@ public: const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps& caps) const SK_OVERRIDE; -private: +protected: GrPathProcessor(GrColor color, const SkMatrix& viewMatrix, const SkMatrix& localMatrix); + +private: + bool hasExplicitLocalCoords() const SK_OVERRIDE { return false; } + GrColor fColor; typedef GrPrimitiveProcessor INHERITED; }; + #endif diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp index 2365f1e5a4..f9febf445b 100644 --- a/src/gpu/GrOptDrawState.cpp +++ b/src/gpu/GrOptDrawState.cpp @@ -87,9 +87,6 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState, fFlags |= kDither_Flag; } - // TODO move local coords completely into GP - bool hasLocalCoords = gp && gp->hasLocalCoords(); - int firstColorStageIdx = colorPOI.firstEffectiveStageIndex(); // TODO: Once we can handle single or four channel input into coverage stages then we can use @@ -102,8 +99,6 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState, this->adjustProgramFromOptimizations(drawState, optFlags, colorPOI, coveragePOI, &firstColorStageIdx, &firstCoverageStageIdx); - fDescInfo.fRequiresLocalCoordAttrib = hasLocalCoords; - bool usesLocalCoords = false; // Copy Stages from DS to ODS diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index 7f93bbe339..b5f3f5a8fe 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -83,12 +83,15 @@ public: const GrBatchTracker&) : fColor(GrColor_ILLEGAL) {} - void emitCode(const EmitArgs& args) SK_OVERRIDE { + void onEmitCode(EmitArgs& args) SK_OVERRIDE { const CircleEdgeEffect& ce = args.fGP.cast<CircleEdgeEffect>(); GrGLGPBuilder* pb = args.fPB; const BatchTracker& local = args.fBT.cast<BatchTracker>(); GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); + // emit attributes + vsBuilder->emitAttributes(ce); + GrGLVertToFrag v(kVec4f_GrSLType); args.fPB->addVarying("CircleEdge", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), ce.inCircleEdge()->fName); @@ -97,16 +100,16 @@ public: this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, &fColorUniform); - // setup coord outputs - vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ce.inPosition()->fName); - vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ce.inPosition()->fName); - // setup uniform viewMatrix this->addUniformViewMatrix(pb); - // setup position varying - vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), - this->uViewM(), ce.inPosition()->fName); + // Setup position + vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uViewM(), + ce.inPosition()->fName); + + // emit transforms + this->emitTransforms(args.fPB, this->position(), ce.inPosition()->fName, + ce.localMatrix(), args.fTransformsIn, args.fTransformsOut);; GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); fsBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn()); @@ -157,7 +160,8 @@ public: GLProcessor::GenKey(*this, bt, caps, b); } - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE { + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const SK_OVERRIDE { return SkNEW_ARGS(GLProcessor, (*this, bt)); } @@ -255,12 +259,15 @@ public: const GrBatchTracker&) : fColor(GrColor_ILLEGAL) {} - void emitCode(const EmitArgs& args) SK_OVERRIDE { + void onEmitCode(EmitArgs& args) SK_OVERRIDE { const EllipseEdgeEffect& ee = args.fGP.cast<EllipseEdgeEffect>(); GrGLGPBuilder* pb = args.fPB; const BatchTracker& local = args.fBT.cast<BatchTracker>(); GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); + // emit attributes + vsBuilder->emitAttributes(ee); + GrGLVertToFrag ellipseOffsets(kVec2f_GrSLType); args.fPB->addVarying("EllipseOffsets", &ellipseOffsets); vsBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(), @@ -275,16 +282,16 @@ public: this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, &fColorUniform); - // setup coord outputs - vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ee.inPosition()->fName); - vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ee.inPosition()->fName); - // setup uniform viewMatrix this->addUniformViewMatrix(pb); - // setup position varying - vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), - this->uViewM(), ee.inPosition()->fName); + // Setup position + vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uViewM(), + ee.inPosition()->fName); + + // emit transforms + this->emitTransforms(args.fPB, this->position(), ee.inPosition()->fName, + ee.localMatrix(), args.fTransformsIn, args.fTransformsOut); // for outer curve GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); @@ -351,7 +358,8 @@ public: GLProcessor::GenKey(*this, bt, caps, b); } - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE { + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const SK_OVERRIDE { return SkNEW_ARGS(GLProcessor, (*this, bt)); } @@ -455,12 +463,15 @@ public: const GrBatchTracker&) : fColor(GrColor_ILLEGAL) {} - void emitCode(const EmitArgs& args) SK_OVERRIDE { + void onEmitCode(EmitArgs& args) SK_OVERRIDE { const DIEllipseEdgeEffect& ee = args.fGP.cast<DIEllipseEdgeEffect>(); GrGLGPBuilder* pb = args.fPB; const BatchTracker& local = args.fBT.cast<BatchTracker>(); GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); + // emit attributes + vsBuilder->emitAttributes(ee); + GrGLVertToFrag offsets0(kVec2f_GrSLType); args.fPB->addVarying("EllipseOffsets0", &offsets0); vsBuilder->codeAppendf("%s = %s;", offsets0.vsOut(), @@ -475,16 +486,16 @@ public: this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, &fColorUniform); - // setup coord outputs - vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ee.inPosition()->fName); - vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ee.inPosition()->fName); - // setup uniform viewMatrix this->addUniformViewMatrix(pb); - // setup position varying - vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), - this->uViewM(), ee.inPosition()->fName); + // Setup position + vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uViewM(), + ee.inPosition()->fName); + + // emit transforms + this->emitTransforms(args.fPB, this->position(), ee.inPosition()->fName, + ee.localMatrix(), args.fTransformsIn, args.fTransformsOut); GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); SkAssertResult(fsBuilder->enableFeature( @@ -566,7 +577,8 @@ public: GLProcessor::GenKey(*this, bt, caps, b); } - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE { + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const SK_OVERRIDE { return SkNEW_ARGS(GLProcessor, (*this, bt)); } diff --git a/src/gpu/GrProgramDesc.h b/src/gpu/GrProgramDesc.h index 9ba20aa94a..e07e116733 100644 --- a/src/gpu/GrProgramDesc.h +++ b/src/gpu/GrProgramDesc.h @@ -83,8 +83,7 @@ public: struct DescInfo { bool operator==(const DescInfo& that) const { return fReadsDst == that.fReadsDst && - fReadsFragPosition == that.fReadsFragPosition && - fRequiresLocalCoordAttrib == that.fRequiresLocalCoordAttrib; + fReadsFragPosition == that.fReadsFragPosition; } bool operator!=(const DescInfo& that) const { return !(*this == that); }; @@ -92,7 +91,6 @@ public: // programs. bool fReadsDst; bool fReadsFragPosition; - bool fRequiresLocalCoordAttrib; }; private: diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp index e16601dee1..f674345728 100644 --- a/src/gpu/effects/GrBezierEffect.cpp +++ b/src/gpu/effects/GrBezierEffect.cpp @@ -24,7 +24,7 @@ public: GrGLConicEffect(const GrGeometryProcessor&, const GrBatchTracker&); - void emitCode(const EmitArgs&) SK_OVERRIDE; + void onEmitCode(EmitArgs&) SK_OVERRIDE; static inline void GenKey(const GrGeometryProcessor&, const GrBatchTracker&, @@ -66,12 +66,15 @@ GrGLConicEffect::GrGLConicEffect(const GrGeometryProcessor& processor, fEdgeType = ce.getEdgeType(); } -void GrGLConicEffect::emitCode(const EmitArgs& args) { +void GrGLConicEffect::onEmitCode(EmitArgs& args) { GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); const GrConicEffect& gp = args.fGP.cast<GrConicEffect>(); const ConicBatchTracker& local = args.fBT.cast<ConicBatchTracker>(); + // emit attributes + vsBuilder->emitAttributes(gp); + GrGLVertToFrag v(kVec4f_GrSLType); args.fPB->addVarying("ConicCoeffs", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName); @@ -80,17 +83,17 @@ void GrGLConicEffect::emitCode(const EmitArgs& args) { this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL, &fColorUniform); - // setup coord outputs - vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName); - vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName); - // setup uniform viewMatrix this->addUniformViewMatrix(pb); - // setup position varying - vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(), + // Setup position + vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uViewM(), gp.inPosition()->fName); + // emit transforms with position + this->emitTransforms(pb, this->position(), gp.inPosition()->fName, gp.localMatrix(), + args.fTransformsIn, args.fTransformsOut); + GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); fsBuilder->codeAppend("float edgeAlpha;"); @@ -184,7 +187,8 @@ void GrConicEffect::getGLProcessorKey(const GrBatchTracker& bt, GrGLConicEffect::GenKey(*this, bt, caps, b); } -GrGLGeometryProcessor* GrConicEffect::createGLInstance(const GrBatchTracker& bt) const { +GrGLPrimitiveProcessor* GrConicEffect::createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const { return SkNEW_ARGS(GrGLConicEffect, (*this, bt)); } @@ -258,7 +262,7 @@ public: GrGLQuadEffect(const GrGeometryProcessor&, const GrBatchTracker&); - void emitCode(const EmitArgs&) SK_OVERRIDE; + void onEmitCode(EmitArgs&) SK_OVERRIDE; static inline void GenKey(const GrGeometryProcessor&, const GrBatchTracker&, @@ -300,12 +304,15 @@ GrGLQuadEffect::GrGLQuadEffect(const GrGeometryProcessor& processor, fEdgeType = ce.getEdgeType(); } -void GrGLQuadEffect::emitCode(const EmitArgs& args) { +void GrGLQuadEffect::onEmitCode(EmitArgs& args) { GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); const GrQuadEffect& gp = args.fGP.cast<GrQuadEffect>(); const QuadBatchTracker& local = args.fBT.cast<QuadBatchTracker>(); + // emit attributes + vsBuilder->emitAttributes(gp); + GrGLVertToFrag v(kVec4f_GrSLType); args.fPB->addVarying("HairQuadEdge", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName); @@ -314,17 +321,17 @@ void GrGLQuadEffect::emitCode(const EmitArgs& args) { this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL, &fColorUniform); - // setup coord outputs - vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName); - vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName); - // setup uniform viewMatrix this->addUniformViewMatrix(pb); - // setup position varying - vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(), + // Setup position + vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uViewM(), gp.inPosition()->fName); + // emit transforms with position + this->emitTransforms(pb, this->position(), gp.inPosition()->fName, gp.localMatrix(), + args.fTransformsIn, args.fTransformsOut); + GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); fsBuilder->codeAppendf("float edgeAlpha;"); @@ -404,7 +411,8 @@ void GrQuadEffect::getGLProcessorKey(const GrBatchTracker& bt, GrGLQuadEffect::GenKey(*this, bt, caps, b); } -GrGLGeometryProcessor* GrQuadEffect::createGLInstance(const GrBatchTracker& bt) const { +GrGLPrimitiveProcessor* GrQuadEffect::createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const { return SkNEW_ARGS(GrGLQuadEffect, (*this, bt)); } @@ -478,7 +486,7 @@ public: GrGLCubicEffect(const GrGeometryProcessor&, const GrBatchTracker&); - void emitCode(const EmitArgs&) SK_OVERRIDE; + void onEmitCode(EmitArgs&) SK_OVERRIDE; static inline void GenKey(const GrGeometryProcessor&, const GrBatchTracker&, @@ -514,11 +522,14 @@ GrGLCubicEffect::GrGLCubicEffect(const GrGeometryProcessor& processor, fEdgeType = ce.getEdgeType(); } -void GrGLCubicEffect::emitCode(const EmitArgs& args) { +void GrGLCubicEffect::onEmitCode(EmitArgs& args) { GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); const GrCubicEffect& gp = args.fGP.cast<GrCubicEffect>(); const CubicBatchTracker& local = args.fBT.cast<CubicBatchTracker>(); + // emit attributes + vsBuilder->emitAttributes(gp); + GrGLVertToFrag v(kVec4f_GrSLType); args.fPB->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName); @@ -527,17 +538,17 @@ void GrGLCubicEffect::emitCode(const EmitArgs& args) { this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL, &fColorUniform); - // setup coord outputs - vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName); - vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName); - // setup uniform viewMatrix this->addUniformViewMatrix(args.fPB); - // setup position varying - vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(), + // Setup position + vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uViewM(), gp.inPosition()->fName); + // emit transforms with position + this->emitTransforms(args.fPB, this->position(), gp.inPosition()->fName, gp.localMatrix(), + args.fTransformsIn, args.fTransformsOut); + GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, kHigh_GrSLPrecision); @@ -647,7 +658,8 @@ void GrCubicEffect::getGLProcessorKey(const GrBatchTracker& bt, GrGLCubicEffect::GenKey(*this, bt, caps, b); } -GrGLGeometryProcessor* GrCubicEffect::createGLInstance(const GrBatchTracker& bt) const { +GrGLPrimitiveProcessor* GrCubicEffect::createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const { return SkNEW_ARGS(GrGLCubicEffect, (*this, bt)); } diff --git a/src/gpu/effects/GrBezierEffect.h b/src/gpu/effects/GrBezierEffect.h index f31542f4db..86f09bc58d 100644 --- a/src/gpu/effects/GrBezierEffect.h +++ b/src/gpu/effects/GrBezierEffect.h @@ -102,7 +102,8 @@ public: const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const SK_OVERRIDE; void initBatchTracker(GrBatchTracker*, const InitBT&) const SK_OVERRIDE; bool onCanMakeEqual(const GrBatchTracker&, @@ -186,7 +187,8 @@ public: const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const SK_OVERRIDE; void initBatchTracker(GrBatchTracker*, const InitBT&) const SK_OVERRIDE; bool onCanMakeEqual(const GrBatchTracker&, @@ -266,7 +268,8 @@ public: const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const SK_OVERRIDE; void initBatchTracker(GrBatchTracker*, const InitBT&) const SK_OVERRIDE; bool onCanMakeEqual(const GrBatchTracker&, diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp index 1cfb64414b..0818fc0d8c 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.cpp +++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp @@ -25,13 +25,16 @@ public: GrGLBitmapTextGeoProc(const GrGeometryProcessor&, const GrBatchTracker&) : fColor(GrColor_ILLEGAL) {} - void emitCode(const EmitArgs& args) SK_OVERRIDE { + void onEmitCode(EmitArgs& args) SK_OVERRIDE { const GrBitmapTextGeoProc& cte = args.fGP.cast<GrBitmapTextGeoProc>(); const BitmapTextBatchTracker& local = args.fBT.cast<BitmapTextBatchTracker>(); GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); + // emit attributes + vsBuilder->emitAttributes(cte); + GrGLVertToFrag v(kVec2f_GrSLType); pb->addVarying("TextureCoords", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), cte.inTextureCoords()->fName); @@ -40,17 +43,17 @@ public: this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, cte.inColor(), &fColorUniform); - // setup output coords - vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), cte.inPosition()->fName); - vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), cte.inPosition()->fName); - // setup uniform viewMatrix this->addUniformViewMatrix(pb); - // setup position varying - vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(), + // Setup position + vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uViewM(), cte.inPosition()->fName); + // emit transforms + this->emitTransforms(args.fPB, this->position(), cte.inPosition()->fName, + cte.localMatrix(), args.fTransformsIn, args.fTransformsOut); + GrGLGPFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); fsBuilder->codeAppendf("%s = ", args.fOutputCoverage); fsBuilder->appendTextureLookup(args.fSamplers[0], v.fsIn(), kVec2f_GrSLType); @@ -135,8 +138,9 @@ void GrBitmapTextGeoProc::getGLProcessorKey(const GrBatchTracker& bt, GrGLBitmapTextGeoProc::GenKey(*this, bt, caps, b); } -GrGLGeometryProcessor* -GrBitmapTextGeoProc::createGLInstance(const GrBatchTracker& bt) const { +GrGLPrimitiveProcessor* +GrBitmapTextGeoProc::createGLInstance(const GrBatchTracker& bt, + const GrGLCaps& caps) const { return SkNEW_ARGS(GrGLBitmapTextGeoProc, (*this, bt)); } diff --git a/src/gpu/effects/GrBitmapTextGeoProc.h b/src/gpu/effects/GrBitmapTextGeoProc.h index 85e4f421e1..399678ab2a 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.h +++ b/src/gpu/effects/GrBitmapTextGeoProc.h @@ -40,7 +40,8 @@ public: const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps& caps) const SK_OVERRIDE; void initBatchTracker(GrBatchTracker*, const InitBT&) const SK_OVERRIDE; bool onCanMakeEqual(const GrBatchTracker&, diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp index 8b69dca9d2..2543145c20 100644 --- a/src/gpu/effects/GrDashingEffect.cpp +++ b/src/gpu/effects/GrDashingEffect.cpp @@ -496,7 +496,8 @@ public: const GrGLCaps&, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker&) const SK_OVERRIDE; + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker&, + const GrGLCaps&) const SK_OVERRIDE; void initBatchTracker(GrBatchTracker* bt, const InitBT& init) const SK_OVERRIDE; @@ -530,7 +531,7 @@ class GLDashingCircleEffect : public GrGLGeometryProcessor { public: GLDashingCircleEffect(const GrGeometryProcessor&, const GrBatchTracker&); - void emitCode(const EmitArgs&) SK_OVERRIDE; + void onEmitCode(EmitArgs&) SK_OVERRIDE; static inline void GenKey(const GrGeometryProcessor&, const GrBatchTracker&, @@ -559,7 +560,7 @@ GLDashingCircleEffect::GLDashingCircleEffect(const GrGeometryProcessor&, fPrevIntervalLength = SK_ScalarMax; } -void GLDashingCircleEffect::emitCode(const EmitArgs& args) { +void GLDashingCircleEffect::onEmitCode(EmitArgs& args) { const DashingCircleEffect& dce = args.fGP.cast<DashingCircleEffect>(); const DashingCircleBatchTracker local = args.fBT.cast<DashingCircleBatchTracker>(); GrGLGPBuilder* pb = args.fPB; @@ -572,6 +573,9 @@ void GLDashingCircleEffect::emitCode(const EmitArgs& args) { GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); + // emit attributes + vsBuilder->emitAttributes(dce); + GrGLVertToFrag v(kVec2f_GrSLType); args.fPB->addVarying("Coord", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dce.inCoord()->fName); @@ -579,17 +583,17 @@ void GLDashingCircleEffect::emitCode(const EmitArgs& args) { // Setup pass through color this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, &fColorUniform); - // setup coord outputs - vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), dce.inPosition()->fName); - vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), dce.inPosition()->fName); - // setup uniform viewMatrix this->addUniformViewMatrix(pb); - // setup position varying - vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(), + // Setup position + vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uViewM(), dce.inPosition()->fName); + // emit transforms + this->emitTransforms(args.fPB, this->position(), dce.inPosition()->fName, dce.localMatrix(), + args.fTransformsIn, args.fTransformsOut); + // transforms all points so that we can compare them to our test circle GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.z;\n", @@ -669,7 +673,8 @@ void DashingCircleEffect::getGLProcessorKey(const GrBatchTracker& bt, GLDashingCircleEffect::GenKey(*this, bt, caps, b); } -GrGLGeometryProcessor* DashingCircleEffect::createGLInstance(const GrBatchTracker& bt) const { +GrGLPrimitiveProcessor* DashingCircleEffect::createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const { return SkNEW_ARGS(GLDashingCircleEffect, (*this, bt)); } @@ -783,7 +788,8 @@ public: const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const SK_OVERRIDE; void initBatchTracker(GrBatchTracker* bt, const InitBT& init) const SK_OVERRIDE; @@ -816,7 +822,7 @@ class GLDashingLineEffect : public GrGLGeometryProcessor { public: GLDashingLineEffect(const GrGeometryProcessor&, const GrBatchTracker&); - void emitCode(const EmitArgs&) SK_OVERRIDE; + void onEmitCode(EmitArgs&) SK_OVERRIDE; static inline void GenKey(const GrGeometryProcessor&, const GrBatchTracker&, @@ -844,7 +850,7 @@ GLDashingLineEffect::GLDashingLineEffect(const GrGeometryProcessor&, fPrevIntervalLength = SK_ScalarMax; } -void GLDashingLineEffect::emitCode(const EmitArgs& args) { +void GLDashingLineEffect::onEmitCode(EmitArgs& args) { const DashingLineEffect& de = args.fGP.cast<DashingLineEffect>(); const DashingLineBatchTracker& local = args.fBT.cast<DashingLineBatchTracker>(); GrGLGPBuilder* pb = args.fPB; @@ -865,6 +871,9 @@ void GLDashingLineEffect::emitCode(const EmitArgs& args) { GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); + // emit attributes + vsBuilder->emitAttributes(de); + GrGLVertToFrag v(kVec2f_GrSLType); args.fPB->addVarying("Coord", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), de.inCoord()->fName); @@ -872,17 +881,17 @@ void GLDashingLineEffect::emitCode(const EmitArgs& args) { // Setup pass through color this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, &fColorUniform); - // setup coord outputs - vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), de.inPosition()->fName); - vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), de.inPosition()->fName); - // setup uniform viewMatrix this->addUniformViewMatrix(pb); - // setup position varying - vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(), + // Setup position + vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uViewM(), de.inPosition()->fName); + // emit transforms + this->emitTransforms(args.fPB, this->position(), de.inPosition()->fName, de.localMatrix(), + args.fTransformsIn, args.fTransformsOut); + // transforms all points so that we can compare them to our test rect GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n", @@ -969,7 +978,8 @@ void DashingLineEffect::getGLProcessorKey(const GrBatchTracker& bt, GLDashingLineEffect::GenKey(*this, bt, caps, b); } -GrGLGeometryProcessor* DashingLineEffect::createGLInstance(const GrBatchTracker& bt) const { +GrGLPrimitiveProcessor* DashingLineEffect::createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const { return SkNEW_ARGS(GLDashingLineEffect, (*this, bt)); } diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp index cdb6ff75e1..24fe001b06 100755 --- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp +++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp @@ -35,7 +35,7 @@ public: #endif {} - void emitCode(const EmitArgs& args) SK_OVERRIDE { + void onEmitCode(EmitArgs& args) SK_OVERRIDE { const GrDistanceFieldTextureEffect& dfTexEffect = args.fGP.cast<GrDistanceFieldTextureEffect>(); const DistanceFieldBatchTracker& local = args.fBT.cast<DistanceFieldBatchTracker>(); @@ -45,6 +45,10 @@ public: GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); + + // emit attributes + vsBuilder->emitAttributes(dfTexEffect); + GrGLVertToFrag v(kVec2f_GrSLType); args.fPB->addVarying("TextureCoords", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName); @@ -56,16 +60,14 @@ public: // setup uniform viewMatrix this->addUniformViewMatrix(pb); - // setup position varying - vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), - this->uViewM(), dfTexEffect.inPosition()->fName); - - // setup output coords - vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), - dfTexEffect.inPosition()->fName); - vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), + // Setup position + vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uViewM(), dfTexEffect.inPosition()->fName); + // emit transforms + this->emitTransforms(args.fPB, this->position(), dfTexEffect.inPosition()->fName, + dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut); + const char* textureSizeUniName = NULL; fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec2f_GrSLType, kDefault_GrSLPrecision, @@ -242,8 +244,9 @@ void GrDistanceFieldTextureEffect::getGLProcessorKey(const GrBatchTracker& bt, GrGLDistanceFieldTextureEffect::GenKey(*this, bt, caps, b); } -GrGLGeometryProcessor* -GrDistanceFieldTextureEffect::createGLInstance(const GrBatchTracker& bt) const { +GrGLPrimitiveProcessor* +GrDistanceFieldTextureEffect::createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const { return SkNEW_ARGS(GrGLDistanceFieldTextureEffect, (*this, bt)); } @@ -321,7 +324,7 @@ public: const GrBatchTracker&) : fColor(GrColor_ILLEGAL), fTextureSize(SkISize::Make(-1, -1)) {} - void emitCode(const EmitArgs& args) SK_OVERRIDE { + void onEmitCode(EmitArgs& args) SK_OVERRIDE { const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = args.fGP.cast<GrDistanceFieldNoGammaTextureEffect>(); @@ -333,6 +336,10 @@ public: GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); + + // emit attributes + vsBuilder->emitAttributes(dfTexEffect); + GrGLVertToFrag v(kVec2f_GrSLType); args.fPB->addVarying("TextureCoords", &v); @@ -342,18 +349,16 @@ public: vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName); - // setup coord outputs - vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), - dfTexEffect.inPosition()->fName); - vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), - dfTexEffect.inPosition()->fName); - // setup uniform viewMatrix this->addUniformViewMatrix(pb); - // setup position varying - vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), - this->uViewM(), dfTexEffect.inPosition()->fName); + // Setup position + vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uViewM(), + dfTexEffect.inPosition()->fName); + + // emit transforms + this->emitTransforms(args.fPB, this->position(), dfTexEffect.inPosition()->fName, + dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut); const char* textureSizeUniName = NULL; fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, @@ -493,8 +498,9 @@ void GrDistanceFieldNoGammaTextureEffect::getGLProcessorKey(const GrBatchTracker GrGLDistanceFieldNoGammaTextureEffect::GenKey(*this, bt, caps, b); } -GrGLGeometryProcessor* -GrDistanceFieldNoGammaTextureEffect::createGLInstance(const GrBatchTracker& bt) const { +GrGLPrimitiveProcessor* +GrDistanceFieldNoGammaTextureEffect::createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const { return SkNEW_ARGS(GrGLDistanceFieldNoGammaTextureEffect, (*this, bt)); } @@ -562,13 +568,17 @@ public: , fTextureSize(SkISize::Make(-1,-1)) , fTextColor(GrColor_ILLEGAL) {} - void emitCode(const EmitArgs& args) SK_OVERRIDE { + void onEmitCode(EmitArgs& args) SK_OVERRIDE { const GrDistanceFieldLCDTextureEffect& dfTexEffect = args.fGP.cast<GrDistanceFieldLCDTextureEffect>(); const DistanceFieldLCDBatchTracker& local = args.fBT.cast<DistanceFieldLCDBatchTracker>(); GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); + + // emit attributes + vsBuilder->emitAttributes(dfTexEffect); + GrGLVertToFrag v(kVec2f_GrSLType); args.fPB->addVarying("TextureCoords", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName); @@ -577,19 +587,17 @@ public: this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, &fColorUniform); - // setup coord outputs - vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), - dfTexEffect.inPosition()->fName); - vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), - dfTexEffect.inPosition()->fName); - // setup uniform viewMatrix this->addUniformViewMatrix(pb); - // setup position varying - vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(), + // Setup position + vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uViewM(), dfTexEffect.inPosition()->fName); + // emit transforms + this->emitTransforms(args.fPB, this->position(), dfTexEffect.inPosition()->fName, + dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut); + const char* textureSizeUniName = NULL; // width, height, 1/(3*width) fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, @@ -805,8 +813,9 @@ void GrDistanceFieldLCDTextureEffect::getGLProcessorKey(const GrBatchTracker& bt GrGLDistanceFieldLCDTextureEffect::GenKey(*this, bt, caps, b); } -GrGLGeometryProcessor* -GrDistanceFieldLCDTextureEffect::createGLInstance(const GrBatchTracker& bt) const { +GrGLPrimitiveProcessor* +GrDistanceFieldLCDTextureEffect::createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const { return SkNEW_ARGS(GrGLDistanceFieldLCDTextureEffect, (*this, bt)); } diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.h b/src/gpu/effects/GrDistanceFieldTextureEffect.h index 6edcf988d2..2fb448b463 100644 --- a/src/gpu/effects/GrDistanceFieldTextureEffect.h +++ b/src/gpu/effects/GrDistanceFieldTextureEffect.h @@ -80,7 +80,8 @@ public: const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const SK_OVERRIDE; void initBatchTracker(GrBatchTracker* bt, const InitBT& init) const SK_OVERRIDE; @@ -144,7 +145,8 @@ public: const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const SK_OVERRIDE; void initBatchTracker(GrBatchTracker* bt, const InitBT& init) const SK_OVERRIDE; @@ -201,7 +203,8 @@ public: const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; + virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, + const GrGLCaps&) const SK_OVERRIDE; void initBatchTracker(GrBatchTracker* bt, const InitBT& init) const SK_OVERRIDE; diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 376bfd432a..73df30b5f3 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -25,6 +25,7 @@ void GrGLCaps::reset() { fMSFBOType = kNone_MSFBOType; fInvalidateFBType = kNone_InvalidateFBType; fLATCAlias = kLATC_LATCAlias; + fNvprSupport = kNone_NvprSupport; fMapBufferType = kNone_MapBufferType; fMaxFragmentUniformVectors = 0; fMaxVertexAttributes = 0; @@ -67,6 +68,7 @@ GrGLCaps& GrGLCaps::operator= (const GrGLCaps& caps) { fStencilFormats = caps.fStencilFormats; fStencilVerifiedColorConfigs = caps.fStencilVerifiedColorConfigs; fLATCAlias = caps.fLATCAlias; + fNvprSupport = caps.fNvprSupport; fMaxFragmentUniformVectors = caps.fMaxFragmentUniformVectors; fMaxVertexAttributes = caps.fMaxVertexAttributes; fMaxFragmentTextureUnits = caps.fMaxFragmentTextureUnits; @@ -359,9 +361,16 @@ bool GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { ((ctxInfo.version() >= GR_GL_VER(4,3) || ctxInfo.hasExtension("GL_ARB_program_interface_query")) && gli->fFunctions.fProgramPathFragmentInputGen)); + if (fPathRenderingSupport) { + fNvprSupport = gli->fFunctions.fProgramPathFragmentInputGen ? kNormal_NvprSupport : + kLegacy_NvprSupport; + } } else { fPathRenderingSupport = ctxInfo.version() >= GR_GL_VER(3,1); + fNvprSupport = fPathRenderingSupport ? kNormal_NvprSupport : kNone_NvprSupport; } + } else { + fNvprSupport = kNone_NvprSupport; } fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker"); diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index 77baf38a96..527cd33ee3 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -286,6 +286,18 @@ public: LATCAlias latcAlias() const { return fLATCAlias; } + /** + * Which type of path rendering is supported, if any + * TODO delete this when we only support normal non-legacy nvpr + */ + enum NvprSupport { + kNone_NvprSupport, + kLegacy_NvprSupport, + kNormal_NvprSupport, + }; + + NvprSupport nvprSupport() const { return fNvprSupport; } + private: /** * Maintains a bit per GrPixelConfig. It is used to avoid redundantly @@ -354,6 +366,7 @@ private: InvalidateFBType fInvalidateFBType; MapBufferType fMapBufferType; LATCAlias fLATCAlias; + NvprSupport fNvprSupport; bool fRGBA8RenderbufferSupport : 1; bool fBGRAIsInternalFormat : 1; diff --git a/src/gpu/gl/GrGLGeometryProcessor.h b/src/gpu/gl/GrGLGeometryProcessor.h index 0b24144d84..524cdf3aa9 100644 --- a/src/gpu/gl/GrGLGeometryProcessor.h +++ b/src/gpu/gl/GrGLGeometryProcessor.h @@ -11,57 +11,67 @@ #include "GrGLProcessor.h" class GrBatchTracker; +class GrFragmentProcessor; class GrGLGPBuilder; -/** - * If a GL effect needs a GrGLFullShaderBuilder* object to emit vertex code, then it must inherit - * from this class. Since paths don't have vertices, this class is only meant to be used internally - * by skia, for special cases. - */ -class GrGLGeometryProcessor { +class GrGLPrimitiveProcessor { public: - GrGLGeometryProcessor() : fViewMatrixName(NULL) { fViewMatrix = SkMatrix::InvalidMatrix(); } - virtual ~GrGLGeometryProcessor() {} + GrGLPrimitiveProcessor() : fViewMatrixName(NULL) { fViewMatrix = SkMatrix::InvalidMatrix(); } + virtual ~GrGLPrimitiveProcessor() {} typedef GrGLProgramDataManager::UniformHandle UniformHandle; typedef GrGLProcessor::TextureSamplerArray TextureSamplerArray; + typedef SkSTArray<2, const GrCoordTransform*, true> ProcCoords; + typedef SkSTArray<8, ProcCoords> TransformsIn; + typedef SkSTArray<8, GrGLProcessor::TransformedCoordsArray> TransformsOut; + struct EmitArgs { EmitArgs(GrGLGPBuilder* pb, const GrPrimitiveProcessor& gp, const GrBatchTracker& bt, const char* outputColor, const char* outputCoverage, - const TextureSamplerArray& samplers) + const TextureSamplerArray& samplers, + const TransformsIn& transformsIn, + TransformsOut* transformsOut) : fPB(pb) , fGP(gp) , fBT(bt) , fOutputColor(outputColor) , fOutputCoverage(outputCoverage) - , fSamplers(samplers) {} + , fSamplers(samplers) + , fTransformsIn(transformsIn) + , fTransformsOut(transformsOut) {} GrGLGPBuilder* fPB; const GrPrimitiveProcessor& fGP; const GrBatchTracker& fBT; const char* fOutputColor; const char* fOutputCoverage; const TextureSamplerArray& fSamplers; + const TransformsIn& fTransformsIn; + TransformsOut* fTransformsOut; }; /** * 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; + virtual void emitCode(EmitArgs&) = 0; + - /** A GrGLGeometryProcessor instance can be reused with any GrGLGeometryProcessor that produces - the same stage key; this function reads data from a GrGLGeometryProcessor and uploads any - uniform variables required by the shaders created in emitCode(). The GrGeometryProcessor - parameter is guaranteed to be of the same type that created this GrGLGeometryProcessor and - to have an identical processor key as the one that created this GrGLGeometryProcessor. */ + /** A GrGLPrimitiveProcessor instance can be reused with any GrGLPrimitiveProcessor that + produces the same stage key; this function reads data from a GrGLPrimitiveProcessor and + uploads any uniform variables required by the shaders created in emitCode(). The + GrPrimitiveProcessor parameter is guaranteed to be of the same type that created this + GrGLPrimitiveProcessor and to have an identical processor key as the one that created this + GrGLPrimitiveProcessor. */ virtual void setData(const GrGLProgramDataManager&, const GrPrimitiveProcessor&, const GrBatchTracker&) = 0; + static SkMatrix GetTransformMatrix(const SkMatrix& localMatrix, const GrCoordTransform&); + protected: /** a helper which can setup vertex, constant, or uniform color depending on inputType. * This function will only do the minimum required to emit the correct shader code. If @@ -86,12 +96,111 @@ protected: void setUniformViewMatrix(const GrGLProgramDataManager&, const SkMatrix& viewMatrix); + class ShaderVarHandle { + public: + bool isValid() const { return fHandle > -1; } + ShaderVarHandle() : fHandle(-1) {} + ShaderVarHandle(int value) : fHandle(value) { SkASSERT(this->isValid()); } + int handle() const { SkASSERT(this->isValid()); return fHandle; } + UniformHandle convertToUniformHandle() { + SkASSERT(this->isValid()); + return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fHandle); + } + + private: + int fHandle; + }; + + struct Transform { + Transform() : fType(kVoid_GrSLType) { fCurrentValue = SkMatrix::InvalidMatrix(); } + ShaderVarHandle fHandle; + SkMatrix fCurrentValue; + GrSLType fType; + }; + + SkSTArray<8, SkSTArray<2, Transform, true> > fInstalledTransforms; + private: UniformHandle fViewMatrixUniform; SkMatrix fViewMatrix; const char* fViewMatrixName; +}; + +class GrGLPathRendering; +/** + * If a GL effect needs a GrGLFullShaderBuilder* object to emit vertex code, then it must inherit + * from this class. Since paths don't have vertices, this class is only meant to be used internally + * by skia, for special cases. + */ +class GrGLGeometryProcessor : public GrGLPrimitiveProcessor { +public: + /* Any general emit code goes in the base class emitCode. Subclasses override onEmitCode */ + void emitCode(EmitArgs&) SK_OVERRIDE; + + void setTransformData(const GrPrimitiveProcessor*, + const GrGLProgramDataManager&, + int index, + const SkTArray<const GrCoordTransform*, true>& transforms); + +protected: + const char* position() const { return "pos3"; } + + // Many GrGeometryProcessors do not need explicit local coords + void emitTransforms(GrGLGPBuilder* gp, + const char* position, + const SkMatrix& localMatrix, + const TransformsIn& tin, + TransformsOut* tout) { + this->emitTransforms(gp, position, position, localMatrix, tin, tout); + } + + void emitTransforms(GrGLGPBuilder*, + const char* position, + const char* localCoords, + const SkMatrix& localMatrix, + const TransformsIn&, + TransformsOut*); + +private: + virtual void onEmitCode(EmitArgs&) = 0; + + typedef GrGLPrimitiveProcessor INHERITED; +}; + +class GrGLGpu; + +class GrGLPathProcessor : public GrGLPrimitiveProcessor { +public: + GrGLPathProcessor(const GrPathProcessor&, const GrBatchTracker&); + + static void GenKey(const GrPathProcessor&, + const GrBatchTracker& bt, + const GrGLCaps&, + GrProcessorKeyBuilder* b); + + void emitCode(EmitArgs&) SK_OVERRIDE; + + virtual void emitTransforms(GrGLGPBuilder*, const TransformsIn&, TransformsOut*) = 0; + + virtual void resolveSeparableVaryings(GrGLGpu* gpu, GrGLuint programId) {} + + void setData(const GrGLProgramDataManager&, + const GrPrimitiveProcessor&, + const GrBatchTracker&) SK_OVERRIDE; + + virtual void setTransformData(const GrPrimitiveProcessor*, + int index, + const SkTArray<const GrCoordTransform*, true>& transforms, + GrGLPathRendering*, + GrGLuint programID) = 0; + + virtual void didSetData(GrGLPathRendering*) {} + +private: + UniformHandle fColorUniform; + GrColor fColor; - typedef GrGLProcessor INHERITED; + typedef GrGLPrimitiveProcessor INHERITED; }; #endif diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 9400e54b12..1af3e56c49 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -24,34 +24,6 @@ #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X) -/** - * Retrieves the final matrix that a transform needs to apply to its source coords. - */ -static SkMatrix get_transform_matrix(const GrPendingFragmentStage& stage, - int transformIdx, - const SkMatrix& localMatrix) { - const GrCoordTransform& coordTransform = stage.processor()->coordTransform(transformIdx); - SkMatrix combined; - - // We only apply the localmatrix to localcoords - if (kLocal_GrCoordSet == coordTransform.sourceCoords()) { - combined.setConcat(coordTransform.getMatrix(), localMatrix); - } else { - combined = coordTransform.getMatrix(); - } - if (coordTransform.reverseY()) { - // combined.postScale(1,-1); - // combined.postTranslate(0,1); - combined.set(SkMatrix::kMSkewY, - combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]); - combined.set(SkMatrix::kMScaleY, - combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]); - combined.set(SkMatrix::kMTransY, - combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]); - } - return combined; -} - /////////////////////////////////////////////////////////////////////////////////////////////////// GrGLProgram::GrGLProgram(GrGLGpu* gpu, @@ -93,9 +65,7 @@ void GrGLProgram::initSamplerUniforms() { fProgramDataManager.setSampler(fBuiltinUniformHandles.fDstCopySamplerUni, texUnitIdx); fDstCopyTexUnit = texUnitIdx++; } - if (fGeometryProcessor.get()) { - this->initSamplers(fGeometryProcessor.get(), &texUnitIdx); - } + this->initSamplers(fGeometryProcessor.get(), &texUnitIdx); if (fXferProcessor.get()) { this->initSamplers(fXferProcessor.get(), &texUnitIdx); } @@ -105,8 +75,9 @@ void GrGLProgram::initSamplerUniforms() { } } -void GrGLProgram::initSamplers(GrGLInstalledProc* ip, int* texUnitIdx) { - SkTArray<GrGLInstalledProc::Sampler, true>& samplers = ip->fSamplers; +template <class Proc> +void GrGLProgram::initSamplers(Proc* ip, int* texUnitIdx) { + SkTArray<typename Proc::Sampler, true>& samplers = ip->fSamplers; int numSamplers = samplers.count(); for (int s = 0; s < numSamplers; ++s) { SkASSERT(samplers[s].fUniform.isValid()); @@ -115,8 +86,9 @@ void GrGLProgram::initSamplers(GrGLInstalledProc* ip, int* texUnitIdx) { } } -void GrGLProgram::bindTextures(const GrGLInstalledProc* ip, const GrProcessor& processor) { - const SkTArray<GrGLInstalledProc::Sampler, true>& samplers = ip->fSamplers; +template <class Proc> +void GrGLProgram::bindTextures(const Proc* ip, const GrProcessor& processor) { + const SkTArray<typename Proc::Sampler, true>& samplers = ip->fSamplers; int numSamplers = samplers.count(); SkASSERT(numSamplers == processor.numTextures()); for (int s = 0; s < numSamplers; ++s) { @@ -161,12 +133,12 @@ void GrGLProgram::setData(const GrOptDrawState& optState) { const GrPrimitiveProcessor& primProc = *optState.getPrimitiveProcessor(); const GrBatchTracker& bt = optState.getBatchTracker(); fGeometryProcessor->fGLProc->setData(fProgramDataManager, primProc, bt); - this->bindTextures(fGeometryProcessor, primProc); + this->bindTextures(fGeometryProcessor.get(), primProc); if (fXferProcessor.get()) { const GrXferProcessor& xp = *optState.getXferProcessor(); fXferProcessor->fGLProc->setData(fProgramDataManager, xp); - this->bindTextures(fXferProcessor, xp); + this->bindTextures(fXferProcessor.get(), xp); } this->setFragmentData(optState); @@ -180,25 +152,21 @@ void GrGLProgram::setFragmentData(const GrOptDrawState& optState) { const GrPendingFragmentStage& stage = optState.getFragmentStage(e); const GrProcessor& processor = *stage.processor(); fFragmentProcessors->fProcs[e]->fGLProc->setData(fProgramDataManager, processor); - const SkMatrix& localMatrix = optState.getPrimitiveProcessor()->localMatrix(); - this->setTransformData(stage, localMatrix, fFragmentProcessors->fProcs[e]); + this->setTransformData(optState.getPrimitiveProcessor(), + stage, + e, + fFragmentProcessors->fProcs[e]); this->bindTextures(fFragmentProcessors->fProcs[e], processor); } } -void GrGLProgram::setTransformData(const GrPendingFragmentStage& processor, - const SkMatrix& localMatrix, +void GrGLProgram::setTransformData(const GrPrimitiveProcessor* primProc, + const GrPendingFragmentStage& processor, + int index, GrGLInstalledFragProc* ip) { - SkTArray<GrGLInstalledFragProc::Transform, true>& transforms = ip->fTransforms; - int numTransforms = transforms.count(); - SkASSERT(numTransforms == processor.processor()->numTransforms()); - for (int t = 0; t < numTransforms; ++t) { - SkASSERT(transforms[t].fHandle.isValid()); - const SkMatrix& matrix = get_transform_matrix(processor, t, localMatrix); - if (!transforms[t].fCurrentValue.cheapEqualTo(matrix)) { - fProgramDataManager.setSkMatrix(transforms[t].fHandle.convertToUniformHandle(), matrix); - transforms[t].fCurrentValue = matrix; - } - } + GrGLGeometryProcessor* gp = + static_cast<GrGLGeometryProcessor*>(fGeometryProcessor.get()->fGLProc.get()); + gp->setTransformData(primProc, fProgramDataManager, index, + processor.processor()->coordTransforms()); } void GrGLProgram::didSetData(GrGpu::DrawType drawType) { @@ -234,29 +202,6 @@ void GrGLProgram::onSetRenderTargetState(const GrOptDrawState& optState) { ///////////////////////////////////////////////////////////////////////////////////////// -GrGLNvprProgramBase::GrGLNvprProgramBase(GrGLGpu* gpu, - const GrProgramDesc& desc, - const BuiltinUniformHandles& builtinUniforms, - GrGLuint programID, - const UniformInfoArray& uniforms, - GrGLInstalledGeoProc* primProc, - GrGLInstalledXferProc* xferProcessor, - GrGLInstalledFragProcs* fragmentProcessors) - : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, primProc, - xferProcessor, fragmentProcessors) { -} - -void GrGLNvprProgramBase::onSetRenderTargetState(const GrOptDrawState& optState) { - SkASSERT(GrGpu::IsPathRenderingDrawType(optState.drawType())); - const GrRenderTarget* rt = optState.getRenderTarget(); - SkISize size; - size.set(rt->width(), rt->height()); - fGpu->glPathRendering()->setProjectionMatrix(optState.getPrimitiveProcessor()->viewMatrix(), - size, rt->origin()); -} - -///////////////////////////////////////////////////////////////////////////////////////// - GrGLNvprProgram::GrGLNvprProgram(GrGLGpu* gpu, const GrProgramDesc& desc, const BuiltinUniformHandles& builtinUniforms, @@ -264,85 +209,32 @@ GrGLNvprProgram::GrGLNvprProgram(GrGLGpu* gpu, const UniformInfoArray& uniforms, GrGLInstalledGeoProc* primProc, GrGLInstalledXferProc* xferProcessor, - GrGLInstalledFragProcs* fragmentProcessors, - const SeparableVaryingInfoArray& separableVaryings) + GrGLInstalledFragProcs* fragmentProcessors) : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, primProc, xferProcessor, fragmentProcessors) { - int count = separableVaryings.count(); - fVaryings.push_back_n(count); - for (int i = 0; i < count; i++) { - Varying& varying = fVaryings[i]; - const SeparableVaryingInfo& builderVarying = separableVaryings[i]; - SkASSERT(GrGLShaderVar::kNonArray == builderVarying.fVariable.getArrayCount()); - SkDEBUGCODE( - varying.fType = builderVarying.fVariable.getType(); - ); - varying.fLocation = builderVarying.fLocation; - } } - void GrGLNvprProgram::didSetData(GrGpu::DrawType drawType) { SkASSERT(GrGpu::IsPathRenderingDrawType(drawType)); + GrGLPathProcessor* pathProc = + static_cast<GrGLPathProcessor*>(fGeometryProcessor.get()->fGLProc.get()); + pathProc->didSetData(fGpu->glPathRendering()); } -void GrGLNvprProgram::setTransformData(const GrPendingFragmentStage& proc, - const SkMatrix& localMatrix, +void GrGLNvprProgram::setTransformData(const GrPrimitiveProcessor* primProc, + const GrPendingFragmentStage& proc, + int index, GrGLInstalledFragProc* ip) { - SkTArray<GrGLInstalledFragProc::Transform, true>& transforms = ip->fTransforms; - int numTransforms = transforms.count(); - SkASSERT(numTransforms == proc.processor()->numTransforms()); - for (int t = 0; t < numTransforms; ++t) { - SkASSERT(transforms[t].fHandle.isValid()); - const SkMatrix& transform = get_transform_matrix(proc, t, localMatrix); - if (transforms[t].fCurrentValue.cheapEqualTo(transform)) { - continue; - } - transforms[t].fCurrentValue = transform; - const Varying& fragmentInput = fVaryings[transforms[t].fHandle.handle()]; - SkASSERT(transforms[t].fType == kVec2f_GrSLType || transforms[t].fType == kVec3f_GrSLType); - unsigned components = transforms[t].fType == kVec2f_GrSLType ? 2 : 3; - fGpu->glPathRendering()->setProgramPathFragmentInputTransform(fProgramID, - fragmentInput.fLocation, - GR_GL_OBJECT_LINEAR, - components, - transform); - } + GrGLPathProcessor* pathProc = + static_cast<GrGLPathProcessor*>(fGeometryProcessor.get()->fGLProc.get()); + pathProc->setTransformData(primProc, index, proc.processor()->coordTransforms(), + fGpu->glPathRendering(), fProgramID); } -////////////////////////////////////////////////////////////////////////////////////// - -GrGLLegacyNvprProgram::GrGLLegacyNvprProgram(GrGLGpu* gpu, - const GrProgramDesc& desc, - const BuiltinUniformHandles& builtinUniforms, - GrGLuint programID, - const UniformInfoArray& uniforms, - GrGLInstalledGeoProc* primProc, - GrGLInstalledXferProc* xp, - GrGLInstalledFragProcs* fps, - int texCoordSetCnt) - : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, primProc, xp, fps) - , fTexCoordSetCnt(texCoordSetCnt) { -} - -void GrGLLegacyNvprProgram::didSetData(GrGpu::DrawType drawType) { - SkASSERT(GrGpu::IsPathRenderingDrawType(drawType)); - fGpu->glPathRendering()->flushPathTexGenSettings(fTexCoordSetCnt); -} - -void -GrGLLegacyNvprProgram::setTransformData(const GrPendingFragmentStage& proc, - const SkMatrix& localMatrix, - GrGLInstalledFragProc* ip) { - // We've hidden the texcoord index in the first entry of the transforms array for each effect - int texCoordIndex = ip->fTransforms[0].fHandle.handle(); - int numTransforms = proc.processor()->numTransforms(); - for (int t = 0; t < numTransforms; ++t) { - const SkMatrix& transform = get_transform_matrix(proc, t, localMatrix); - GrGLPathRendering::PathTexGenComponents components = - GrGLPathRendering::kST_PathTexGenComponents; - if (proc.isPerspectiveCoordTransform(t)) { - components = GrGLPathRendering::kSTR_PathTexGenComponents; - } - fGpu->glPathRendering()->enablePathTexGen(texCoordIndex++, components, transform); - } +void GrGLNvprProgram::onSetRenderTargetState(const GrOptDrawState& optState) { + SkASSERT(GrGpu::IsPathRenderingDrawType(optState.drawType())); + const GrRenderTarget* rt = optState.getRenderTarget(); + SkISize size; + size.set(rt->width(), rt->height()); + fGpu->glPathRendering()->setProjectionMatrix(optState.getPrimitiveProcessor()->viewMatrix(), + size, rt->origin()); } diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index e70fee738f..d18a92daf0 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -10,7 +10,6 @@ #define GrGLProgram_DEFINED #include "builders/GrGLProgramBuilder.h" -#include "builders/GrGLNvprProgramBuilder.h" #include "GrDrawState.h" #include "GrGLContext.h" #include "GrGLProgramDesc.h" @@ -118,14 +117,17 @@ protected: // Sets the texture units for samplers. void initSamplerUniforms(); - void initSamplers(GrGLInstalledProc*, int* texUnitIdx); + template <class Proc> + void initSamplers(Proc*, int* texUnitIdx); // A templated helper to loop over effects, set the transforms(via subclass) and bind textures void setFragmentData(const GrOptDrawState&); - virtual void setTransformData(const GrPendingFragmentStage&, - const SkMatrix& localMatrix, + virtual void setTransformData(const GrPrimitiveProcessor*, + const GrPendingFragmentStage&, + int index, GrGLInstalledFragProc*); - void bindTextures(const GrGLInstalledProc*, const GrProcessor&); + template <class Proc> + void bindTextures(const Proc*, const GrProcessor&); /* * Legacy NVPR needs a hook here to flush path tex gen settings. @@ -166,28 +168,8 @@ protected: * specialized methods for setting transform data. Both types of NVPR also require setting the * projection matrix through a special function call */ -class GrGLNvprProgramBase : public GrGLProgram { +class GrGLNvprProgram : public GrGLProgram { protected: - GrGLNvprProgramBase(GrGLGpu*, - const GrProgramDesc&, - const BuiltinUniformHandles&, - GrGLuint programID, - const UniformInfoArray&, - GrGLInstalledGeoProc*, - GrGLInstalledXferProc* xferProcessor, - GrGLInstalledFragProcs* fragmentProcessors); - virtual void onSetRenderTargetState(const GrOptDrawState&); - - typedef GrGLProgram INHERITED; -}; - -class GrGLNvprProgram : public GrGLNvprProgramBase { -public: - bool hasVertexShader() const SK_OVERRIDE { return true; } - -private: - typedef GrGLNvprProgramBuilder::SeparableVaryingInfo SeparableVaryingInfo; - typedef GrGLNvprProgramBuilder::SeparableVaryingInfoArray SeparableVaryingInfoArray; GrGLNvprProgram(GrGLGpu*, const GrProgramDesc&, const BuiltinUniformHandles&, @@ -195,50 +177,19 @@ private: const UniformInfoArray&, GrGLInstalledGeoProc*, GrGLInstalledXferProc* xferProcessor, - GrGLInstalledFragProcs* fragmentProcessors, - const SeparableVaryingInfoArray& separableVaryings); - void didSetData(GrGpu::DrawType) SK_OVERRIDE; - virtual void setTransformData(const GrPendingFragmentStage&, - const SkMatrix& localMatrix, - GrGLInstalledFragProc*) SK_OVERRIDE; - - struct Varying { - GrGLint fLocation; - SkDEBUGCODE( - GrSLType fType; - ); - }; - SkTArray<Varying, true> fVaryings; - - friend class GrGLNvprProgramBuilder; - - typedef GrGLNvprProgramBase INHERITED; -}; - -class GrGLLegacyNvprProgram : public GrGLNvprProgramBase { -public: - bool hasVertexShader() const SK_OVERRIDE { return false; } + GrGLInstalledFragProcs* fragmentProcessors); private: - GrGLLegacyNvprProgram(GrGLGpu* gpu, - const GrProgramDesc& desc, - const BuiltinUniformHandles&, - GrGLuint programID, - const UniformInfoArray&, - GrGLInstalledGeoProc*, - GrGLInstalledXferProc* xp, - GrGLInstalledFragProcs* fps, - int texCoordSetCnt); void didSetData(GrGpu::DrawType) SK_OVERRIDE; - virtual void setTransformData(const GrPendingFragmentStage&, - const SkMatrix& localMatrix, + virtual void setTransformData(const GrPrimitiveProcessor*, + const GrPendingFragmentStage&, + int index, GrGLInstalledFragProc*) SK_OVERRIDE; + virtual void onSetRenderTargetState(const GrOptDrawState&); - int fTexCoordSetCnt; - - friend class GrGLLegacyNvprProgramBuilder; + friend class GrGLNvprProgramBuilder; - typedef GrGLNvprProgramBase INHERITED; + typedef GrGLProgram INHERITED; }; #endif diff --git a/src/gpu/gl/GrGLProgramDataManager.h b/src/gpu/gl/GrGLProgramDataManager.h index 31f7f2e15b..f893d181ec 100644 --- a/src/gpu/gl/GrGLProgramDataManager.h +++ b/src/gpu/gl/GrGLProgramDataManager.h @@ -54,6 +54,7 @@ public: friend class GrGLProgramDataManager; // For accessing toProgramDataIndex(). friend class GrGLProgramBuilder; // For accessing toShaderBuilderIndex(). + friend class GrGLGeometryProcessor; }; struct UniformInfo { diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp index d5dc84c65b..631cf42adc 100644 --- a/src/gpu/gl/GrGLProgramDesc.cpp +++ b/src/gpu/gl/GrGLProgramDesc.cpp @@ -40,62 +40,6 @@ static bool swizzle_requires_alpha_remapping(const GrGLCaps& caps, return false; } -/** - * The key for an individual coord transform is made up of a matrix type, a precision, and a bit - * that indicates the source of the input coords. - */ -enum { - kMatrixTypeKeyBits = 1, - kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1, - - kPrecisionBits = 2, - kPrecisionShift = kMatrixTypeKeyBits, - - kPositionCoords_Flag = (1 << (kPrecisionShift + kPrecisionBits)), - kDeviceCoords_Flag = kPositionCoords_Flag + kPositionCoords_Flag, - - kTransformKeyBits = kMatrixTypeKeyBits + kPrecisionBits + 2, -}; - -GR_STATIC_ASSERT(kHigh_GrSLPrecision < (1 << kPrecisionBits)); - -/** - * We specialize the vertex code for each of these matrix types. - */ -enum MatrixType { - kNoPersp_MatrixType = 0, - kGeneral_MatrixType = 1, -}; - -static uint32_t gen_transform_key(const GrPendingFragmentStage& stage, bool useExplicitLocalCoords) { - uint32_t totalKey = 0; - int numTransforms = stage.processor()->numTransforms(); - for (int t = 0; t < numTransforms; ++t) { - uint32_t key = 0; - if (stage.isPerspectiveCoordTransform(t)) { - key |= kGeneral_MatrixType; - } else { - key |= kNoPersp_MatrixType; - } - - const GrCoordTransform& coordTransform = stage.processor()->coordTransform(t); - if (kLocal_GrCoordSet == coordTransform.sourceCoords() && !useExplicitLocalCoords) { - key |= kPositionCoords_Flag; - } else if (kDevice_GrCoordSet == coordTransform.sourceCoords()) { - key |= kDeviceCoords_Flag; - } - - GR_STATIC_ASSERT(kGrSLPrecisionCount <= (1 << kPrecisionBits)); - key |= (coordTransform.precision() << kPrecisionShift); - - key <<= kTransformKeyBits * t; - - SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to overlap - totalKey |= key; - } - return totalKey; -} - static uint32_t gen_texture_key(const GrProcessor& proc, const GrGLCaps& caps) { uint32_t key = 0; int numTextures = proc.numTextures(); @@ -152,8 +96,6 @@ bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState, // bindings in use or other descriptor field settings) it should be set // to a canonical value to avoid duplicate programs with different keys. - bool requiresLocalCoordAttrib = descInfo.fRequiresLocalCoordAttrib; - GR_STATIC_ASSERT(0 == kProcessorKeysOffset % sizeof(uint32_t)); // Make room for everything up to the effect keys. desc->fKey.reset(); @@ -172,8 +114,7 @@ bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState, const GrPendingFragmentStage& fps = optState.getFragmentStage(s); const GrFragmentProcessor& fp = *fps.processor(); fp.getGLProcessorKey(gpu->glCaps(), &b); - if (!get_meta_key(fp, gpu->glCaps(), - gen_transform_key(fps, requiresLocalCoordAttrib), &b)) { + if (!get_meta_key(fp, gpu->glCaps(), primProc.getTransformKey(fp.coordTransforms()), &b)) { desc->fKey.reset(); return false; } @@ -197,7 +138,6 @@ bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState, bool isPathRendering = GrGpu::IsPathRenderingDrawType(drawType); if (gpu->caps()->pathRenderingSupport() && isPathRendering) { header->fUseNvpr = true; - SkASSERT(!optState.hasGeometryProcessor()); } else { header->fUseNvpr = false; } diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h index 8e8a008e00..688bbe6269 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h @@ -48,6 +48,8 @@ public: virtual const char* fragmentPosition() = 0; private: + friend class GrGLNormalPathProcessor; + typedef GrGLShaderBuilder INHERITED; }; @@ -153,7 +155,6 @@ private: bool fHasReadDstColor; bool fHasReadFragmentPosition; - friend class GrGLNvprProgramBuilder; friend class GrGLProgramBuilder; typedef GrGLFPFragmentBuilder INHERITED; diff --git a/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp b/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp deleted file mode 100644 index e8b4075b03..0000000000 --- a/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp +++ /dev/null @@ -1,50 +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. - */ - -#include "GrGLLegacyNvprProgramBuilder.h" -#include "../GrGLGpu.h" - -GrGLLegacyNvprProgramBuilder::GrGLLegacyNvprProgramBuilder(GrGLGpu* gpu, - const GrOptDrawState& optState) - : INHERITED(gpu, optState) - , fTexCoordSetCnt(0) { -} - -int GrGLLegacyNvprProgramBuilder::addTexCoordSets(int count) { - int firstFreeCoordSet = fTexCoordSetCnt; - fTexCoordSetCnt += count; - SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fTexCoordSetCnt); - return firstFreeCoordSet; -} - -void GrGLLegacyNvprProgramBuilder::emitTransforms(const GrPendingFragmentStage& processorStage, - GrGLProcessor::TransformedCoordsArray* outCoords, - GrGLInstalledFragProc* ifp) { - int numTransforms = processorStage.processor()->numTransforms(); - int texCoordIndex = this->addTexCoordSets(numTransforms); - - // Use the first uniform location as the texcoord index. This may seem a bit hacky but it - // allows us to use one program effects object for all of our programs which really simplifies - // the code overall - ifp->fTransforms.push_back_n(1); - ifp->fTransforms[0].fHandle = GrGLInstalledFragProc::ShaderVarHandle(texCoordIndex); - - SkString name; - for (int t = 0; t < numTransforms; ++t) { - GrSLType type = processorStage.isPerspectiveCoordTransform(t) ? kVec3f_GrSLType : - kVec2f_GrSLType; - - name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCoordIndex++); - SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, (name, type)); - } -} - -GrGLProgram* GrGLLegacyNvprProgramBuilder::createProgram(GrGLuint programID) { - return SkNEW_ARGS(GrGLLegacyNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms, - fGeometryProcessor, fXferProcessor, fFragmentProcessors.get(), - fTexCoordSetCnt)); -} diff --git a/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.h b/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.h deleted file mode 100644 index 519e87aa09..0000000000 --- a/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.h +++ /dev/null @@ -1,30 +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 GrGLLegacyNvprProgramBuilder_DEFINED -#define GrGLLegacyNvprProgramBuilder_DEFINED - -#include "GrGLProgramBuilder.h" - -class GrGLLegacyNvprProgramBuilder : public GrGLProgramBuilder { -public: - GrGLLegacyNvprProgramBuilder(GrGLGpu*, const GrOptDrawState&); - - GrGLProgram* createProgram(GrGLuint programID) SK_OVERRIDE; - -private: - int addTexCoordSets(int count); - void emitTransforms(const GrPendingFragmentStage&, - GrGLProcessor::TransformedCoordsArray* outCoords, - GrGLInstalledFragProc*) SK_OVERRIDE; - - int fTexCoordSetCnt; - - typedef GrGLProgramBuilder INHERITED; -}; - -#endif diff --git a/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp b/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp deleted file mode 100644 index e50037d098..0000000000 --- a/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp +++ /dev/null @@ -1,78 +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. - */ - -#include "GrGLNvprProgramBuilder.h" -#include "../GrGLGpu.h" - -#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) - -GrGLNvprProgramBuilder::GrGLNvprProgramBuilder(GrGLGpu* gpu, - const GrOptDrawState& optState) - : INHERITED(gpu, optState) - , fSeparableVaryingInfos(kVarsPerBlock) { -} - -void GrGLNvprProgramBuilder::emitTransforms(const GrPendingFragmentStage& processorStage, - GrGLProcessor::TransformedCoordsArray* outCoords, - GrGLInstalledFragProc* ifp) { - const GrFragmentProcessor* effect = processorStage.processor(); - int numTransforms = effect->numTransforms(); - - ifp->fTransforms.push_back_n(numTransforms); - - for (int t = 0; t < numTransforms; t++) { - GrSLType varyingType = - processorStage.isPerspectiveCoordTransform(t) ? - kVec3f_GrSLType : - kVec2f_GrSLType; - - const char* varyingName = "MatrixCoord"; - SkString suffixedVaryingName; - if (0 != t) { - suffixedVaryingName.append(varyingName); - suffixedVaryingName.appendf("_%i", t); - varyingName = suffixedVaryingName.c_str(); - } - GrGLVertToFrag v(varyingType); - ifp->fTransforms[t].fHandle = this->addSeparableVarying(varyingName, &v); - ifp->fTransforms[t].fType = varyingType; - - SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, - (SkString(v.fsIn()), varyingType)); - } -} - -GrGLInstalledFragProc::ShaderVarHandle -GrGLNvprProgramBuilder::addSeparableVarying(const char* name, GrGLVarying* v) { - this->addVarying(name, v); - SeparableVaryingInfo& varying = fSeparableVaryingInfos.push_back(); - varying.fVariable = fFS.fInputs.back(); - return GrGLInstalledFragProc::ShaderVarHandle(fSeparableVaryingInfos.count() - 1); -} - -void GrGLNvprProgramBuilder::resolveSeparableVaryings(GrGLuint programId) { - int count = fSeparableVaryingInfos.count(); - for (int i = 0; i < count; ++i) { - GrGLint location; - GL_CALL_RET(location, - GetProgramResourceLocation(programId, - GR_GL_FRAGMENT_INPUT, - fSeparableVaryingInfos[i].fVariable.c_str())); - fSeparableVaryingInfos[i].fLocation = location; - } -} - -GrGLProgram* GrGLNvprProgramBuilder::createProgram(GrGLuint programID) { - // this is just for nvpr es, which has separable varyings that are plugged in after - // building - this->resolveSeparableVaryings(programID); - return SkNEW_ARGS(GrGLNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms, - fGeometryProcessor, - fXferProcessor, fFragmentProcessors.get(), - fSeparableVaryingInfos)); -} diff --git a/src/gpu/gl/builders/GrGLNvprProgramBuilder.h b/src/gpu/gl/builders/GrGLNvprProgramBuilder.h deleted file mode 100644 index 83a35586f9..0000000000 --- a/src/gpu/gl/builders/GrGLNvprProgramBuilder.h +++ /dev/null @@ -1,53 +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 GrGLNvprProgramBuilder_DEFINED -#define GrGLNvprProgramBuilder_DEFINED - -#include "GrGLProgramBuilder.h" - -class GrGLNvprProgramBuilder : public GrGLProgramBuilder { -public: - GrGLNvprProgramBuilder(GrGLGpu*, const GrOptDrawState&); - - /* - * The separable varying info must be passed to GrGLProgram so this must - * be part of the public interface - */ - struct SeparableVaryingInfo { - GrGLShaderVar fVariable; - GrGLint fLocation; - }; - - typedef GrTAllocator<SeparableVaryingInfo> SeparableVaryingInfoArray; - - GrGLProgram* createProgram(GrGLuint programID) SK_OVERRIDE; - -private: - virtual void emitTransforms(const GrPendingFragmentStage&, - GrGLProcessor::TransformedCoordsArray* outCoords, - GrGLInstalledFragProc*) SK_OVERRIDE; - - typedef GrGLInstalledFragProc::ShaderVarHandle ShaderVarHandle; - - /** - * Add a separable varying input variable to the current program. - * A separable varying (fragment shader input) is a varying that can be used also when vertex - * shaders are not used. With a vertex shader, the operation is same as with other - * varyings. Without a vertex shader, such as with NV_path_rendering, GL APIs are used to - * populate the variable. The APIs can refer to the variable through the returned handle. - */ - ShaderVarHandle addSeparableVarying(const char* name, GrGLVarying* v); - - void resolveSeparableVaryings(GrGLuint programId); - - SeparableVaryingInfoArray fSeparableVaryingInfos; - - typedef GrGLProgramBuilder INHERITED; -}; - -#endif diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp index 0c41781979..147723b9d3 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; diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h index fd1d6c8041..37e678fefb 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLProgramBuilder.h @@ -89,6 +89,7 @@ public: const char* gsIn() const { return fGsIn; } const char* gsOut() const { return fGsOut; } const char* fsIn() const { return fFsIn; } + GrSLType type() const { return fType; } protected: enum Varying { @@ -181,11 +182,31 @@ public: * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE */ }; -struct GrGLInstalledProc; -struct GrGLInstalledGeoProc; -struct GrGLInstalledXferProc; -struct GrGLInstalledFragProc; -struct GrGLInstalledFragProcs; + +/** + * The below struct represent processors installed in programs. + */ +template <class Proc> +struct GrGLInstalledProc { + typedef GrGLProgramDataManager::UniformHandle UniformHandle; + + struct Sampler { + SkDEBUGCODE(Sampler() : fTextureUnit(-1) {}) + UniformHandle fUniform; + int fTextureUnit; + }; + SkSTArray<4, Sampler, true> fSamplers; + SkAutoTDelete<Proc> fGLProc; +}; + +typedef GrGLInstalledProc<GrGLPrimitiveProcessor> GrGLInstalledGeoProc; +typedef GrGLInstalledProc<GrGLXferProcessor> GrGLInstalledXferProc; +typedef GrGLInstalledProc<GrGLFragmentProcessor> GrGLInstalledFragProc; + +struct GrGLInstalledFragProcs : public SkRefCnt { + virtual ~GrGLInstalledFragProcs(); + SkSTArray<8, GrGLInstalledFragProc*, true> fProcs; +}; /* * Please note - no diamond problems because of virtual inheritance. Also, both base classes @@ -256,9 +277,7 @@ protected: typedef GrGLProgramDataManager::UniformInfo UniformInfo; typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray; - static GrGLProgramBuilder* CreateProgramBuilder(const GrOptDrawState&, - bool hasGeometryProcessor, - GrGLGpu*); + static GrGLProgramBuilder* CreateProgramBuilder(const GrOptDrawState&, GrGLGpu*); GrGLProgramBuilder(GrGLGpu*, const GrOptDrawState&); @@ -287,6 +306,7 @@ protected: // these emit functions help to keep the createAndEmitProcessors template general void emitAndInstallProc(const GrPendingFragmentStage&, + int index, const char* outColor, const char* inColor); void emitAndInstallProc(const GrPrimitiveProcessor&, @@ -299,14 +319,11 @@ protected: void verify(const GrPrimitiveProcessor&); void verify(const GrXferProcessor&); void verify(const GrFragmentProcessor&); + template <class Proc> void emitSamplers(const GrProcessor&, GrGLProcessor::TextureSamplerArray* outSamplers, - GrGLInstalledProc*); + GrGLInstalledProc<Proc>*); - // each specific program builder has a distinct transform and must override this function - virtual void emitTransforms(const GrPendingFragmentStage&, - GrGLProcessor::TransformedCoordsArray* outCoords, - GrGLInstalledFragProc*); GrGLProgram* finalize(); void bindUniformLocations(GrGLuint programID); bool checkLinkStatus(GrGLuint programID); @@ -350,14 +367,6 @@ protected: void enterStage() { fOutOfStage = false; } int stageIndex() const { return fStageIndex; } - struct TransformVarying { - TransformVarying(const GrGLVarying& v, const char* uniName, GrCoordSet coordSet) - : fV(v), fUniName(uniName), fCoordSet(coordSet) {} - GrGLVarying fV; - SkString fUniName; - GrCoordSet fCoordSet; - }; - const char* rtAdjustment() const { return "rtAdjustment"; } // number of each input/output type in a single allocation block, used by many builders @@ -378,68 +387,12 @@ protected: const GrProgramDesc& fDesc; GrGLGpu* fGpu; UniformInfoArray fUniforms; - SkSTArray<16, TransformVarying, true> fCoordVaryings; + GrGLPrimitiveProcessor::TransformsIn fCoordTransforms; + GrGLPrimitiveProcessor::TransformsOut fOutCoords; friend class GrGLShaderBuilder; friend class GrGLVertexBuilder; friend class GrGLFragmentShaderBuilder; friend class GrGLGeometryBuilder; }; - -/** - * The below structs represent processors installed in programs. All processors can have texture - * samplers, but only frag processors have coord transforms, hence the need for different structs - */ -struct GrGLInstalledProc { - typedef GrGLProgramDataManager::UniformHandle UniformHandle; - - struct Sampler { - SkDEBUGCODE(Sampler() : fTextureUnit(-1) {}) - UniformHandle fUniform; - int fTextureUnit; - }; - SkSTArray<4, Sampler, true> fSamplers; -}; - -struct GrGLInstalledGeoProc : public GrGLInstalledProc { - SkAutoTDelete<GrGLGeometryProcessor> fGLProc; -}; - -struct GrGLInstalledXferProc : public GrGLInstalledProc { - SkAutoTDelete<GrGLXferProcessor> fGLProc; -}; - -struct GrGLInstalledFragProc : public GrGLInstalledProc { - GrGLInstalledFragProc() : fGLProc(NULL) {} - class ShaderVarHandle { - public: - bool isValid() const { return fHandle > -1; } - ShaderVarHandle() : fHandle(-1) {} - ShaderVarHandle(int value) : fHandle(value) { SkASSERT(this->isValid()); } - int handle() const { SkASSERT(this->isValid()); return fHandle; } - UniformHandle convertToUniformHandle() { - SkASSERT(this->isValid()); - return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fHandle); - } - - private: - int fHandle; - }; - - struct Transform { - Transform() : fType(kVoid_GrSLType) { fCurrentValue = SkMatrix::InvalidMatrix(); } - ShaderVarHandle fHandle; - SkMatrix fCurrentValue; - GrSLType fType; - }; - - SkAutoTDelete<GrGLFragmentProcessor> fGLProc; - SkSTArray<2, Transform, true> fTransforms; -}; - -struct GrGLInstalledFragProcs : public SkRefCnt { - virtual ~GrGLInstalledFragProcs(); - SkSTArray<8, GrGLInstalledFragProc*, true> fProcs; -}; - #endif diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp index fd79abbeb5..ead0edfaea 100644 --- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp @@ -35,52 +35,23 @@ void GrGLVertexBuilder::emitAttributes(const GrGeometryProcessor& gp) { return; } -void GrGLVertexBuilder::transformToNormalizedDeviceSpace() { +void GrGLVertexBuilder::transformToNormalizedDeviceSpace(const char* pos3) { + SkASSERT(!fRtAdjustName); + // setup RT Uniform fProgramBuilder->fUniformHandles.fRTAdjustmentUni = fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility, kVec4f_GrSLType, kDefault_GrSLPrecision, fProgramBuilder->rtAdjustment(), &fRtAdjustName); - // Wire transforms - SkTArray<GrGLProgramBuilder::TransformVarying, true>& transVs = fProgramBuilder->fCoordVaryings; - int transformCount = transVs.count(); - for (int i = 0; i < transformCount; i++) { - GrCoordSet coordSet = transVs[i].fCoordSet; - const char* coords = NULL; - switch (coordSet) { - case kLocal_GrCoordSet: - coords = this->localCoords(); - break; - case kDevice_GrCoordSet: - coords = this->glPosition(); - break; - } - - // varying = matrix * coords (logically) - const GrGLVarying& v = transVs[i].fV; - if (kDevice_GrCoordSet == coordSet) { - if (kVec2f_GrSLType == v.fType) { - this->codeAppendf("%s = (%s * %s).xy;", v.fVsOut, transVs[i].fUniName.c_str(), - coords); - } else { - this->codeAppendf("%s = %s * %s;", v.fVsOut, transVs[i].fUniName.c_str(), coords); - } - } else { - if (kVec2f_GrSLType == v.fType) { - this->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.fVsOut, transVs[i].fUniName.c_str(), - coords); - } else { - this->codeAppendf("%s = %s * vec3(%s, 1);", v.fVsOut, transVs[i].fUniName.c_str(), - coords); - } - } - } // Transform from Skia's device coords to GL's normalized device coords. this->codeAppendf("gl_Position = vec4(dot(%s.xz, %s.xy), dot(%s.yz, %s.zw), 0, %s.z);", - this->glPosition(), fRtAdjustName, this->glPosition(), fRtAdjustName, - this->glPosition()); + pos3, fRtAdjustName, pos3, fRtAdjustName, pos3); + + // We could have the GrGeometryProcessor do this, but its just easier to have it performed here. + // If we ever need to set variable pointsize, then we can reinvestigate + this->codeAppend("gl_PointSize = 1.0;"); } void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) { diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h index ba978a8beb..da094b507f 100644 --- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h @@ -16,10 +16,8 @@ class GrGLVertexBuilder : public GrGLShaderBuilder { public: GrGLVertexBuilder(GrGLProgramBuilder* program); - /** returns the expected position output */ - const char* glPosition() const { return "pos3"; } - const char* positionCoords() const { return "position"; } - const char* localCoords() const { return "localCoords"; } + void transformToNormalizedDeviceSpace(const char* pos3); + void emitAttributes(const GrGeometryProcessor& gp); void addAttribute(const GrGeometryProcessor::GrAttribute* attr) { this->addAttribute(GrShaderVar(attr->fName, @@ -36,8 +34,6 @@ private: /* * private helpers for compilation by GrGLProgramBuilder */ - void transformToNormalizedDeviceSpace(); - void emitAttributes(const GrGeometryProcessor& gp); void bindVertexAttributes(GrGLuint programID); bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const; |