aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-10-03 15:17:58 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-10-03 15:17:58 +0000
commit3390b9ac9ad69a6e772c2b957d75d19611239025 (patch)
tree39b8dfb8c27086d504a1ecf139120e346efe3b54 /src/gpu
parent17cb562da95ff3bdfdd7b754a8e572e1ff528de6 (diff)
Repurpose GrGLCoordTransform as GrGLProgramEffects
Creates a GrGLProgramEffects class that the GrGLProgram uses to manage an array of effects. This gives us enough abstraction for the program to cleanly handle different types of coord transforms. R=bsalomon@google.com Author: cdalton@nvidia.com Review URL: https://codereview.chromium.org/25605008 git-svn-id: http://skia.googlecode.com/svn/trunk@11588 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/gl/GrGLCoordTransform.cpp188
-rw-r--r--src/gpu/gl/GrGLCoordTransform.h109
-rw-r--r--src/gpu/gl/GrGLEffect.cpp63
-rw-r--r--src/gpu/gl/GrGLEffect.h16
-rw-r--r--src/gpu/gl/GrGLProgram.cpp124
-rw-r--r--src/gpu/gl/GrGLProgram.h41
-rw-r--r--src/gpu/gl/GrGLProgramEffects.cpp414
-rw-r--r--src/gpu/gl/GrGLProgramEffects.h192
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp171
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h112
10 files changed, 706 insertions, 724 deletions
diff --git a/src/gpu/gl/GrGLCoordTransform.cpp b/src/gpu/gl/GrGLCoordTransform.cpp
deleted file mode 100644
index bfbae1e9a3..0000000000
--- a/src/gpu/gl/GrGLCoordTransform.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrGLCoordTransform.h"
-#include "GrDrawEffect.h"
-#include "GrTexture.h"
-#include "GrGLShaderBuilder.h"
-
-GrGLCoordTransform::EffectKey GrGLCoordTransform::GenKey(const GrDrawEffect& drawEffect,
- int transformIdx) {
- const GrCoordTransform& transform = (*drawEffect.effect())->coordTransform(transformIdx);
- EffectKey key = 0;
- SkMatrix::TypeMask type0 = transform.getMatrix().getType();
- SkMatrix::TypeMask type1;
- if (kLocal_GrCoordSet == transform.sourceCoords()) {
- type1 = drawEffect.getCoordChangeMatrix().getType();
- } else {
- if (drawEffect.programHasExplicitLocalCoords()) {
- // We only make the key indicate that device coords are referenced when the local coords
- // are not actually determined by positions. Otherwise the local coords var and position
- // var are identical.
- key |= kPositionCoords_Flag;
- }
- type1 = SkMatrix::kIdentity_Mask;
- }
-
- int combinedTypes = type0 | type1;
-
- bool reverseY = transform.reverseY();
-
- if (SkMatrix::kPerspective_Mask & combinedTypes) {
- key |= kGeneral_MatrixType;
- } else if (((SkMatrix::kAffine_Mask | SkMatrix::kScale_Mask) & combinedTypes) || reverseY) {
- key |= kNoPersp_MatrixType;
- } else if (SkMatrix::kTranslate_Mask & combinedTypes) {
- key |= kTrans_MatrixType;
- } else {
- key |= kIdentity_MatrixType;
- }
- return key;
-}
-
-void GrGLCoordTransform::emitCode(GrGLShaderBuilder* builder,
- EffectKey key,
- TransformedCoords* transformedCoords,
- int suffix) {
- GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
- SkASSERT(NULL != vertexBuilder);
-
- GrSLType varyingType = kVoid_GrSLType;
- const char* uniName;
- switch (key & kMatrixTypeKeyMask) {
- case kIdentity_MatrixType:
- fUniType = kVoid_GrSLType;
- uniName = NULL;
- varyingType = kVec2f_GrSLType;
- break;
- case kTrans_MatrixType:
- fUniType = kVec2f_GrSLType;
- uniName = "StageTranslate";
- varyingType = kVec2f_GrSLType;
- break;
- case kNoPersp_MatrixType:
- fUniType = kMat33f_GrSLType;
- uniName = "StageMatrix";
- varyingType = kVec2f_GrSLType;
- break;
- case kGeneral_MatrixType:
- fUniType = kMat33f_GrSLType;
- uniName = "StageMatrix";
- varyingType = kVec3f_GrSLType;
- break;
- default:
- GrCrash("Unexpected key.");
- }
- SkString suffixedUniName;
- if (kVoid_GrSLType != fUniType) {
- if (0 != suffix) {
- suffixedUniName.append(uniName);
- suffixedUniName.appendf("_%i", suffix);
- uniName = suffixedUniName.c_str();
- }
- fUni = builder->addUniform(GrGLShaderBuilder::kVertex_Visibility,
- fUniType,
- uniName,
- &uniName);
- }
-
- const char* varyingName = "MatrixCoord";
- SkString suffixedVaryingName;
- if (0 != suffix) {
- suffixedVaryingName.append(varyingName);
- suffixedVaryingName.appendf("_%i", suffix);
- varyingName = suffixedVaryingName.c_str();
- }
- const char* vsVaryingName;
- const char* fsVaryingName;
- vertexBuilder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
-
- const GrGLShaderVar& coords = (kPositionCoords_Flag & key) ?
- vertexBuilder->positionAttribute() :
- vertexBuilder->localCoordsAttribute();
- // varying = matrix * coords (logically)
- switch (fUniType) {
- case kVoid_GrSLType:
- SkASSERT(kVec2f_GrSLType == varyingType);
- vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords.c_str());
- break;
- case kVec2f_GrSLType:
- SkASSERT(kVec2f_GrSLType == varyingType);
- vertexBuilder->vsCodeAppendf("\t%s = %s + %s;\n",
- vsVaryingName, uniName, coords.c_str());
- break;
- case kMat33f_GrSLType: {
- SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
- if (kVec2f_GrSLType == varyingType) {
- vertexBuilder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n",
- vsVaryingName, uniName, coords.c_str());
- } else {
- vertexBuilder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n",
- vsVaryingName, uniName, coords.c_str());
- }
- break;
- }
- default:
- GrCrash("Unexpected uniform type.");
- }
- SkASSERT(NULL != transformedCoords);
- transformedCoords->fName = fsVaryingName;
- transformedCoords->fType = varyingType;
- transformedCoords->fVSName = vsVaryingName;
-}
-
-void GrGLCoordTransform::setData(const GrGLUniformManager& uniformManager,
- const GrDrawEffect& drawEffect,
- int transformIdx) {
- SkASSERT(fUni.isValid() != (kVoid_GrSLType == fUniType));
- const GrCoordTransform& transform = (*drawEffect.effect())->coordTransform(transformIdx);
- const SkMatrix& matrix = transform.getMatrix();
- const SkMatrix& coordChangeMatrix = kLocal_GrCoordSet == transform.sourceCoords() ?
- drawEffect.getCoordChangeMatrix() :
- SkMatrix::I();
- switch (fUniType) {
- case kVoid_GrSLType:
- SkASSERT(matrix.isIdentity());
- SkASSERT(coordChangeMatrix.isIdentity());
- SkASSERT(!transform.reverseY());
- return;
- case kVec2f_GrSLType: {
- SkASSERT(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChangeMatrix.getType()));
- SkASSERT(!transform.reverseY());
- SkScalar tx = matrix[SkMatrix::kMTransX] + (coordChangeMatrix)[SkMatrix::kMTransX];
- SkScalar ty = matrix[SkMatrix::kMTransY] + (coordChangeMatrix)[SkMatrix::kMTransY];
- if (fPrevMatrix.get(SkMatrix::kMTransX) != tx ||
- fPrevMatrix.get(SkMatrix::kMTransY) != ty) {
- uniformManager.set2f(fUni, tx, ty);
- fPrevMatrix.set(SkMatrix::kMTransX, tx);
- fPrevMatrix.set(SkMatrix::kMTransY, ty);
- }
- break;
- }
- case kMat33f_GrSLType: {
- SkMatrix combined;
- combined.setConcat(matrix, coordChangeMatrix);
- if (transform.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]);
- }
- if (!fPrevMatrix.cheapEqualTo(combined)) {
- uniformManager.setSkMatrix(fUni, combined);
- fPrevMatrix = combined;
- }
- break;
- }
- default:
- GrCrash("Unexpected uniform type.");
- }
-}
diff --git a/src/gpu/gl/GrGLCoordTransform.h b/src/gpu/gl/GrGLCoordTransform.h
deleted file mode 100644
index cd2f38a028..0000000000
--- a/src/gpu/gl/GrGLCoordTransform.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrGLCoordTransform_DEFINED
-#define GrGLCoordTransform_DEFINED
-
-#include "GrBackendEffectFactory.h"
-#include "GrCoordTransform.h"
-#include "GrGLUniformManager.h"
-
-class GrTexture;
-class GrGLShaderBuilder;
-
-/**
- * This is a helper class used by the framework to implement a coordinate transform that operates on
- * incoming coords in the vertex shader and writes them to a varying to be used in the fragment
- * shader. Effects should not use this class directly, but instead call GrEffect::addCoordTransform.
- * When the input coords are local coordinates this class accounts for the coord change matrix
- * communicated via GrDrawEffect. The input coords may also be positions and in this case the coord
- * change matrix is ignored. The GrGLCoordTransform may emit different code based on the type of
- * matrix and thus must contribute to the effect's key.
- *
- * This class cannot be used to apply a matrix to coordinates that come in the form of custom vertex
- * attributes.
- */
-class GrGLCoordTransform {
-private:
- // We specialize the generated code for each of these matrix types.
- enum MatrixTypes {
- kIdentity_MatrixType = 0,
- kTrans_MatrixType = 1,
- kNoPersp_MatrixType = 2,
- kGeneral_MatrixType = 3,
- };
- // The key for is made up of a matrix type and a bit that indicates the source of the input
- // coords.
- enum {
- kMatrixTypeKeyBits = 2,
- kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1,
- kPositionCoords_Flag = (1 << kMatrixTypeKeyBits),
- kKeyBitsPrivate = kMatrixTypeKeyBits + 1,
- };
-
-public:
-
- typedef GrBackendEffectFactory::EffectKey EffectKey;
-
- /**
- * A GrGLCoordTransform key is kKeyBits long. The framework automatically generates and includes
- * these in EffectKeys.
- */
- enum {
- kKeyBits = kKeyBitsPrivate,
- kKeyMask = (1 << kKeyBits) - 1,
- };
-
- GrGLCoordTransform() { fPrevMatrix = SkMatrix::InvalidMatrix(); }
-
- /**
- * Generates the key for the portion of the code emitted by this class's emitCode() function.
- */
- static EffectKey GenKey(const GrDrawEffect&, int transformIdx);
-
- /**
- * Stores the name and type of a transformed set of coordinates. This class is passed to
- * GrGLEffect::emitCode.
- */
- class TransformedCoords {
- public:
- const char* c_str() const { return fName.c_str(); }
- GrSLType type() const { return fType; }
- const SkString& getName() const { return fName; }
- // TODO: Remove the VS name when we have vertexless shaders, and gradients are reworked.
- const SkString& getVSName() const { return fVSName; }
-
- private:
- friend class GrGLCoordTransform;
-
- SkString fName;
- GrSLType fType;
- SkString fVSName;
- };
-
- /**
- * Emits code to implement the matrix in the VS. A varying is added as an output of the VS and
- * input to the FS. The varying may be either a vec2f or vec3f depending upon whether
- * perspective interpolation is required or not. The names of the varying in the VS and FS as
- * well as its type are written to the TransformedCoords* object. The suffix is an optional
- * parameter that can be used to make all variables emitted by the object unique within a stage.
- * It is only necessary if multiple GrGLCoordTransform objects are used by a single GrGLEffect.
- */
- void emitCode(GrGLShaderBuilder*, EffectKey, TransformedCoords*, int suffix = 0);
-
- /**
- * Call from a GrGLEffect's subclass to update the texture matrix. The matrix and reverseY value
- * should match those used with GenKey.
- */
- void setData(const GrGLUniformManager&, const GrDrawEffect&, int transformIdx);
-
- GrGLUniformManager::UniformHandle fUni;
- GrSLType fUniType;
- SkMatrix fPrevMatrix;
-};
-
-#endif
diff --git a/src/gpu/gl/GrGLEffect.cpp b/src/gpu/gl/GrGLEffect.cpp
deleted file mode 100644
index af351a47fe..0000000000
--- a/src/gpu/gl/GrGLEffect.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrGLSL.h"
-#include "GrGLEffect.h"
-#include "GrCoordTransform.h"
-#include "GrDrawEffect.h"
-
-GrGLEffect::GrGLEffect(const GrBackendEffectFactory& factory)
- : fFactory(factory) {
-}
-
-GrGLEffect::~GrGLEffect() {
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void GrGLEffect::setData(const GrGLUniformManager&, const GrDrawEffect&) {
-}
-
-GrGLEffect::EffectKey GrGLEffect::GenTextureKey(const GrDrawEffect& drawEffect,
- const GrGLCaps& caps) {
- EffectKey key = 0;
- int numTextures = (*drawEffect.effect())->numTextures();
- for (int index = 0; index < numTextures; ++index) {
- const GrTextureAccess& access = (*drawEffect.effect())->textureAccess(index);
- EffectKey value = GrGLShaderBuilder::KeyForTextureAccess(access, caps) << index;
- SkASSERT(0 == (value & key)); // keys for each access ought not to overlap
- key |= value;
- }
- return key;
-}
-
-GrGLEffect::EffectKey GrGLEffect::GenTransformKey(const GrDrawEffect& drawEffect) {
- EffectKey key = 0;
- int numTransforms = (*drawEffect.effect())->numTransforms();
- for (int index = 0; index < numTransforms; ++index) {
- EffectKey value = GrGLCoordTransform::GenKey(drawEffect, index);
- value <<= index * GrGLCoordTransform::kKeyBits;
- SkASSERT(0 == (value & key)); // keys for each transform ought not to overlap
- key |= value;
- }
- return key;
-}
-
-GrGLEffect::EffectKey GrGLEffect::GenAttribKey(const GrDrawEffect& drawEffect) {
- EffectKey key = 0;
-
- int numAttributes = drawEffect.getVertexAttribIndexCount();
- SkASSERT(numAttributes <= 2);
- const int* attributeIndices = drawEffect.getVertexAttribIndices();
- for (int index = 0; index < numAttributes; ++index) {
- EffectKey value = attributeIndices[index] << 3*index;
- SkASSERT(0 == (value & key)); // keys for each attribute ought not to overlap
- key |= value;
- }
-
- return key;
-}
diff --git a/src/gpu/gl/GrGLEffect.h b/src/gpu/gl/GrGLEffect.h
index d3c49d11cf..52b1e921c1 100644
--- a/src/gpu/gl/GrGLEffect.h
+++ b/src/gpu/gl/GrGLEffect.h
@@ -9,6 +9,7 @@
#define GrGLEffect_DEFINED
#include "GrBackendEffectFactory.h"
+#include "GrGLProgramEffects.h"
#include "GrGLShaderBuilder.h"
#include "GrGLShaderVar.h"
#include "GrGLSL.h"
@@ -38,6 +39,8 @@ class GrGLEffect {
public:
typedef GrBackendEffectFactory::EffectKey EffectKey;
+ typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
+ typedef GrGLProgramEffects::TextureSamplerArray TextureSamplerArray;
enum {
kNoEffectKey = GrBackendEffectFactory::kNoEffectKey,
@@ -45,12 +48,9 @@ public:
kEffectKeyBits = GrBackendEffectFactory::kEffectKeyBits,
};
- typedef GrGLShaderBuilder::TransformedCoordsArray TransformedCoordsArray;
- typedef GrGLShaderBuilder::TextureSamplerArray TextureSamplerArray;
+ GrGLEffect(const GrBackendEffectFactory& factory) : fFactory(factory) {}
- GrGLEffect(const GrBackendEffectFactory&);
-
- virtual ~GrGLEffect();
+ virtual ~GrGLEffect() {}
/** Called when the program stage should insert its code into the shaders. The code in each
shader will be in its own block ({}) and so locally scoped names will not collide across
@@ -87,16 +87,12 @@ public:
EffectKey as the one that created this GrGLEffect. Effects that use local coords have
to consider whether the GrEffectStage's coord change matrix should be used. When explicit
local coordinates are used it can be ignored. */
- virtual void setData(const GrGLUniformManager&, const GrDrawEffect&);
+ virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) {}
const char* name() const { return fFactory.name(); }
static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { return 0; }
- static EffectKey GenTextureKey(const GrDrawEffect&, const GrGLCaps&);
- static EffectKey GenTransformKey(const GrDrawEffect&);
- static EffectKey GenAttribKey(const GrDrawEffect& stage);
-
protected:
const GrBackendEffectFactory& fFactory;
};
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 89f5f584bf..3691fe994b 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -48,9 +48,6 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu,
fColor = GrColor_ILLEGAL;
fColorFilterColor = GrColor_ILLEGAL;
- fColorEffects.reset(desc.numColorEffects());
- fCoverageEffects.reset(desc.numCoverageEffects());
-
this->genProgram(colorStages, coverageStages);
}
@@ -235,33 +232,12 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
bool needColor, needFilterColor;
need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor);
- // used in order for builder to return the per-stage uniform handles.
- typedef SkTArray<GrGLCoordTransform, false>* CoordTransformArrayPtr;
- typedef SkTArray<GrGLUniformManager::UniformHandle, true>* UniHandleArrayPtr;
- int maxColorOrCovEffectCnt = GrMax(fDesc.numColorEffects(), fDesc.numCoverageEffects());
- SkAutoTArray<CoordTransformArrayPtr> effectCoordTransformArrays(maxColorOrCovEffectCnt);
- SkAutoTArray<UniHandleArrayPtr> effectUniformArrays(maxColorOrCovEffectCnt);
- SkAutoTArray<GrGLEffect*> glEffects(maxColorOrCovEffectCnt);
-
- if (needColor) {
- for (int e = 0; e < fDesc.numColorEffects(); ++e) {
- effectCoordTransformArrays[e] = &fColorEffects[e].fCoordTransforms;
- effectUniformArrays[e] = &fColorEffects[e].fSamplerUnis;
- }
-
- builder.emitEffects(colorStages,
- fDesc.effectKeys(),
- fDesc.numColorEffects(),
- &inColor,
- &knownColorValue,
- effectCoordTransformArrays.get(),
- effectUniformArrays.get(),
- glEffects.get());
-
- for (int e = 0; e < fDesc.numColorEffects(); ++e) {
- fColorEffects[e].fGLEffect = glEffects[e];
- }
- }
+ fColorEffects.reset(
+ builder.createAndEmitEffects(colorStages,
+ fDesc.effectKeys(),
+ needColor ? fDesc.numColorEffects() : 0,
+ &inColor,
+ &knownColorValue));
// Insert the color filter. This will soon be replaced by a color effect.
if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) {
@@ -290,22 +266,12 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
SkString inCoverage = builder.getInputCoverage();
GrSLConstantVec knownCoverageValue = builder.getKnownCoverageValue();
- for (int e = 0; e < fDesc.numCoverageEffects(); ++e) {
- effectCoordTransformArrays[e] = &fCoverageEffects[e].fCoordTransforms;
- effectUniformArrays[e] = &fCoverageEffects[e].fSamplerUnis;
- }
-
- builder.emitEffects(coverageStages,
- fDesc.getEffectKeys() + fDesc.numColorEffects(),
- fDesc.numCoverageEffects(),
- &inCoverage,
- &knownCoverageValue,
- effectCoordTransformArrays.get(),
- effectUniformArrays.get(),
- glEffects.get());
- for (int e = 0; e < fDesc.numCoverageEffects(); ++e) {
- fCoverageEffects[e].fGLEffect = glEffects[e];
- }
+ fCoverageEffects.reset(
+ builder.createAndEmitEffects(coverageStages,
+ fDesc.getEffectKeys() + fDesc.numColorEffects(),
+ fDesc.numCoverageEffects(),
+ &inCoverage,
+ &knownCoverageValue));
// discard if coverage is zero
if (header.fDiscardIfZeroCoverage && kOnes_GrSLConstantVec != knownCoverageValue) {
@@ -421,59 +387,12 @@ void GrGLProgram::initSamplerUniforms() {
fUniformManager.setSampler(fUniformHandles.fDstCopySamplerUni, texUnitIdx);
fDstCopyTexUnit = texUnitIdx++;
}
-
- for (int e = 0; e < fColorEffects.count(); ++e) {
- this->initEffectSamplerUniforms(&fColorEffects[e], &texUnitIdx);
- }
-
- for (int e = 0; e < fCoverageEffects.count(); ++e) {
- this->initEffectSamplerUniforms(&fCoverageEffects[e], &texUnitIdx);
- }
-}
-
-void GrGLProgram::initEffectSamplerUniforms(EffectAndSamplers* effect, int* texUnitIdx) {
- int numSamplers = effect->fSamplerUnis.count();
- effect->fTextureUnits.reset(numSamplers);
- for (int s = 0; s < numSamplers; ++s) {
- UniformHandle handle = effect->fSamplerUnis[s];
- if (handle.isValid()) {
- fUniformManager.setSampler(handle, *texUnitIdx);
- effect->fTextureUnits[s] = (*texUnitIdx)++;
- }
- }
+ fColorEffects->initSamplers(fUniformManager, &texUnitIdx);
+ fCoverageEffects->initSamplers(fUniformManager, &texUnitIdx);
}
///////////////////////////////////////////////////////////////////////////////
-void GrGLProgram::setEffectData(const GrEffectStage& stage,
- EffectAndSamplers& effect) {
-
- // Let the GrGLEffect set its data.
- bool explicitLocalCoords = -1 != fDesc.getHeader().fLocalCoordAttributeIndex;
- GrDrawEffect drawEffect(stage, explicitLocalCoords);
- effect.fGLEffect->setData(fUniformManager, drawEffect);
-
- // Set the effect's coord transform matrices.
- int numTransforms = effect.fCoordTransforms.count();
- SkASSERT((*stage.getEffect())->numTransforms() == numTransforms);
- for (int c = 0; c < numTransforms; ++c) {
- effect.fCoordTransforms[c].setData(fUniformManager, drawEffect, c);
- }
-
- // Bind the texures for the effect.
- int numSamplers = effect.fSamplerUnis.count();
- SkASSERT((*stage.getEffect())->numTextures() == numSamplers);
- for (int s = 0; s < numSamplers; ++s) {
- UniformHandle handle = effect.fSamplerUnis[s];
- if (handle.isValid()) {
- const GrTextureAccess& access = (*stage.getEffect())->textureAccess(s);
- GrGLTexture* texture = static_cast<GrGLTexture*>(access.getTexture());
- int unit = effect.fTextureUnits[s];
- fGpu->bindTexture(unit, access.getParams(), texture);
- }
- }
-}
-
void GrGLProgram::setData(GrDrawState::BlendOptFlags blendOpts,
const GrEffectStage* colorStages[],
const GrEffectStage* coverageStages[],
@@ -528,19 +447,8 @@ void GrGLProgram::setData(GrDrawState::BlendOptFlags blendOpts,
SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid());
}
- for (int e = 0; e < fColorEffects.count(); ++e) {
- // We may have omitted the GrGLEffect because of the color filter logic in genProgram.
- // This can be removed when the color filter is an effect.
- if (NULL != fColorEffects[e].fGLEffect) {
- this->setEffectData(*colorStages[e], fColorEffects[e]);
- }
- }
-
- for (int e = 0; e < fCoverageEffects.count(); ++e) {
- if (NULL != fCoverageEffects[e].fGLEffect) {
- this->setEffectData(*coverageStages[e], fCoverageEffects[e]);
- }
- }
+ fColorEffects->setData(fGpu, fUniformManager, colorStages);
+ fCoverageEffects->setData(fGpu, fUniformManager, coverageStages);
}
void GrGLProgram::setColor(const GrDrawState& drawState,
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 441230938b..c8bcbf479e 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -11,7 +11,6 @@
#include "GrDrawState.h"
#include "GrGLContext.h"
-#include "GrGLCoordTransform.h"
#include "GrGLProgramDesc.h"
#include "GrGLShaderBuilder.h"
#include "GrGLSL.h"
@@ -23,6 +22,7 @@
class GrBinHashKeyBuilder;
class GrGLEffect;
+class GrGLProgramEffects;
class GrGLShaderBuilder;
/**
@@ -149,19 +149,6 @@ private:
UniformHandle fDstCopySamplerUni;
};
- typedef SkSTArray<4, GrGLCoordTransform, false> CoordTransformSArray;
- typedef SkSTArray<4, UniformHandle, true> SamplerUniSArray;
- typedef SkSTArray<4, int, true> TextureUnitSArray;
-
- struct EffectAndSamplers {
- EffectAndSamplers() : fGLEffect(NULL) {}
- ~EffectAndSamplers() { delete fGLEffect; }
- GrGLEffect* fGLEffect;
- CoordTransformSArray fCoordTransforms;
- SamplerUniSArray fSamplerUnis; // sampler uni handles for effect's GrTextureAccess
- TextureUnitSArray fTextureUnits; // texture unit used for each entry of fSamplerUnis
- };
-
GrGLProgram(GrGpuGL* gpu,
const GrGLProgramDesc& desc,
const GrEffectStage* colorStages[],
@@ -177,10 +164,6 @@ private:
// Sets the texture units for samplers
void initSamplerUniforms();
- void initEffectSamplerUniforms(EffectAndSamplers* effect, int* texUnitIdx);
-
- // Helper for setData().
- void setEffectData(const GrEffectStage& stage, EffectAndSamplers& effect);
// Helper for setData(). Makes GL calls to specify the initial color when there is not
// per-vertex colors.
@@ -197,20 +180,20 @@ private:
GrGLuint fProgramID;
// these reflect the current values of uniforms (GL uniform values travel with program)
- MatrixState fMatrixState;
- GrColor fColor;
- GrColor fCoverage;
- GrColor fColorFilterColor;
- int fDstCopyTexUnit;
+ MatrixState fMatrixState;
+ GrColor fColor;
+ GrColor fCoverage;
+ GrColor fColorFilterColor;
+ int fDstCopyTexUnit;
- SkTArray<EffectAndSamplers> fColorEffects;
- SkTArray<EffectAndSamplers> fCoverageEffects;
+ SkAutoTDelete<GrGLProgramEffects> fColorEffects;
+ SkAutoTDelete<GrGLProgramEffects> fCoverageEffects;
- GrGLProgramDesc fDesc;
- GrGpuGL* fGpu;
+ GrGLProgramDesc fDesc;
+ GrGpuGL* fGpu;
- GrGLUniformManager fUniformManager;
- UniformHandles fUniformHandles;
+ GrGLUniformManager fUniformManager;
+ UniformHandles fUniformHandles;
typedef SkRefCnt INHERITED;
};
diff --git a/src/gpu/gl/GrGLProgramEffects.cpp b/src/gpu/gl/GrGLProgramEffects.cpp
new file mode 100644
index 0000000000..312322c683
--- /dev/null
+++ b/src/gpu/gl/GrGLProgramEffects.cpp
@@ -0,0 +1,414 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLProgramEffects.h"
+#include "GrDrawEffect.h"
+#include "gl/GrGLEffect.h"
+#include "gl/GrGLShaderBuilder.h"
+#include "gl/GrGpuGL.h"
+
+typedef GrGLProgramEffects::EffectKey EffectKey;
+typedef GrGLProgramEffects::TransformedCoords TransformedCoords;
+typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
+typedef GrGLProgramEffects::TextureSampler TextureSampler;
+typedef GrGLProgramEffects::TextureSamplerArray TextureSamplerArray;
+
+/**
+ * We specialize the vertex code for each of these matrix types.
+ */
+enum MatrixType {
+ kIdentity_MatrixType = 0,
+ kTrans_MatrixType = 1,
+ kNoPersp_MatrixType = 2,
+ kGeneral_MatrixType = 3,
+};
+
+/**
+ * The key for an individual coord transform is made up of a matrix type and a bit that
+ * indicates the source of the input coords.
+ */
+enum {
+ kMatrixTypeKeyBits = 2,
+ kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1,
+ kPositionCoords_Flag = (1 << kMatrixTypeKeyBits),
+ kTransformKeyBits = kMatrixTypeKeyBits + 1,
+ kTransformKeyMask = (1 << kTransformKeyBits) - 1,
+};
+
+namespace {
+
+/**
+ * Do we need to either map r,g,b->a or a->r. configComponentMask indicates which channels are
+ * present in the texture's config. swizzleComponentMask indicates the channels present in the
+ * shader swizzle.
+ */
+inline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
+ uint32_t configComponentMask,
+ uint32_t swizzleComponentMask) {
+ if (caps.textureSwizzleSupport()) {
+ // Any remapping is handled using texture swizzling not shader modifications.
+ return false;
+ }
+ // check if the texture is alpha-only
+ if (kA_GrColorComponentFlag == configComponentMask) {
+ if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleComponentMask)) {
+ // we must map the swizzle 'a's to 'r'.
+ return true;
+ }
+ if (kRGB_GrColorComponentFlags & swizzleComponentMask) {
+ // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our semantics that
+ // alpha-only textures smear alpha across all four channels when read.
+ return true;
+ }
+ }
+ return false;
+}
+
+}
+
+EffectKey GrGLProgramEffects::GenAttribKey(const GrDrawEffect& drawEffect) {
+ EffectKey key = 0;
+ int numAttributes = drawEffect.getVertexAttribIndexCount();
+ SkASSERT(numAttributes <= 2);
+ const int* attributeIndices = drawEffect.getVertexAttribIndices();
+ for (int a = 0; a < numAttributes; ++a) {
+ EffectKey value = attributeIndices[a] << 3 * a;
+ SkASSERT(0 == (value & key)); // keys for each attribute ought not to overlap
+ key |= value;
+ }
+ return key;
+}
+
+EffectKey GrGLProgramEffects::GenTransformKey(const GrDrawEffect& drawEffect) {
+ EffectKey totalKey = 0;
+ int numTransforms = (*drawEffect.effect())->numTransforms();
+ for (int t = 0; t < numTransforms; ++t) {
+ EffectKey key = 0;
+ const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTransform(t);
+ SkMatrix::TypeMask type0 = coordTransform.getMatrix().getType();
+ SkMatrix::TypeMask type1;
+ if (kLocal_GrCoordSet == coordTransform.sourceCoords()) {
+ type1 = drawEffect.getCoordChangeMatrix().getType();
+ } else {
+ if (drawEffect.programHasExplicitLocalCoords()) {
+ // We only make the key indicate that device coords are referenced when the local coords
+ // are not actually determined by positions. Otherwise the local coords var and position
+ // var are identical.
+ key |= kPositionCoords_Flag;
+ }
+ type1 = SkMatrix::kIdentity_Mask;
+ }
+
+ int combinedTypes = type0 | type1;
+
+ bool reverseY = coordTransform.reverseY();
+
+ if (SkMatrix::kPerspective_Mask & combinedTypes) {
+ key |= kGeneral_MatrixType;
+ } else if (((SkMatrix::kAffine_Mask | SkMatrix::kScale_Mask) & combinedTypes) || reverseY) {
+ key |= kNoPersp_MatrixType;
+ } else if (SkMatrix::kTranslate_Mask & combinedTypes) {
+ key |= kTrans_MatrixType;
+ } else {
+ key |= kIdentity_MatrixType;
+ }
+ key <<= kTransformKeyBits * t;
+ SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to overlap
+ totalKey |= key;
+ }
+ return totalKey;
+}
+
+EffectKey GrGLProgramEffects::GenTextureKey(const GrDrawEffect& drawEffect, const GrGLCaps& caps) {
+ EffectKey key = 0;
+ int numTextures = (*drawEffect.effect())->numTextures();
+ for (int t = 0; t < numTextures; ++t) {
+ const GrTextureAccess& access = (*drawEffect.effect())->textureAccess(t);
+ uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config());
+ if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) {
+ key |= 1 << t;
+ }
+ }
+ return key;
+}
+
+GrGLProgramEffects::~GrGLProgramEffects() {
+ int numEffects = fGLEffects.count();
+ for (int e = 0; e < numEffects; ++e) {
+ SkDELETE(fGLEffects[e]);
+ }
+}
+
+void GrGLProgramEffects::initSamplers(const GrGLUniformManager& uniformManager, int* texUnitIdx) {
+ int numEffects = fGLEffects.count();
+ SkASSERT(numEffects == fSamplers.count());
+ for (int e = 0; e < numEffects; ++e) {
+ SkTArray<Sampler, true>& samplers = fSamplers[e];
+ int numSamplers = samplers.count();
+ for (int s = 0; s < numSamplers; ++s) {
+ SkASSERT(samplers[s].fUniform.isValid());
+ uniformManager.setSampler(samplers[s].fUniform, *texUnitIdx);
+ samplers[s].fTextureUnit = (*texUnitIdx)++;
+ }
+ }
+}
+
+void GrGLProgramEffects::setData(GrGpuGL* gpu,
+ const GrGLUniformManager& uniformManager,
+ const GrEffectStage* effectStages[]) {
+ int numEffects = fGLEffects.count();
+ SkASSERT(numEffects == fTransforms.count());
+ SkASSERT(numEffects == fSamplers.count());
+ for (int e = 0; e < numEffects; ++e) {
+ GrDrawEffect drawEffect(*effectStages[e], fHasExplicitLocalCoords);
+ fGLEffects[e]->setData(uniformManager, drawEffect);
+ this->setTransformData(uniformManager, drawEffect, e);
+ this->bindTextures(gpu, *drawEffect.effect(), e);
+ }
+}
+
+void GrGLProgramEffects::setTransformData(const GrGLUniformManager& uniformManager,
+ const GrDrawEffect& drawEffect,
+ int effectIdx) {
+ SkTArray<Transform, true>& transforms = fTransforms[effectIdx];
+ int numTransforms = transforms.count();
+ SkASSERT(numTransforms == (*drawEffect.effect())->numTransforms());
+ for (int t = 0; t < numTransforms; ++t) {
+ const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTransform(t);
+ const SkMatrix& matrix = coordTransform.getMatrix();
+ const SkMatrix& coordChangeMatrix = kLocal_GrCoordSet == coordTransform.sourceCoords() ?
+ drawEffect.getCoordChangeMatrix() :
+ SkMatrix::I();
+ SkASSERT(transforms[t].fHandle.isValid() != (kVoid_GrSLType == transforms[t].fType));
+ switch (transforms[t].fType) {
+ case kVoid_GrSLType:
+ SkASSERT(matrix.isIdentity());
+ SkASSERT(coordChangeMatrix.isIdentity());
+ SkASSERT(!coordTransform.reverseY());
+ return;
+ case kVec2f_GrSLType: {
+ SkASSERT(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChangeMatrix.getType()));
+ SkASSERT(!coordTransform.reverseY());
+ SkScalar tx = matrix[SkMatrix::kMTransX] + (coordChangeMatrix)[SkMatrix::kMTransX];
+ SkScalar ty = matrix[SkMatrix::kMTransY] + (coordChangeMatrix)[SkMatrix::kMTransY];
+ if (transforms[t].fCurrentValue.get(SkMatrix::kMTransX) != tx ||
+ transforms[t].fCurrentValue.get(SkMatrix::kMTransY) != ty) {
+ uniformManager.set2f(transforms[t].fHandle, tx, ty);
+ transforms[t].fCurrentValue.set(SkMatrix::kMTransX, tx);
+ transforms[t].fCurrentValue.set(SkMatrix::kMTransY, ty);
+ }
+ break;
+ }
+ case kMat33f_GrSLType: {
+ SkMatrix combined;
+ combined.setConcat(matrix, coordChangeMatrix);
+ 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]);
+ }
+ if (!transforms[t].fCurrentValue.cheapEqualTo(combined)) {
+ uniformManager.setSkMatrix(transforms[t].fHandle, combined);
+ transforms[t].fCurrentValue = combined;
+ }
+ break;
+ }
+ default:
+ GrCrash("Unexpected uniform type.");
+ }
+ }
+}
+
+void GrGLProgramEffects::bindTextures(GrGpuGL* gpu, const GrEffectRef& effect, int effectIdx) {
+ const SkTArray<Sampler, true>& samplers = fSamplers[effectIdx];
+ int numSamplers = samplers.count();
+ SkASSERT(numSamplers == effect->numTextures());
+ for (int s = 0; s < numSamplers; ++s) {
+ SkASSERT(samplers[s].fTextureUnit >= 0);
+ const GrTextureAccess& textureAccess = effect->textureAccess(s);
+ gpu->bindTexture(samplers[s].fTextureUnit,
+ textureAccess.getParams(),
+ static_cast<GrGLTexture*>(textureAccess.getTexture()));
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrGLProgramEffectsBuilder::GrGLProgramEffectsBuilder(GrGLShaderBuilder* builder, int reserveCount)
+ : fBuilder(builder) {
+ GrGLShaderBuilder::VertexBuilder* vertexBuilder = fBuilder->getVertexBuilder();
+ SkASSERT(NULL != vertexBuilder);
+ fProgramEffects.reset(SkNEW_ARGS(GrGLProgramEffects,
+ (reserveCount, vertexBuilder->hasExplicitLocalCoords())));
+}
+
+void GrGLProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
+ EffectKey key,
+ const char* outColor,
+ const char* inColor,
+ int stageIndex) {
+ GrGLShaderBuilder::VertexBuilder* vertexBuilder = fBuilder->getVertexBuilder();
+ SkASSERT(NULL != vertexBuilder);
+ SkASSERT(NULL != fProgramEffects.get());
+
+ GrDrawEffect drawEffect(stage, fProgramEffects->fHasExplicitLocalCoords);
+ const GrEffectRef& effect = *stage.getEffect();
+ SkSTArray<2, TransformedCoords> coords(effect->numTransforms());
+ SkSTArray<4, TextureSampler> samplers(effect->numTextures());
+
+ this->emitAttributes(stage);
+ this->emitTransforms(effect, key, &coords);
+ this->emitSamplers(effect, &samplers);
+
+ GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
+ fProgramEffects->fGLEffects.push_back(glEffect);
+
+ // Enclose custom code in a block to avoid namespace conflicts
+ SkString openBrace;
+ openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
+ vertexBuilder->vsCodeAppend(openBrace.c_str());
+ fBuilder->fsCodeAppend(openBrace.c_str());
+
+ glEffect->emitCode(fBuilder, drawEffect, key, outColor, inColor, coords, samplers);
+
+ vertexBuilder->vsCodeAppend("\t}\n");
+ fBuilder->fsCodeAppend("\t}\n");
+}
+
+void GrGLProgramEffectsBuilder::emitAttributes(const GrEffectStage& stage) {
+ GrGLShaderBuilder::VertexBuilder* vertexBuilder = fBuilder->getVertexBuilder();
+ SkASSERT(NULL != vertexBuilder);
+
+ int numAttributes = stage.getVertexAttribIndexCount();
+ const int* attributeIndices = stage.getVertexAttribIndices();
+ for (int a = 0; a < numAttributes; ++a) {
+ // TODO: Make addAttribute mangle the name.
+ SkString attributeName("aAttr");
+ attributeName.appendS32(attributeIndices[a]);
+ vertexBuilder->addEffectAttribute(attributeIndices[a],
+ (*stage.getEffect())->vertexAttribType(a),
+ attributeName);
+ }
+}
+
+void GrGLProgramEffectsBuilder::emitTransforms(const GrEffectRef& effect,
+ EffectKey effectKey,
+ TransformedCoordsArray* outCoords) {
+ GrGLShaderBuilder::VertexBuilder* vertexBuilder = fBuilder->getVertexBuilder();
+ SkASSERT(NULL != vertexBuilder);
+
+ typedef GrGLProgramEffects::Transform Transform;
+ SkTArray<Transform, true>& transforms = fProgramEffects->fTransforms.push_back();
+ EffectKey totalKey = GrBackendEffectFactory::GetTransformKey(effectKey);
+ int numTransforms = effect->numTransforms();
+ transforms.push_back_n(numTransforms);
+ for (int t = 0; t < numTransforms; t++) {
+ EffectKey key = (totalKey >> (kTransformKeyBits * t)) & kTransformKeyMask;
+ GrSLType varyingType = kVoid_GrSLType;
+ const char* uniName;
+ switch (key & kMatrixTypeKeyMask) {
+ case kIdentity_MatrixType:
+ transforms[t].fType = kVoid_GrSLType;
+ uniName = NULL;
+ varyingType = kVec2f_GrSLType;
+ break;
+ case kTrans_MatrixType:
+ transforms[t].fType = kVec2f_GrSLType;
+ uniName = "StageTranslate";
+ varyingType = kVec2f_GrSLType;
+ break;
+ case kNoPersp_MatrixType:
+ transforms[t].fType = kMat33f_GrSLType;
+ uniName = "StageMatrix";
+ varyingType = kVec2f_GrSLType;
+ break;
+ case kGeneral_MatrixType:
+ transforms[t].fType = kMat33f_GrSLType;
+ uniName = "StageMatrix";
+ varyingType = kVec3f_GrSLType;
+ break;
+ default:
+ GrCrash("Unexpected key.");
+ }
+ SkString suffixedUniName;
+ if (kVoid_GrSLType != transforms[t].fType) {
+ if (0 != t) {
+ suffixedUniName.append(uniName);
+ suffixedUniName.appendf("_%i", t);
+ uniName = suffixedUniName.c_str();
+ }
+ transforms[t].fHandle = fBuilder->addUniform(GrGLShaderBuilder::kVertex_Visibility,
+ transforms[t].fType,
+ uniName,
+ &uniName);
+ }
+
+ const char* varyingName = "MatrixCoord";
+ SkString suffixedVaryingName;
+ if (0 != t) {
+ suffixedVaryingName.append(varyingName);
+ suffixedVaryingName.appendf("_%i", t);
+ varyingName = suffixedVaryingName.c_str();
+ }
+ const char* vsVaryingName;
+ const char* fsVaryingName;
+ vertexBuilder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
+
+ const GrGLShaderVar& coords = (kPositionCoords_Flag & key) ?
+ vertexBuilder->positionAttribute() :
+ vertexBuilder->localCoordsAttribute();
+ // varying = matrix * coords (logically)
+ switch (transforms[t].fType) {
+ case kVoid_GrSLType:
+ SkASSERT(kVec2f_GrSLType == varyingType);
+ vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords.c_str());
+ break;
+ case kVec2f_GrSLType:
+ SkASSERT(kVec2f_GrSLType == varyingType);
+ vertexBuilder->vsCodeAppendf("\t%s = %s + %s;\n",
+ vsVaryingName, uniName, coords.c_str());
+ break;
+ case kMat33f_GrSLType: {
+ SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
+ if (kVec2f_GrSLType == varyingType) {
+ vertexBuilder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n",
+ vsVaryingName, uniName, coords.c_str());
+ } else {
+ vertexBuilder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n",
+ vsVaryingName, uniName, coords.c_str());
+ }
+ break;
+ }
+ default:
+ GrCrash("Unexpected uniform type.");
+ }
+ SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords,
+ (fsVaryingName, varyingType, vsVaryingName));
+ }
+}
+
+void GrGLProgramEffectsBuilder::emitSamplers(const GrEffectRef& effect,
+ TextureSamplerArray* outSamplers) {
+ typedef GrGLProgramEffects::Sampler Sampler;
+ SkTArray<Sampler, true>& samplers = fProgramEffects->fSamplers.push_back();
+ int numTextures = effect->numTextures();
+ samplers.push_back_n(numTextures);
+ SkString name;
+ for (int t = 0; t < numTextures; ++t) {
+ name.printf("Sampler%d", t);
+ samplers[t].fUniform = fBuilder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ kSampler2D_GrSLType,
+ name.c_str());
+ SkNEW_APPEND_TO_TARRAY(outSamplers, TextureSampler,
+ (samplers[t].fUniform, effect->textureAccess(t)));
+ }
+}
diff --git a/src/gpu/gl/GrGLProgramEffects.h b/src/gpu/gl/GrGLProgramEffects.h
new file mode 100644
index 0000000000..c2c21042b0
--- /dev/null
+++ b/src/gpu/gl/GrGLProgramEffects.h
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLProgramEffects_DEFINED
+#define GrGLProgramEffects_DEFINED
+
+#include "GrBackendEffectFactory.h"
+#include "GrTexture.h"
+#include "GrTextureAccess.h"
+#include "GrGLUniformManager.h"
+
+class GrEffectStage;
+class GrGLProgramEffectsBuilder;
+class GrGLShaderBuilder;
+
+/**
+ * This class encapsulates an array of GrGLEffects and their supporting data (coord transforms
+ * and textures). It is built with GrGLProgramEffectsBuilder, then used to manage the necessary GL
+ * state and shader uniforms.
+ */
+class GrGLProgramEffects {
+public:
+ typedef GrBackendEffectFactory::EffectKey EffectKey;
+ typedef GrGLUniformManager::UniformHandle UniformHandle;
+
+ /**
+ * These methods generate different portions of an effect's final key.
+ */
+ static EffectKey GenAttribKey(const GrDrawEffect&);
+ static EffectKey GenTransformKey(const GrDrawEffect&);
+ static EffectKey GenTextureKey(const GrDrawEffect&, const GrGLCaps&);
+
+ ~GrGLProgramEffects();
+
+ /**
+ * Assigns a texture unit to each sampler. It starts on *texUnitIdx and writes the next
+ * available unit to *texUnitIdx when it returns.
+ */
+ void initSamplers(const GrGLUniformManager&, int* texUnitIdx);
+
+ /**
+ * Calls setData() on each effect, and sets their transformation matrices and texture bindings.
+ */
+ void setData(GrGpuGL*,
+ const GrGLUniformManager&,
+ const GrEffectStage* effectStages[]);
+
+ /**
+ * Passed to GrGLEffects so they can add transformed coordinates to their shader code.
+ */
+ class TransformedCoords {
+ public:
+ TransformedCoords(const char* name, GrSLType type, const char* vsName)
+ : fName(name), fType(type), fVSName(vsName) {
+ }
+
+ const char* c_str() const { return fName.c_str(); }
+ GrSLType type() const { return fType; }
+ const SkString& getName() const { return fName; }
+ // TODO: Remove the VS name when we have vertexless shaders, and gradients are reworked.
+ const SkString& getVSName() const { return fVSName; }
+
+ private:
+ SkString fName;
+ GrSLType fType;
+ SkString fVSName;
+ };
+
+ typedef SkTArray<TransformedCoords> TransformedCoordsArray;
+
+ /**
+ * Passed to GrGLEffects so they can add texture reads to their shader code.
+ */
+ class TextureSampler {
+ public:
+ TextureSampler(UniformHandle uniform, const GrTextureAccess& access)
+ : fSamplerUniform(uniform)
+ , fConfigComponentMask(GrPixelConfigComponentMask(access.getTexture()->config())) {
+ SkASSERT(0 != fConfigComponentMask);
+ memcpy(fSwizzle, access.getSwizzle(), 5);
+ }
+
+ UniformHandle samplerUniform() const { return fSamplerUniform; }
+ // bitfield of GrColorComponentFlags present in the texture's config.
+ uint32_t configComponentMask() const { return fConfigComponentMask; }
+ const char* swizzle() const { return fSwizzle; }
+
+ private:
+ UniformHandle fSamplerUniform;
+ uint32_t fConfigComponentMask;
+ char fSwizzle[5];
+ };
+
+ typedef SkTArray<TextureSampler> TextureSamplerArray;
+
+private:
+ friend class GrGLProgramEffectsBuilder;
+
+ GrGLProgramEffects(int reserveCount, bool explicitLocalCoords)
+ : fGLEffects(reserveCount)
+ , fTransforms(reserveCount)
+ , fSamplers(reserveCount)
+ , fHasExplicitLocalCoords(explicitLocalCoords) {
+ }
+
+ /**
+ * Helper for setData(). Sets all the transform matrices for an effect.
+ */
+ void setTransformData(const GrGLUniformManager&, const GrDrawEffect&, int effectIdx);
+
+ /**
+ * Helper for setData(). Binds all the textures for an effect.
+ */
+ void bindTextures(GrGpuGL*, const GrEffectRef&, int effectIdx);
+
+ struct Transform {
+ Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
+ UniformHandle fHandle;
+ GrSLType fType;
+ SkMatrix fCurrentValue;
+ };
+
+ struct Sampler {
+ SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
+ UniformHandle fUniform;
+ int fTextureUnit;
+ };
+
+ SkTArray<GrGLEffect*> fGLEffects;
+ SkTArray<SkSTArray<2, Transform, true> > fTransforms;
+ SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
+ bool fHasExplicitLocalCoords;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * This class is used to construct a GrGLProgramEffects.
+ */
+class GrGLProgramEffectsBuilder {
+public:
+ GrGLProgramEffectsBuilder(GrGLShaderBuilder* builder, int reserveCount);
+
+ /**
+ * Emits the effect's shader code, and stores the necessary uniforms internally.
+ */
+ void emitEffect(const GrEffectStage&,
+ GrGLProgramEffects::EffectKey,
+ const char* outColor,
+ const char* inColor,
+ int stageIndex);
+
+ /**
+ * Finalizes the building process and returns the effect array. After this call, the builder
+ * becomes invalid.
+ */
+ GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
+
+private:
+ /**
+ * Helper for emitEffect(). Emits any attributes an effect might have.
+ */
+ void emitAttributes(const GrEffectStage&);
+
+ /**
+ * Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS.
+ * Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a
+ * vec2f or vec3f depending upon whether perspective interpolation is required or not. The names
+ * of the varyings in the VS and FS as well their types are appended to the
+ * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function.
+ */
+ void emitTransforms(const GrEffectRef&,
+ GrGLProgramEffects::EffectKey,
+ GrGLProgramEffects::TransformedCoordsArray*);
+
+ /**
+ * Helper for emitEffect(). Emits uniforms for an effect's texture accesses. The uniform info
+ * as well as texture access parameters are appended to the TextureSamplerArray* object, which
+ * is in turn passed to the effect's emitCode() function.
+ */
+ void emitSamplers(const GrEffectRef&,
+ GrGLProgramEffects::TextureSamplerArray*);
+
+ GrGLShaderBuilder* fBuilder;
+ SkAutoTDelete<GrGLProgramEffects> fProgramEffects;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index 313ad863c3..c33f04ba30 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -49,44 +49,27 @@ inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen)
}
}
-/**
- * Do we need to either map r,g,b->a or a->r. configComponentMask indicates which channels are
- * present in the texture's config. swizzleComponentMask indicates the channels present in the
- * shader swizzle.
- */
-inline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
- uint32_t configComponentMask,
- uint32_t swizzleComponentMask) {
- if (caps.textureSwizzleSupport()) {
- // Any remapping is handled using texture swizzling not shader modifications.
- return false;
- }
- // check if the texture is alpha-only
- if (kA_GrColorComponentFlag == configComponentMask) {
- if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleComponentMask)) {
- // we must map the swizzle 'a's to 'r'.
- return true;
- }
- if (kRGB_GrColorComponentFlags & swizzleComponentMask) {
- // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our semantics that
- // alpha-only textures smear alpha across all four channels when read.
- return true;
- }
- }
- return false;
-}
+void append_texture_lookup(SkString* out,
+ GrGpuGL* gpu,
+ const char* samplerName,
+ const char* coordName,
+ uint32_t configComponentMask,
+ const char* swizzle,
+ GrSLType varyingType = kVec2f_GrSLType) {
+ SkASSERT(NULL != coordName);
+
+ out->appendf("%s(%s, %s)",
+ sample_function_name(varyingType, gpu->glslGeneration()),
+ samplerName,
+ coordName);
-void append_swizzle(SkString* outAppend,
- const GrGLShaderBuilder::TextureSampler& texSampler,
- const GrGLCaps& caps) {
- const char* swizzle = texSampler.swizzle();
char mangledSwizzle[5];
// The swizzling occurs using texture params instead of shader-mangling if ARB_texture_swizzle
// is available.
- if (!caps.textureSwizzleSupport() &&
- (kA_GrColorComponentFlag == texSampler.configComponentMask())) {
- char alphaChar = caps.textureRedSupport() ? 'r' : 'a';
+ if (!gpu->glCaps().textureSwizzleSupport() &&
+ (kA_GrColorComponentFlag == configComponentMask)) {
+ char alphaChar = gpu->glCaps().textureRedSupport() ? 'r' : 'a';
int i;
for (i = 0; '\0' != swizzle[i]; ++i) {
mangledSwizzle[i] = alphaChar;
@@ -96,7 +79,7 @@ void append_swizzle(SkString* outAppend,
}
// For shader prettiness we omit the swizzle rather than appending ".rgba".
if (memcmp(swizzle, "rgba", 4)) {
- outAppend->appendf(".%s", swizzle);
+ out->appendf(".%s", swizzle);
}
}
@@ -141,8 +124,9 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu,
} else {
configMask = kRGBA_GrColorComponentFlags;
}
- fDstCopySampler.init(this, configMask, "rgba", 0);
-
+ fDstCopySamplerUniform = this->addUniform(kFragment_Visibility,
+ kSampler2D_GrSLType,
+ "DstCopySampler");
fDstCopyTopLeftUniform = this->addUniform(kFragment_Visibility,
kVec2f_GrSLType,
"DstCopyUpperLeft",
@@ -159,7 +143,12 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu,
this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n");
}
this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName);
- this->fsAppendTextureLookup(fDstCopySampler, "_dstTexCoord");
+ append_texture_lookup(&fFSCode,
+ fGpu,
+ this->getUniformCStr(fDstCopySamplerUniform),
+ "_dstTexCoord",
+ configMask,
+ "rgba");
this->fsCodeAppend(";\n\n");
}
@@ -312,7 +301,7 @@ const char* GrGLShaderBuilder::dstColor() {
} else if (GrGLCaps::kNV_FBFetchType == fetchType) {
SkAssertResult(this->enablePrivateFeature(kNVShaderFramebufferFetch_GLSLPrivateFeature));
return kFBFetchColorName;
- } else if (fDstCopySampler.isInitialized()) {
+ } else if (fDstCopySamplerUniform.isValid()) {
return kDstCopyColorName;
} else {
return "";
@@ -323,13 +312,13 @@ void GrGLShaderBuilder::appendTextureLookup(SkString* out,
const GrGLShaderBuilder::TextureSampler& sampler,
const char* coordName,
GrSLType varyingType) const {
- SkASSERT(NULL != coordName);
-
- out->appendf("%s(%s, %s)",
- sample_function_name(varyingType, fGpu->glslGeneration()),
- this->getUniformCStr(sampler.fSamplerUniform),
- coordName);
- append_swizzle(out, sampler, fGpu->glCaps());
+ append_texture_lookup(out,
+ fGpu,
+ this->getUniformCStr(sampler.samplerUniform()),
+ coordName,
+ sampler.configComponentMask(),
+ sampler.swizzle(),
+ varyingType);
}
void GrGLShaderBuilder::fsAppendTextureLookup(const GrGLShaderBuilder::TextureSampler& sampler,
@@ -348,16 +337,6 @@ void GrGLShaderBuilder::fsAppendTextureLookupAndModulate(
GrGLSLModulatef<4>(&fFSCode, modulation, lookup.c_str());
}
-GrGLShaderBuilder::EffectKey GrGLShaderBuilder::KeyForTextureAccess(const GrTextureAccess& access,
- const GrGLCaps& caps) {
- uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config());
- if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) {
- return 1;
- } else {
- return 0;
- }
-}
-
GrGLShaderBuilder::DstReadKey GrGLShaderBuilder::KeyForDstRead(const GrTexture* dstCopy,
const GrGLCaps& caps) {
uint32_t key = kYesDstRead_DstReadKeyBit;
@@ -572,15 +551,14 @@ void GrGLShaderBuilder::appendUniformDecls(ShaderVisibility visibility,
}
}
-void GrGLShaderBuilder::emitEffects(
- const GrEffectStage* effectStages[],
- const EffectKey effectKeys[],
- int effectCnt,
- SkString* fsInOutColor,
- GrSLConstantVec* fsInOutColorKnownValue,
- SkTArray<GrGLCoordTransform, false>* effectCoordTransformArrays[],
- SkTArray<GrGLUniformManager::UniformHandle, true>* effectSamplerHandles[],
- GrGLEffect* glEffects[]) {
+GrGLProgramEffects* GrGLShaderBuilder::createAndEmitEffects(
+ const GrEffectStage* effectStages[],
+ const EffectKey effectKeys[],
+ int effectCnt,
+ SkString* fsInOutColor,
+ GrSLConstantVec* fsInOutColorKnownValue) {
+
+ GrGLProgramEffectsBuilder programEffectsBuilder(this, effectCnt);
bool effectEmitted = false;
SkString inColor = *fsInOutColor;
@@ -589,47 +567,9 @@ void GrGLShaderBuilder::emitEffects(
for (int e = 0; e < effectCnt; ++e) {
SkASSERT(NULL != effectStages[e] && NULL != effectStages[e]->getEffect());
const GrEffectStage& stage = *effectStages[e];
- const GrEffectRef& effect = *stage.getEffect();
CodeStage::AutoStageRestore csar(&fCodeStage, &stage);
- int numTransforms = effect->numTransforms();
- SkSTArray<8, GrGLCoordTransform::TransformedCoords> transformedCoords;
- transformedCoords.push_back_n(numTransforms);
- EffectKey transformKey = GrBackendEffectFactory::GetTransformKey(effectKeys[e]);
- for (int c = 0; c < numTransforms; ++c) {
- GrGLCoordTransform& ct = effectCoordTransformArrays[e]->push_back();
- EffectKey key = (transformKey >> (c * GrGLCoordTransform::kKeyBits)) &
- (GrGLCoordTransform::kKeyMask);
- ct.emitCode(this, key, &transformedCoords[c], c);
- }
-
- int numTextures = effect->numTextures();
- SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers;
- textureSamplers.push_back_n(numTextures);
- for (int t = 0; t < numTextures; ++t) {
- textureSamplers[t].init(this, &effect->textureAccess(t), t);
- effectSamplerHandles[e]->push_back(textureSamplers[t].fSamplerUniform);
- }
-
- GrDrawEffect drawEffect(stage, NULL != fVertexBuilder.get()
- && fVertexBuilder->hasExplicitLocalCoords());
-
- int numAttributes = stage.getVertexAttribIndexCount();
- const int* attributeIndices = stage.getVertexAttribIndices();
- SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames;
- for (int a = 0; a < numAttributes; ++a) {
- // TODO: Make addAttribute mangle the name.
- SkASSERT(NULL != fVertexBuilder.get());
- SkString attributeName("aAttr");
- attributeName.appendS32(attributeIndices[a]);
- fVertexBuilder->addEffectAttribute(attributeIndices[a],
- effect->vertexAttribType(a),
- attributeName);
- }
-
- glEffects[e] = effect->getFactory().createGLInstance(drawEffect);
-
if (kZeros_GrSLConstantVec == *fsInOutColorKnownValue) {
// Effects have no way to communicate zeros, they treat an empty string as ones.
this->nameVariable(&inColor, '\0', "input");
@@ -640,26 +580,11 @@ void GrGLShaderBuilder::emitEffects(
this->nameVariable(&outColor, '\0', "output");
this->fsCodeAppendf("\tvec4 %s;\n", outColor.c_str());
- // Enclose custom code in a block to avoid namespace conflicts
- SkString openBrace;
- openBrace.printf("\t{ // Stage %d: %s\n", fCodeStage.stageIndex(), glEffects[e]->name());
- if (NULL != fVertexBuilder.get()) {
- fVertexBuilder->vsCodeAppend(openBrace.c_str());
- }
- this->fsCodeAppend(openBrace.c_str());
-
- glEffects[e]->emitCode(this,
- drawEffect,
- effectKeys[e],
- outColor.c_str(),
- inColor.isEmpty() ? NULL : inColor.c_str(),
- transformedCoords,
- textureSamplers);
-
- if (NULL != fVertexBuilder.get()) {
- fVertexBuilder->vsCodeAppend("\t}\n");
- }
- this->fsCodeAppend("\t}\n");
+ programEffectsBuilder.emitEffect(stage,
+ effectKeys[e],
+ outColor.c_str(),
+ inColor.isEmpty() ? NULL : inColor.c_str(),
+ fCodeStage.stageIndex());
inColor = outColor;
*fsInOutColorKnownValue = kNone_GrSLConstantVec;
@@ -669,6 +594,8 @@ void GrGLShaderBuilder::emitEffects(
if (effectEmitted) {
*fsInOutColor = outColor;
}
+
+ return programEffectsBuilder.finish();
}
const char* GrGLShaderBuilder::getColorOutputName() const {
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h
index a70a0b04a7..4553ac3a0e 100644
--- a/src/gpu/gl/GrGLShaderBuilder.h
+++ b/src/gpu/gl/GrGLShaderBuilder.h
@@ -13,7 +13,7 @@
#include "GrColor.h"
#include "GrEffect.h"
#include "SkTypes.h"
-#include "gl/GrGLCoordTransform.h"
+#include "gl/GrGLProgramEffects.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLUniformManager.h"
@@ -29,78 +29,10 @@ class GrGLProgramDesc;
*/
class GrGLShaderBuilder {
public:
- /**
- * Passed to GrGLEffects to add texture reads to their shader code.
- */
- class TextureSampler {
- public:
- TextureSampler()
- : fConfigComponentMask(0) {
- // we will memcpy the first 4 bytes from passed in swizzle. This ensures the string is
- // terminated.
- fSwizzle[4] = '\0';
- }
-
- TextureSampler(const TextureSampler& other) { *this = other; }
-
- TextureSampler& operator= (const TextureSampler& other) {
- SkASSERT(0 == fConfigComponentMask);
- SkASSERT(!fSamplerUniform.isValid());
-
- fConfigComponentMask = other.fConfigComponentMask;
- fSamplerUniform = other.fSamplerUniform;
- return *this;
- }
-
- // bitfield of GrColorComponentFlags present in the texture's config.
- uint32_t configComponentMask() const { return fConfigComponentMask; }
-
- const char* swizzle() const { return fSwizzle; }
-
- bool isInitialized() const { return 0 != fConfigComponentMask; }
-
- private:
- // The idx param is used to ensure multiple samplers within a single effect have unique
- // uniform names. swizzle is a four char max string made up of chars 'r', 'g', 'b', and 'a'.
- void init(GrGLShaderBuilder* builder,
- uint32_t configComponentMask,
- const char* swizzle,
- int idx) {
- SkASSERT(!this->isInitialized());
- SkASSERT(0 != configComponentMask);
- SkASSERT(!fSamplerUniform.isValid());
-
- SkASSERT(NULL != builder);
- SkString name;
- name.printf("Sampler%d", idx);
- fSamplerUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
- kSampler2D_GrSLType,
- name.c_str());
- SkASSERT(fSamplerUniform.isValid());
-
- fConfigComponentMask = configComponentMask;
- memcpy(fSwizzle, swizzle, 4);
- }
-
- void init(GrGLShaderBuilder* builder, const GrTextureAccess* access, int idx) {
- SkASSERT(NULL != access);
- this->init(builder,
- GrPixelConfigComponentMask(access->getTexture()->config()),
- access->getSwizzle(),
- idx);
- }
-
- uint32_t fConfigComponentMask;
- char fSwizzle[5];
- GrGLUniformManager::UniformHandle fSamplerUniform;
-
- friend class GrGLShaderBuilder; // to call init().
- };
-
- typedef SkTArray<GrGLCoordTransform::TransformedCoords> TransformedCoordsArray;
- typedef SkTArray<TextureSampler> TextureSamplerArray;
typedef GrTAllocator<GrGLShaderVar> VarArray;
typedef GrBackendEffectFactory::EffectKey EffectKey;
+ typedef GrGLProgramEffects::TextureSampler TextureSampler;
+ typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
enum ShaderVisibility {
kVertex_Visibility = 0x1,
@@ -175,11 +107,6 @@ public:
/** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */
GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); }
- /** Generates a EffectKey for the shader code based on the texture access parameters and the
- capabilities of the GL context. This is useful for keying the shader programs that may
- have multiple representations, based on the type/format of textures used. */
- static EffectKey KeyForTextureAccess(const GrTextureAccess&, const GrGLCaps&);
-
typedef uint8_t DstReadKey;
typedef uint8_t FragPosKey;
@@ -253,24 +180,19 @@ public:
GrSLConstantVec getKnownCoverageValue() const { return fKnownCoverageValue; }
/**
- * Adds code for effects. effectStages contains the effects to add. effectKeys[i] is the key
- * generated from effectStages[i]. An entry in effectStages can be NULL, in which case it is
- * skipped. Moreover, if the corresponding key is GrGLEffect::NoEffectKey then it is skipped.
- * inOutFSColor specifies the input color to the first stage and is updated to be the
- * output color of the last stage. fsInOutColorKnownValue specifies whether the input color
- * has a known constant value and is updated to refer to the status of the output color.
- * The handles to texture samplers for effectStage[i] are added to effectSamplerHandles[i]. The
- * glEffects array is updated to contain the GrGLEffect generated for each entry in
- * effectStages.
+ * Adds code for effects and returns a GrGLProgramEffects* object. The caller is responsible for
+ * deleting it when finished. effectStages contains the effects to add. effectKeys[i] is the key
+ * generated from effectStages[i]. inOutFSColor specifies the input color to the first stage and
+ * is updated to be the output color of the last stage. fsInOutColorKnownValue specifies whether
+ * the input color has a known constant value and is updated to refer to the status of the
+ * output color. The handles to texture samplers for effectStage[i] are added to
+ * effectSamplerHandles[i].
*/
- void emitEffects(const GrEffectStage* effectStages[],
- const EffectKey effectKeys[],
- int effectCnt,
- SkString* inOutFSColor,
- GrSLConstantVec* fsInOutColorKnownValue,
- SkTArray<GrGLCoordTransform, false>* effectCoordTransformArrays[],
- SkTArray<GrGLUniformManager::UniformHandle, true>* effectSamplerHandles[],
- GrGLEffect* glEffects[]);
+ GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
+ const EffectKey effectKeys[],
+ int effectCnt,
+ SkString* inOutFSColor,
+ GrSLConstantVec* fsInOutColorKnownValue);
const char* getColorOutputName() const;
const char* enableSecondaryOutput();
@@ -285,7 +207,7 @@ public:
GrGLUniformManager::UniformHandle getColorUniform() const { return fColorUniform; }
GrGLUniformManager::UniformHandle getCoverageUniform() const { return fCoverageUniform; }
GrGLUniformManager::UniformHandle getDstCopySamplerUniform() const {
- return fDstCopySampler.fSamplerUniform;
+ return fDstCopySamplerUniform;
}
/** Helper class used to build the vertex and geometry shaders. This functionality
@@ -484,7 +406,7 @@ private:
SkString fFSCode;
bool fSetupFragPosition;
- TextureSampler fDstCopySampler;
+ GrGLUniformManager::UniformHandle fDstCopySamplerUniform;
SkString fInputColor;
GrSLConstantVec fKnownColorValue;