Move most of the transform logic into the primitive processors
BUG=skia:
Review URL: https://codereview.chromium.org/822423004
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 5be7f4b..90896b3 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 fe6e6fa..341b3fb 100644
--- a/include/gpu/GrFragmentProcessor.h
+++ b/include/gpu/GrFragmentProcessor.h
@@ -47,6 +47,10 @@
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 784f685..0690175 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -535,11 +535,14 @@
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 @@
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 @@
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 49c663d..a6eaa6d 100644
--- a/src/gpu/GrDefaultGeoProcFactory.cpp
+++ b/src/gpu/GrDefaultGeoProcFactory.cpp
@@ -83,33 +83,37 @@
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 @@
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 6bd6b2b..e8ffc7b 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 @@
#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::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::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 @@
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) {}
+ GrGLLegacyPathProcessor(const GrPathProcessor& pathProc, const GrBatchTracker& bt,
+ int maxTexCoords)
+ : INHERITED(pathProc, bt)
+ , fMaxTexCoords(maxTexCoords)
+ , fTexCoordSetCnt(0) {}
- void emitCode(const EmitArgs& args) SK_OVERRIDE {
- GrGLGPBuilder* pb = args.fPB;
- GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
- const PathBatchTracker& local = args.fBT.cast<PathBatchTracker>();
+ int addTexCoordSets(int count) {
+ int firstFreeCoordSet = fTexCoordSetCnt;
+ fTexCoordSetCnt += count;
+ SkASSERT(fMaxTexCoords >= fTexCoordSetCnt);
+ return firstFreeCoordSet;
+ }
- // 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);
- }
+ 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());
- // setup constant solid coverage
- if (kAllOnes_GrGPInput == local.fInputCoverageType) {
- fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
+ // 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));
+ }
}
}
- 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 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 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 didSetData(GrGLPathRendering* glpr) SK_OVERRIDE {
+ glpr->flushPathTexGenSettings(fTexCoordSetCnt);
+ }
+
+private:
+ 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 {
+ 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));
+ }
+ }
+ }
+
+ 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 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 @@
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 ad75d23..074fffc 100644
--- a/src/gpu/GrGeometryProcessor.h
+++ b/src/gpu/GrGeometryProcessor.h
@@ -66,7 +66,7 @@
};
class GrGLCaps;
-class GrGLGeometryProcessor;
+class GrGLPrimitiveProcessor;
class GrOptDrawState;
struct GrInitInvariantOutput;
@@ -122,6 +122,11 @@
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 @@
/** 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 @@
}
private:
+ virtual bool hasExplicitLocalCoords() const = 0;
+
SkMatrix fViewMatrix;
SkMatrix fLocalMatrix;
@@ -261,7 +269,6 @@
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 @@
// 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 @@
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 @@
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;
+
+protected:
+ GrPathProcessor(GrColor color, const SkMatrix& viewMatrix, const SkMatrix& localMatrix);
private:
- GrPathProcessor(GrColor color, const SkMatrix& viewMatrix, const SkMatrix& localMatrix);
+ 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 2365f1e..f9febf4 100644
--- a/src/gpu/GrOptDrawState.cpp
+++ b/src/gpu/GrOptDrawState.cpp
@@ -87,9 +87,6 @@
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 @@
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 7f93bbe..b5f3f5a 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -83,12 +83,15 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 9ba20aa..e07e116 100644
--- a/src/gpu/GrProgramDesc.h
+++ b/src/gpu/GrProgramDesc.h
@@ -83,8 +83,7 @@
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 @@
// programs.
bool fReadsDst;
bool fReadsFragPosition;
- bool fRequiresLocalCoordAttrib;
};
private:
diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp
index e16601d..f674345 100644
--- a/src/gpu/effects/GrBezierEffect.cpp
+++ b/src/gpu/effects/GrBezierEffect.cpp
@@ -24,7 +24,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 f31542f..86f09bc 100644
--- a/src/gpu/effects/GrBezierEffect.h
+++ b/src/gpu/effects/GrBezierEffect.h
@@ -102,7 +102,8 @@
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 @@
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 @@
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 1cfb644..0818fc0 100644
--- a/src/gpu/effects/GrBitmapTextGeoProc.cpp
+++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp
@@ -25,13 +25,16 @@
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 @@
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 @@
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 85e4f42..399678a 100644
--- a/src/gpu/effects/GrBitmapTextGeoProc.h
+++ b/src/gpu/effects/GrBitmapTextGeoProc.h
@@ -40,7 +40,8 @@
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 8b69dca..2543145 100644
--- a/src/gpu/effects/GrDashingEffect.cpp
+++ b/src/gpu/effects/GrDashingEffect.cpp
@@ -496,7 +496,8 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 cdb6ff7..24fe001 100755
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
@@ -35,7 +35,7 @@
#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 @@
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,15 +60,13 @@
// 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);
- // setup output coords
- vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(),
- dfTexEffect.inPosition()->fName);
- vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(),
- 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,
@@ -242,8 +244,9 @@
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 @@
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 @@
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 @@
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 @@
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 @@
, 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 @@
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 @@
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 6edcf98..2fb448b 100644
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.h
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.h
@@ -80,7 +80,8 @@
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 @@
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 @@
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 376bfd4..73df30b 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -25,6 +25,7 @@
fMSFBOType = kNone_MSFBOType;
fInvalidateFBType = kNone_InvalidateFBType;
fLATCAlias = kLATC_LATCAlias;
+ fNvprSupport = kNone_NvprSupport;
fMapBufferType = kNone_MapBufferType;
fMaxFragmentUniformVectors = 0;
fMaxVertexAttributes = 0;
@@ -67,6 +68,7 @@
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 @@
((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 77baf38..527cd33 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -286,6 +286,18 @@
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 @@
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 0b24144..524cdf3 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 @@
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;
+};
- typedef GrGLProcessor INHERITED;
+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 GrGLPrimitiveProcessor INHERITED;
};
#endif
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 9400e54..1af3e56 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 @@
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::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::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 @@
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 @@
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 @@
/////////////////////////////////////////////////////////////////////////////////////////
-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 @@
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 e70fee7..d18a92d 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 @@
// 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 @@
* 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 @@
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;
+ GrGLInstalledFragProcs* fragmentProcessors);
- struct Varying {
- GrGLint fLocation;
- SkDEBUGCODE(
- GrSLType fType;
- );
- };
- SkTArray<Varying, true> fVaryings;
+private:
+ void didSetData(GrGpu::DrawType) SK_OVERRIDE;
+ virtual void setTransformData(const GrPrimitiveProcessor*,
+ const GrPendingFragmentStage&,
+ int index,
+ GrGLInstalledFragProc*) SK_OVERRIDE;
+ virtual void onSetRenderTargetState(const GrOptDrawState&);
friend class GrGLNvprProgramBuilder;
- typedef GrGLNvprProgramBase INHERITED;
-};
-
-class GrGLLegacyNvprProgram : public GrGLNvprProgramBase {
-public:
- bool hasVertexShader() const SK_OVERRIDE { return false; }
-
-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,
- GrGLInstalledFragProc*) SK_OVERRIDE;
-
- int fTexCoordSetCnt;
-
- friend class GrGLLegacyNvprProgramBuilder;
-
- typedef GrGLNvprProgramBase INHERITED;
+ typedef GrGLProgram INHERITED;
};
#endif
diff --git a/src/gpu/gl/GrGLProgramDataManager.h b/src/gpu/gl/GrGLProgramDataManager.h
index 31f7f2e..f893d18 100644
--- a/src/gpu/gl/GrGLProgramDataManager.h
+++ b/src/gpu/gl/GrGLProgramDataManager.h
@@ -54,6 +54,7 @@
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 d5dc84c..631cf42 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -40,62 +40,6 @@
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 @@
// 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 @@
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 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 8e8a008..688bbe6 100644
--- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
@@ -48,6 +48,8 @@
virtual const char* fragmentPosition() = 0;
private:
+ friend class GrGLNormalPathProcessor;
+
typedef GrGLShaderBuilder INHERITED;
};
@@ -153,7 +155,6 @@
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 e8b4075..0000000
--- 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 519e87a..0000000
--- 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 e50037d..0000000
--- 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 83a3558..0000000
--- 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 0c41781..147723b 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 @@
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 @@
}
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 @@
}
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 @@
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 @@
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 GrPendingFragmentStage& fs,
+ int index,
const char* outColor,
const char* inColor) {
GrGLInstalledFragProc* ifp = SkNEW(GrGLInstalledFragProc);
@@ -281,11 +288,7 @@
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 @@
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 @@
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 fd1d6c8..37e678f 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -89,6 +89,7 @@
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 @@
* *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 @@
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 @@
// 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 @@
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 @@
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 @@
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 fd79abb..ead0edf 100644
--- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
@@ -35,52 +35,23 @@
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 ba978a8..da094b5 100644
--- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
@@ -16,10 +16,8 @@
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 helpers for compilation by GrGLProgramBuilder
*/
- void transformToNormalizedDeviceSpace();
- void emitAttributes(const GrGeometryProcessor& gp);
void bindVertexAttributes(GrGLuint programID);
bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;