aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@chromium.org>2015-02-12 14:20:52 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-02-12 14:20:52 -0800
commit8072caa80384292858d31ae34b7e19768875866b (patch)
tree540934943305cb0aa1e73bfa836e260cab8b45b0 /src/gpu/gl
parentb0fb935bd544b0c6f68c692c7e1ee40876184a1a (diff)
A simple change to move a bunch of stuff out of Gr*Geometry.h
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLGeometryProcessor.cpp129
-rw-r--r--src/gpu/gl/GrGLGeometryProcessor.h156
-rw-r--r--src/gpu/gl/GrGLPathProcessor.cpp183
-rw-r--r--src/gpu/gl/GrGLPathProcessor.h113
-rw-r--r--src/gpu/gl/GrGLPrimitiveProcessor.cpp75
-rw-r--r--src/gpu/gl/GrGLPrimitiveProcessor.h130
-rw-r--r--src/gpu/gl/GrGLProgram.cpp4
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp7
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.h2
9 files changed, 640 insertions, 159 deletions
diff --git a/src/gpu/gl/GrGLGeometryProcessor.cpp b/src/gpu/gl/GrGLGeometryProcessor.cpp
new file mode 100644
index 0000000000..a8d020a166
--- /dev/null
+++ b/src/gpu/gl/GrGLGeometryProcessor.cpp
@@ -0,0 +1,129 @@
+/*
+ * 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 "GrGLGeometryProcessor.h"
+
+#include "builders/GrGLProgramBuilder.h"
+
+void GrGLGeometryProcessor::emitCode(EmitArgs& args) {
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
+ GrGPArgs gpArgs;
+ this->onEmitCode(args, &gpArgs);
+ vsBuilder->transformToNormalizedDeviceSpace(gpArgs.fPositionVar);
+}
+
+void GrGLGeometryProcessor::emitTransforms(GrGLGPBuilder* pb,
+ const GrShaderVar& posVar,
+ 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) {
+ if (kVec2f_GrSLType == posVar.getType()) {
+ vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
+ v.vsOut(), uniName, posVar.c_str());
+ } else {
+ // The brackets here are just to scope the temp variable
+ vb->codeAppendf("{ vec3 temp = %s * %s;", uniName, posVar.c_str());
+ vb->codeAppendf("%s = vec2(temp.x/temp.z, temp.y/temp.z); }", v.vsOut());
+ }
+ } else {
+ if (kVec2f_GrSLType == posVar.getType()) {
+ vb->codeAppendf("%s = %s * vec3(%s, 1);",
+ v.vsOut(), uniName, posVar.c_str());
+ } else {
+ vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, posVar.c_str());
+ }
+ }
+ } 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;
+ }
+ }
+}
+
+void GrGLGeometryProcessor::SetupPosition(GrGLVertexBuilder* vsBuilder,
+ GrGPArgs* gpArgs,
+ const char* posName,
+ const SkMatrix& mat,
+ const char* matName) {
+ if (mat.isIdentity()) {
+ gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2");
+
+ vsBuilder->codeAppendf("vec2 %s = %s;", gpArgs->fPositionVar.c_str(), posName);
+ } else if (!mat.hasPerspective()) {
+ gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2");
+
+ vsBuilder->codeAppendf("vec2 %s = vec2(%s * vec3(%s, 1));",
+ gpArgs->fPositionVar.c_str(), matName, posName);
+ } else {
+ gpArgs->fPositionVar.set(kVec3f_GrSLType, "pos3");
+
+ vsBuilder->codeAppendf("vec3 %s = %s * vec3(%s, 1);",
+ gpArgs->fPositionVar.c_str(), matName, posName);
+ }
+}
diff --git a/src/gpu/gl/GrGLGeometryProcessor.h b/src/gpu/gl/GrGLGeometryProcessor.h
index da6c347314..e8b16afe33 100644
--- a/src/gpu/gl/GrGLGeometryProcessor.h
+++ b/src/gpu/gl/GrGLGeometryProcessor.h
@@ -8,126 +8,10 @@
#ifndef GrGLGeometryProcessor_DEFINED
#define GrGLGeometryProcessor_DEFINED
-#include "GrGLProcessor.h"
+#include "GrGLPrimitiveProcessor.h"
-class GrBatchTracker;
-class GrFragmentProcessor;
-class GrGLGPBuilder;
-
-class GrGLPrimitiveProcessor {
-public:
- 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 TransformsIn& transformsIn,
- TransformsOut* transformsOut)
- : fPB(pb)
- , fGP(gp)
- , fBT(bt)
- , fOutputColor(outputColor)
- , fOutputCoverage(outputCoverage)
- , 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(EmitArgs&) = 0;
-
-
- /** 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
- * inputType == attribute, then colorAttr must not be NULL. Likewise, if inputType == Uniform
- * then colorUniform must not be NULL.
- */
- void setupColorPassThrough(GrGLGPBuilder* pb,
- GrGPInput inputType,
- const char* inputName,
- const GrGeometryProcessor::Attribute* colorAttr,
- UniformHandle* colorUniform);
-
- const char* uViewM() const { return fViewMatrixName; }
-
- /** a helper function to setup the uniform handle for the uniform view matrix */
- void addUniformViewMatrix(GrGLGPBuilder*);
-
-
- /** a helper function to upload a uniform viewmatrix.
- * TODO we can remove this function when we have deferred geometry in place
- */
- 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;
class GrGLVertexBuilder;
+
/**
* 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
@@ -189,40 +73,4 @@ private:
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 GrGLPrimitiveProcessor INHERITED;
-};
-
#endif
diff --git a/src/gpu/gl/GrGLPathProcessor.cpp b/src/gpu/gl/GrGLPathProcessor.cpp
new file mode 100644
index 0000000000..3f3e5d9be7
--- /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);
+ }
+}
diff --git a/src/gpu/gl/GrGLPathProcessor.h b/src/gpu/gl/GrGLPathProcessor.h
new file mode 100644
index 0000000000..368f1f9fcd
--- /dev/null
+++ b/src/gpu/gl/GrGLPathProcessor.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLPathProcessor_DEFINED
+#define GrGLPathProcessor_DEFINED
+
+#include "GrGLPrimitiveProcessor.h"
+
+class GrPathProcessor;
+class GrGLPathRendering;
+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 GrGLPrimitiveProcessor INHERITED;
+};
+
+class GrGLLegacyPathProcessor : public GrGLPathProcessor {
+public:
+ GrGLLegacyPathProcessor(const GrPathProcessor& pathProc, const GrBatchTracker& bt,
+ int maxTexCoords)
+ : INHERITED(pathProc, bt)
+ , fTexCoordSetCnt(0) {
+ SkDEBUGCODE(fMaxTexCoords = maxTexCoords;)
+ }
+
+ int addTexCoordSets(int count) {
+ int firstFreeCoordSet = fTexCoordSetCnt;
+ fTexCoordSetCnt += count;
+ SkASSERT(fMaxTexCoords >= fTexCoordSetCnt);
+ return firstFreeCoordSet;
+ }
+
+ void emitTransforms(GrGLGPBuilder*, const TransformsIn& tin, TransformsOut* tout) SK_OVERRIDE;
+
+ void setTransformData(const GrPrimitiveProcessor& primProc,
+ int index,
+ const SkTArray<const GrCoordTransform*, true>& transforms,
+ GrGLPathRendering* glpr,
+ GrGLuint) SK_OVERRIDE;
+
+ void didSetData(GrGLPathRendering* glpr) SK_OVERRIDE;
+
+private:
+ SkDEBUGCODE(int fMaxTexCoords;)
+ int fTexCoordSetCnt;
+
+ typedef GrGLPathProcessor INHERITED;
+};
+
+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;
+
+ void resolveSeparableVaryings(GrGLGpu* gpu, GrGLuint programId);
+
+ void setTransformData(const GrPrimitiveProcessor& primProc,
+ int index,
+ const SkTArray<const GrCoordTransform*, true>& coordTransforms,
+ GrGLPathRendering* glpr,
+ GrGLuint programID) SK_OVERRIDE;
+
+private:
+ struct SeparableVaryingInfo {
+ GrSLType fType;
+ GrGLShaderVar fVariable;
+ GrGLint fLocation;
+ };
+
+ typedef SkSTArray<8, SeparableVaryingInfo, true> SeparableVaryingInfoArray;
+
+ SeparableVaryingInfoArray fSeparableVaryingInfos;
+
+ typedef GrGLPathProcessor INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLPrimitiveProcessor.cpp b/src/gpu/gl/GrGLPrimitiveProcessor.cpp
new file mode 100644
index 0000000000..335dc4fe5f
--- /dev/null
+++ b/src/gpu/gl/GrGLPrimitiveProcessor.cpp
@@ -0,0 +1,75 @@
+/*
+ * 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 "GrGLPrimitiveProcessor.h"
+
+#include "builders/GrGLProgramBuilder.h"
+
+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::Attribute* colorAttr,
+ UniformHandle* colorUniform) {
+ GrGLGPFragmentBuilder* fs = pb->getFragmentShaderBuilder();
+ if (kUniform_GrGPInput == inputType) {
+ SkASSERT(colorUniform);
+ const char* stagedLocalVarName;
+ *colorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kVec4f_GrSLType,
+ kDefault_GrSLPrecision,
+ "Color",
+ &stagedLocalVarName);
+ fs->codeAppendf("%s = %s;", outputName, stagedLocalVarName);
+ } else if (kAttribute_GrGPInput == inputType) {
+ SkASSERT(colorAttr);
+ pb->addPassThroughAttribute(colorAttr, outputName);
+ } else if (kAllOnes_GrGPInput == inputType) {
+ fs->codeAppendf("%s = vec4(1);", outputName);
+ }
+}
+
+void GrGLPrimitiveProcessor::addUniformViewMatrix(GrGLGPBuilder* pb) {
+ fViewMatrixUniform = pb->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+ kMat33f_GrSLType, kDefault_GrSLPrecision,
+ "uViewM",
+ &fViewMatrixName);
+}
+
+void GrGLPrimitiveProcessor::setUniformViewMatrix(const GrGLProgramDataManager& pdman,
+ const SkMatrix& viewMatrix) {
+ if (!fViewMatrix.cheapEqualTo(viewMatrix)) {
+ SkASSERT(fViewMatrixUniform.isValid());
+ fViewMatrix = viewMatrix;
+
+ GrGLfloat viewMatrix[3 * 3];
+ GrGLGetMatrix<3>(viewMatrix, fViewMatrix);
+ pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
+ }
+}
diff --git a/src/gpu/gl/GrGLPrimitiveProcessor.h b/src/gpu/gl/GrGLPrimitiveProcessor.h
new file mode 100644
index 0000000000..30b1c178cd
--- /dev/null
+++ b/src/gpu/gl/GrGLPrimitiveProcessor.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLPrimitiveProcessor_DEFINED
+#define GrGLPrimitiveProcessor_DEFINED
+
+#include "GrPrimitiveProcessor.h"
+#include "GrGLProcessor.h"
+
+class GrBatchTracker;
+class GrPrimitiveProcessor;
+class GrGLGPBuilder;
+
+class GrGLPrimitiveProcessor {
+public:
+ 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 TransformsIn& transformsIn,
+ TransformsOut* transformsOut)
+ : fPB(pb)
+ , fGP(gp)
+ , fBT(bt)
+ , fOutputColor(outputColor)
+ , fOutputCoverage(outputCoverage)
+ , 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(EmitArgs&) = 0;
+
+
+ /** 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
+ * inputType == attribute, then colorAttr must not be NULL. Likewise, if inputType == Uniform
+ * then colorUniform must not be NULL.
+ */
+ void setupColorPassThrough(GrGLGPBuilder* pb,
+ GrGPInput inputType,
+ const char* inputName,
+ const GrPrimitiveProcessor::Attribute* colorAttr,
+ UniformHandle* colorUniform);
+
+ const char* uViewM() const { return fViewMatrixName; }
+
+ /** a helper function to setup the uniform handle for the uniform view matrix */
+ void addUniformViewMatrix(GrGLGPBuilder*);
+
+
+ /** a helper function to upload a uniform viewmatrix.
+ * TODO we can remove this function when we have deferred geometry in place
+ */
+ 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;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index eebcf6b2f3..2f6b784b40 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -11,12 +11,12 @@
#include "GrProcessor.h"
#include "GrCoordTransform.h"
#include "GrGLGeometryProcessor.h"
-#include "GrGLProcessor.h"
-#include "GrGLXferProcessor.h"
#include "GrGLGpu.h"
+#include "GrGLPathProcessor.h"
#include "GrGLPathRendering.h"
#include "GrGLShaderVar.h"
#include "GrGLSL.h"
+#include "GrGLXferProcessor.h"
#include "GrPipeline.h"
#include "GrXferProcessor.h"
#include "SkXfermode.h"
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index bb278be395..5a623033fb 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -6,11 +6,14 @@
*/
#include "GrGLProgramBuilder.h"
+
+#include "gl/GrGLGeometryProcessor.h"
+#include "gl/GrGLGpu.h"
+#include "gl/GrGLPathProcessor.h"
#include "gl/GrGLProgram.h"
#include "gl/GrGLSLPrettyPrint.h"
#include "gl/GrGLUniformHandle.h"
-#include "../GrGLXferProcessor.h"
-#include "../GrGLGpu.h"
+#include "gl/GrGLXferProcessor.h"
#include "GrCoordTransform.h"
#include "GrGLProgramBuilder.h"
#include "GrTexture.h"
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index a9288cc9b0..37908f9971 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -13,7 +13,7 @@
#include "GrGLVertexShaderBuilder.h"
#include "../GrGLProgramDataManager.h"
#include "../GrGLUniformHandle.h"
-#include "../GrGLGeometryProcessor.h"
+#include "../GrGLPrimitiveProcessor.h"
#include "../GrGLXferProcessor.h"
#include "../../GrPendingFragmentStage.h"
#include "../../GrPipeline.h"