Index: src/gpu/gl/GrGLPathProcessor.cpp |
diff --git a/src/gpu/gl/GrGLPathProcessor.cpp b/src/gpu/gl/GrGLPathProcessor.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3f3e5d9be79cac0386c8f702aa1f8e457b31c5ff |
--- /dev/null |
+++ b/src/gpu/gl/GrGLPathProcessor.cpp |
@@ -0,0 +1,183 @@ |
+/* |
+ * Copyright 2013 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "GrGLPathProcessor.h" |
+ |
+#include "GrPathProcessor.h" |
+#include "GrGLGpu.h" |
+#include "GrGLPathRendering.h" |
+ |
+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; |
+ } |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+void GrGLLegacyPathProcessor::emitTransforms(GrGLGPBuilder*, const TransformsIn& tin, |
+ TransformsOut* tout) { |
+ 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 GrGLLegacyPathProcessor::setTransformData( |
+ const GrPrimitiveProcessor& primProc, |
+ int index, |
+ const SkTArray<const GrCoordTransform*, true>& transforms, |
+ GrGLPathRendering* glpr, |
+ GrGLuint) { |
+ // 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 GrGLLegacyPathProcessor::didSetData(GrGLPathRendering* glpr) { |
+ glpr->flushPathTexGenSettings(fTexCoordSetCnt); |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+void GrGLNormalPathProcessor::emitTransforms(GrGLGPBuilder* pb, const TransformsIn& tin, |
+ TransformsOut* tout) { |
+ 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; |
+ |
+ |
+ SkString strVaryingName("MatrixCoord"); |
+ strVaryingName.appendf("_%i_%i", i, t); |
+ GrGLVertToFrag v(varyingType); |
+ pb->addVarying(strVaryingName.c_str(), &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)); |
+ } |
+ } |
+} |
+ |
+void GrGLNormalPathProcessor::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 GrGLNormalPathProcessor::setTransformData( |
+ const GrPrimitiveProcessor& primProc, |
+ int index, |
+ const SkTArray<const GrCoordTransform*, true>& coordTransforms, |
+ GrGLPathRendering* glpr, |
+ GrGLuint programID) { |
+ 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); |
+ } |
+} |