aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-03-20 19:19:53 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-03-20 19:19:53 +0000
commitc78188896e28a4ae49e406a7422b345ae177dafe (patch)
tree8345c0828c94fc81cd4c54a0fe7778e5b159394d /src/gpu
parentb8210f20ce3da43f55b773a2fad3f2244d3ba74d (diff)
Attempt to reland 8264-5 with warning-as-error fixes.
git-svn-id: http://skia.googlecode.com/svn/trunk@8272 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrClipMaskManager.cpp10
-rw-r--r--src/gpu/GrContext.cpp51
-rw-r--r--src/gpu/GrDrawState.cpp66
-rw-r--r--src/gpu/GrDrawState.h103
-rw-r--r--src/gpu/GrDrawTarget.cpp27
-rw-r--r--src/gpu/GrDrawTarget.h29
-rw-r--r--src/gpu/GrInOrderDrawBuffer.cpp33
-rw-r--r--src/gpu/GrInOrderDrawBuffer.h5
-rw-r--r--src/gpu/GrSWMaskHelper.cpp25
-rw-r--r--src/gpu/GrTextContext.cpp19
-rw-r--r--src/gpu/effects/GrCircleEdgeEffect.cpp20
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.cpp35
-rw-r--r--src/gpu/effects/GrConvolutionEffect.cpp36
-rw-r--r--src/gpu/effects/GrEllipseEdgeEffect.cpp21
-rw-r--r--src/gpu/effects/GrSimpleTextureEffect.cpp88
-rw-r--r--src/gpu/effects/GrSimpleTextureEffect.h67
-rw-r--r--src/gpu/effects/GrSingleTextureEffect.cpp21
-rw-r--r--src/gpu/effects/GrSingleTextureEffect.h23
-rw-r--r--src/gpu/effects/GrTextureDomainEffect.cpp77
-rw-r--r--src/gpu/effects/GrTextureDomainEffect.h6
-rw-r--r--src/gpu/gl/GrGLEffect.cpp16
-rw-r--r--src/gpu/gl/GrGLEffect.h50
-rw-r--r--src/gpu/gl/GrGLEffectMatrix.cpp87
-rw-r--r--src/gpu/gl/GrGLEffectMatrix.h65
-rw-r--r--src/gpu/gl/GrGLProgram.cpp61
-rw-r--r--src/gpu/gl/GrGLProgram.h2
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp20
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h16
28 files changed, 565 insertions, 514 deletions
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 99068c75ed..6415859db9 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -40,6 +40,9 @@ void setup_drawstate_aaclip(GrGpu* gpu,
static const int kMaskStage = GrPaint::kTotalStages+1;
SkMatrix mat;
+ // We want to use device coords to compute the texture coordinates. We set our matrix to be
+ // equal to the view matrix followed by an offset to the devBound, and then a scaling matrix to
+ // normalized coords. We apply this matrix to the vertex positions rather than local coords.
mat.setIDiv(result->width(), result->height());
mat.preTranslate(SkIntToScalar(-devBound.fLeft),
SkIntToScalar(-devBound.fTop));
@@ -51,7 +54,9 @@ void setup_drawstate_aaclip(GrGpu* gpu,
GrTextureDomainEffect::Create(result,
mat,
GrTextureDomainEffect::MakeTexelDomain(result, domainTexels),
- GrTextureDomainEffect::kDecal_WrapMode))->unref();
+ GrTextureDomainEffect::kDecal_WrapMode,
+ false,
+ GrEffect::kPosition_CoordsType))->unref();
}
bool path_needs_SW_renderer(GrContext* context,
@@ -354,7 +359,8 @@ void GrClipMaskManager::mergeMask(GrTexture* dstMask,
GrTextureDomainEffect::Create(srcMask,
sampleM,
GrTextureDomainEffect::MakeTexelDomain(srcMask, srcBound),
- GrTextureDomainEffect::kDecal_WrapMode))->unref();
+ GrTextureDomainEffect::kDecal_WrapMode,
+ false))->unref();
fGpu->drawSimpleRect(SkRect::MakeFromIRect(dstBound), NULL);
drawState->disableStage(0);
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 4c18574999..4798297a3a 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -360,12 +360,12 @@ GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc,
{kVec2f_GrVertexAttribType, 0},
{kVec2f_GrVertexAttribType, sizeof(GrPoint)}
};
- static const GrAttribBindings kAttribBindings =
- GrDrawState::ExplicitTexCoordAttribBindingsBit(0);
+
+ static const GrAttribBindings kAttribBindings = GrDrawState::kLocalCoords_AttribBindingsBit;
drawState->setAttribBindings(kAttribBindings);
drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
- drawState->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, 1);
+ drawState->setAttribIndex(GrDrawState::kLocalCoords_AttribIndex, 1);
GrDrawTarget::AutoReleaseGeometry arg(fGpu, 4, 0);
if (arg.succeeded()) {
@@ -852,21 +852,15 @@ void GrContext::drawRect(const GrPaint& paint,
void GrContext::drawRectToRect(const GrPaint& paint,
const GrRect& dstRect,
- const GrRect& srcRect,
+ const GrRect& localRect,
const SkMatrix* dstMatrix,
- const SkMatrix* srcMatrix) {
+ const SkMatrix* localMatrix) {
SK_TRACE_EVENT0("GrContext::drawRectToRect");
- // srcRect refers to paint's first color stage
- if (!paint.isColorStageEnabled(0)) {
- drawRect(paint, dstRect, -1, dstMatrix);
- return;
- }
-
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW);
+ GrDrawState::AutoStageDisable atr(fDrawState);
#if GR_STATIC_RECT_VB
- GrDrawState::AutoStageDisable atr(fDrawState);
GrDrawState* drawState = target->drawState();
SkMatrix m;
@@ -878,19 +872,21 @@ void GrContext::drawRectToRect(const GrPaint& paint,
m.postConcat(*dstMatrix);
}
- // The first color stage's coords come from srcRect rather than applying a matrix to dstRect.
- // We explicitly compute a matrix for that stage below, no need to adjust here.
- static const uint32_t kExplicitCoordMask = 1 << GrPaint::kFirstColorStage;
- GrDrawState::AutoViewMatrixRestore avmr(drawState, m, kExplicitCoordMask);
+ // This code path plays a little fast and loose with the notion of local coords and coord
+ // change matrices in order to account for localRect and localMatrix. The unit square VB only
+ // has one set of coords. Rather than using AutoViewMatrixRestore we instead directly set concat
+ // with m and then call GrDrawState::localCoordChange() with a matrix that accounts for
+ // localRect and localMatrix. This code path is preventing some encapsulation in GrDrawState.
+ SkMatrix savedViewMatrix = drawState->getViewMatrix();
+ drawState->preConcatViewMatrix(m);
- m.setAll(srcRect.width(), 0, srcRect.fLeft,
- 0, srcRect.height(), srcRect.fTop,
- 0, 0, SkMatrix::I()[8]);
- if (NULL != srcMatrix) {
- m.postConcat(*srcMatrix);
+ m.setAll(localRect.width(), 0, localRect.fLeft,
+ 0, localRect.height(), localRect.fTop,
+ 0, 0, SkMatrix::I()[8]);
+ if (NULL != localMatrix) {
+ m.postConcat(*localMatrix);
}
-
- drawState->preConcatStageMatrices(kExplicitCoordMask, m);
+ drawState->localCoordChange(m);
const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer();
if (NULL == sqVB) {
@@ -900,10 +896,9 @@ void GrContext::drawRectToRect(const GrPaint& paint,
drawState->setDefaultVertexAttribs();
target->setVertexSourceToBuffer(sqVB);
target->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
+ drawState->setViewMatrix(savedViewMatrix);
#else
- GrDrawState::AutoStageDisable atr(fDrawState);
-
- target->drawRect(dstRect, dstMatrix, &srcRect, srcMatrix, 0);
+ target->drawRect(dstRect, dstMatrix, &localRect, localMatrix);
#endif
}
@@ -937,8 +932,8 @@ void GrContext::drawVertices(const GrPaint& paint,
// set up optional texture coordinate attributes
if (NULL != texCoords) {
- bindings |= GrDrawState::ExplicitTexCoordAttribBindingsBit(0);
- drawState->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, attribs.count());
+ bindings |= GrDrawState::kLocalCoords_AttribBindingsBit;
+ drawState->setAttribIndex(GrDrawState::kLocalCoords_AttribIndex, attribs.count());
currAttrib.set(kVec2f_GrVertexAttribType, currentOffset);
attribs.push_back(currAttrib);
texOffset = currentOffset;
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index cd5fe1c0d6..79829357ba 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -46,28 +46,6 @@ void GrDrawState::setFromPaint(const GrPaint& paint) {
////////////////////////////////////////////////////////////////////////////////
-namespace {
-
-/**
- * This function generates a mask that we like to have known at compile
- * time. When the number of stages is bumped or the way bits are defined in
- * GrDrawState.h changes this function should be rerun to generate the new mask.
- * (We attempted to force the compiler to generate the mask using recursive
- * templates but always wound up with static initializers under gcc, even if
- * they were just a series of immediate->memory moves.)
- *
- */
-void gen_tex_coord_mask(GrAttribBindings* texCoordMask) {
- *texCoordMask = 0;
- for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- *texCoordMask |= GrDrawState::ExplicitTexCoordAttribBindingsBit(s);
- }
-}
-
-const GrAttribBindings kTexCoord_AttribBindingsMask = (1 << GrDrawState::kNumStages)-1;
-
-} //unnamed namespace
-
const size_t GrDrawState::kVertexAttribSizes[kGrVertexAttribTypeCount] = {
sizeof(float), // kFloat_GrVertexAttribType
2*sizeof(float), // kVec2_GrVertexAttribType
@@ -106,7 +84,7 @@ const GrAttribBindings GrDrawState::kAttribIndexMasks[kAttribIndexCount] = {
kColor_AttribBindingsBit,
kCoverage_AttribBindingsBit,
kEdge_AttribBindingsBit,
- kTexCoord_AttribBindingsMask
+ kLocalCoords_AttribBindingsBit,
};
////////////////////////////////////////////////////////////////////////////////
@@ -210,20 +188,8 @@ bool GrDrawState::validateVertexAttribs() const {
return true;
}
-////////////////////////////////////////////////////////////////////////////////
-
-bool GrDrawState::AttributesBindExplicitTexCoords(GrAttribBindings attribBindings) {
- return SkToBool(kTexCoord_AttribBindingsMask & attribBindings);
-}
-
-////////////////////////////////////////////////////////////////////////////////
void GrDrawState::VertexAttributesUnitTest() {
- // Ensure that our tex coord mask is correct
- GrAttribBindings texCoordMask;
- gen_tex_coord_mask(&texCoordMask);
- GrAssert(texCoordMask == kTexCoord_AttribBindingsMask);
-
// not necessarily exhaustive
static bool run;
if (!run) {
@@ -259,27 +225,11 @@ void GrDrawState::VertexAttributesUnitTest() {
attribs.push_back(currAttrib);
GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) + sizeof(float) + 4*sizeof(float) ==
vertex_size(attribs.begin(), attribs.count()));
-
- GrAttribBindings tcMask = 0;
- GrAssert(!AttributesBindExplicitTexCoords(0));
- for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- tcMask |= ExplicitTexCoordAttribBindingsBit(s);
- GrAssert(AttributesBindExplicitTexCoords(tcMask));
- GrAssert(StageBindsExplicitTexCoords(tcMask, s));
- for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) {
- GrAssert(!StageBindsExplicitTexCoords(tcMask, s2));
- }
- }
- GrAssert(kTexCoord_AttribBindingsMask == tcMask);
}
}
////////////////////////////////////////////////////////////////////////////////
-bool GrDrawState::StageBindsExplicitTexCoords(GrAttribBindings bindings, int stageIdx) {
- return SkToBool(bindings & ExplicitTexCoordAttribBindingsBit(stageIdx));
-}
-
bool GrDrawState::srcAlphaWillBeOne(GrAttribBindings bindings) const {
uint32_t validComponentFlags;
@@ -500,8 +450,7 @@ void GrDrawState::AutoViewMatrixRestore::restore() {
}
void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
- const SkMatrix& preconcatMatrix,
- uint32_t explicitCoordStageMask) {
+ const SkMatrix& preconcatMatrix) {
this->restore();
fDrawState = drawState;
@@ -513,10 +462,10 @@ void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
fViewMatrix = drawState->getViewMatrix();
drawState->preConcatViewMatrix(preconcatMatrix);
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) {
+ if (drawState->isStageEnabled(s)) {
fRestoreMask |= (1 << s);
fDrawState->fStages[s].saveCoordChange(&fSavedCoordChanges[s]);
- drawState->fStages[s].preConcatCoordChange(preconcatMatrix);
+ drawState->fStages[s].localCoordChange(preconcatMatrix);
}
}
}
@@ -535,8 +484,7 @@ void GrDrawState::AutoDeviceCoordDraw::restore() {
fDrawState = NULL;
}
-bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState,
- uint32_t explicitCoordStageMask) {
+bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState) {
GrAssert(NULL != drawState);
this->restore();
@@ -552,7 +500,7 @@ bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState,
bool inverted = false;
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) {
+ if (drawState->isStageEnabled(s)) {
if (!inverted && !fViewMatrix.invert(&invVM)) {
// sad trombone sound
fDrawState = NULL;
@@ -563,7 +511,7 @@ bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState,
fRestoreMask |= (1 << s);
GrEffectStage* stage = drawState->fStages + s;
stage->saveCoordChange(&fSavedCoordChanges[s]);
- stage->preConcatCoordChange(invVM);
+ stage->localCoordChange(invVM);
}
}
drawState->viewMatrix()->reset();
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 2203e889e3..ffa7b093bb 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -257,38 +257,26 @@ public:
/**
* The vertex data used by the current program is represented as a bitfield
* of flags. Programs always use positions and may also use texture
- * coordinates, per-vertex colors, per-vertex coverage and edge data. Each
- * stage can use the explicit texture coordinates as its input texture
- * coordinates or it may use the positions as texture coordinates.
+ * coordinates, per-vertex colors, per-vertex coverage and edge data. The
+ * local coords accessible by effects may either come from positions or
+ * be specified explicitly.
*/
/**
- * Generates a bit indicating that a texture stage uses texture coordinates
- *
- * @param stageIdx the stage that will use texture coordinates.
- *
- * @return the bit to add to a GrAttribBindings bitfield.
- */
- static int ExplicitTexCoordAttribBindingsBit(int stageIdx) {
- GrAssert(stageIdx < kNumStages);
- return (1 << stageIdx);
- }
-
- static bool StageBindsExplicitTexCoords(GrAttribBindings bindings, int stageIdx);
-
- /**
* Additional Bits that can be specified in GrAttribBindings.
*/
enum AttribBindingsBits {
+ /** explicit local coords are provided (instead of using pre-view-matrix positions) */
+ kLocalCoords_AttribBindingsBit = 0x1,
/* program uses colors (GrColor) */
- kColor_AttribBindingsBit = 1 << (kNumStages + 0),
+ kColor_AttribBindingsBit = 0x2,
/* program uses coverage (GrColor)
*/
- kCoverage_AttribBindingsBit = 1 << (kNumStages + 1),
+ kCoverage_AttribBindingsBit = 0x4,
/* program uses edge data. Distance to the edge is used to
* compute a coverage. See GrDrawState::setVertexEdgeType().
*/
- kEdge_AttribBindingsBit = 1 << (kNumStages + 2),
+ kEdge_AttribBindingsBit = 0x8,
// for below assert
kDummyAttribBindingsBit,
kHighAttribBindingsBit = kDummyAttribBindingsBit - 1
@@ -313,17 +301,6 @@ public:
// Helpers for picking apart attribute bindings
/**
- * Helper function to determine if program uses explicit texture
- * coordinates.
- *
- * @param bindings attribute bindings to query
- *
- * @return true if program uses texture coordinates,
- * false otherwise.
- */
- static bool AttributesBindExplicitTexCoords(GrAttribBindings bindings);
-
- /**
* Determines whether src alpha is guaranteed to be one for all src pixels
*/
bool srcAlphaWillBeOne(GrAttribBindings) const;
@@ -356,9 +333,9 @@ public:
kColor_AttribIndex,
kCoverage_AttribIndex,
kEdge_AttribIndex,
- kTexCoord_AttribIndex,
+ kLocalCoords_AttribIndex,
- kLast_AttribIndex = kTexCoord_AttribIndex
+ kLast_AttribIndex = kLocalCoords_AttribIndex
};
static const int kAttribIndexCount = kLast_AttribIndex + 1;
@@ -410,7 +387,7 @@ public:
/**
* Add a color filter that can be represented by a color and a mode. Applied
- * after color-computing texture stages.
+ * after color-computing effect stages.
*/
void setColorFilter(GrColor c, SkXfermode::Mode mode) {
fCommon.fColorFilterColor = c;
@@ -497,7 +474,7 @@ public:
}
/**
- * Creates a GrSimpleTextureEffect.
+ * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
*/
void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) {
GrAssert(!this->getStage(stageIdx).getEffect());
@@ -556,42 +533,16 @@ public:
}
/**
- * Called when the source coord system is changing. preConcat gives the transformation from the
- * old coord system to the new coord system.
+ * Called when the source coord system is changing. This ensures that effects will see the
+ * correct local coordinates. oldToNew gives the transformation from the old coord system in
+ * which the geometry was specified to the new coordinate system from which it will be rendered.
*/
- void preConcatStageMatrices(const SkMatrix& preConcat) {
- this->preConcatStageMatrices(~0U, preConcat);
- }
- /**
- * Version of above that applies the update matrix selectively to stages via a mask.
- */
- void preConcatStageMatrices(uint32_t stageMask, const SkMatrix& preConcat) {
- for (int i = 0; i < kNumStages; ++i) {
- if (((1 << i) & stageMask) && this->isStageEnabled(i)) {
- fStages[i].preConcatCoordChange(preConcat);
- }
- }
- }
-
- /**
- * Called when the source coord system is changing. preConcatInverse is the inverse of the
- * transformation from the old coord system to the new coord system. Returns false if the matrix
- * cannot be inverted.
- */
- bool preConcatStageMatricesWithInverse(const SkMatrix& preConcatInverse) {
- SkMatrix inv;
- bool computed = false;
+ void localCoordChange(const SkMatrix& oldToNew) {
for (int i = 0; i < kNumStages; ++i) {
if (this->isStageEnabled(i)) {
- if (!computed && !preConcatInverse.invert(&inv)) {
- return false;
- } else {
- computed = true;
- }
- fStages[i].preConcatCoordChange(preConcatInverse);
+ fStages[i].localCoordChange(oldToNew);
}
}
- return true;
}
/// @}
@@ -832,11 +783,9 @@ public:
public:
AutoViewMatrixRestore() : fDrawState(NULL) {}
- AutoViewMatrixRestore(GrDrawState* ds,
- const SkMatrix& preconcatMatrix,
- uint32_t explicitCoordStageMask = 0) {
+ AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) {
fDrawState = NULL;
- this->set(ds, preconcatMatrix, explicitCoordStageMask);
+ this->set(ds, preconcatMatrix);
}
~AutoViewMatrixRestore() { this->restore(); }
@@ -846,9 +795,7 @@ public:
*/
void restore();
- void set(GrDrawState* drawState,
- const SkMatrix& preconcatMatrix,
- uint32_t explicitCoordStageMask = 0);
+ void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix);
bool isSet() const { return NULL != fDrawState; }
@@ -875,15 +822,14 @@ public:
* positions, then we don't want to modify its matrix. The explicitCoordStageMask is used
* to specify such stages.
*/
- AutoDeviceCoordDraw(GrDrawState* drawState,
- uint32_t explicitCoordStageMask = 0) {
+ AutoDeviceCoordDraw(GrDrawState* drawState) {
fDrawState = NULL;
- this->set(drawState, explicitCoordStageMask);
+ this->set(drawState);
}
~AutoDeviceCoordDraw() { this->restore(); }
- bool set(GrDrawState* drawState, uint32_t explicitCoordStageMask = 0);
+ bool set(GrDrawState* drawState);
/**
* Returns true if this object was successfully initialized on to a GrDrawState. It may
@@ -1197,8 +1143,7 @@ public:
return false;
}
for (int i = 0; i < kAttribIndexCount; ++i) {
- if ((i == kPosition_AttribIndex ||
- s.fCommon.fAttribBindings & kAttribIndexMasks[i]) &&
+ if ((i == kPosition_AttribIndex || s.fCommon.fAttribBindings & (1 << i)) &&
fAttribIndices[i] != s.fAttribIndices[i]) {
return false;
}
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 6fdc3a080f..cd4d4d2007 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -529,11 +529,9 @@ void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
void GrDrawTarget::drawRect(const GrRect& rect,
const SkMatrix* matrix,
- const GrRect* srcRect,
- const SkMatrix* srcMatrix,
- int stage) {
+ const GrRect* localRect,
+ const SkMatrix* localMatrix) {
GrAttribBindings bindings = 0;
- uint32_t explicitCoordMask = 0;
// position + (optional) texture coord
static const GrVertexAttrib kAttribs[] = {
{kVec2f_GrVertexAttribType, 0},
@@ -541,16 +539,15 @@ void GrDrawTarget::drawRect(const GrRect& rect,
};
int attribCount = 1;
- if (NULL != srcRect) {
- bindings |= GrDrawState::ExplicitTexCoordAttribBindingsBit(stage);
+ if (NULL != localRect) {
+ bindings |= GrDrawState::kLocalCoords_AttribBindingsBit;
attribCount = 2;
- this->drawState()->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, 1);
- explicitCoordMask = (1 << stage);
+ this->drawState()->setAttribIndex(GrDrawState::kLocalCoords_AttribIndex, 1);
}
GrDrawState::AutoViewMatrixRestore avmr;
if (NULL != matrix) {
- avmr.set(this->drawState(), *matrix, explicitCoordMask);
+ avmr.set(this->drawState(), *matrix);
}
this->drawState()->setVertexAttribs(kAttribs, attribCount);
@@ -564,15 +561,15 @@ void GrDrawTarget::drawRect(const GrRect& rect,
size_t vsize = this->drawState()->getVertexSize();
geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
- if (NULL != srcRect) {
+ if (NULL != localRect) {
GrAssert(attribCount == 2);
GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
kAttribs[1].fOffset);
- coords->setRectFan(srcRect->fLeft, srcRect->fTop,
- srcRect->fRight, srcRect->fBottom,
- vsize);
- if (NULL != srcMatrix) {
- srcMatrix->mapPointsWithStride(coords, vsize, 4);
+ coords->setRectFan(localRect->fLeft, localRect->fTop,
+ localRect->fRight, localRect->fBottom,
+ vsize);
+ if (NULL != localMatrix) {
+ localMatrix->mapPointsWithStride(coords, vsize, 4);
}
}
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index a011aaef99..de8c5c4580 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -388,8 +388,8 @@ public:
/**
* Helper function for drawing rects. This does not use the current index
* and vertex sources. After returning, the vertex and index sources may
- * have changed. They should be reestablished before the next drawIndexed
- * or drawNonIndexed. This cannot be called between reserving and releasing
+ * have changed. They should be reestablished before the next draw call.
+ * This cannot be called between reserving and releasing
* geometry.
*
* A subclass may override this to perform more optimal rect rendering. Its
@@ -397,34 +397,29 @@ public:
* (e.g. drawNonIndexed, drawIndexedInstances, ...). The base class draws a two
* triangle fan using drawNonIndexed from reserved vertex space.
*
- * @param rect the rect to draw
- * @param matrix optional matrix applied to rect (before viewMatrix)
- * @param srcRects specifies rect for explicit texture coordinates.
- * if srcRect is non-NULL then that rect will be used
- * as the coordinates for the given stage.
- * @param srcMatrix optional matrix applied to srcRect. If
+ * @param rect the rect to draw
+ * @param matrix optional matrix applied to rect (before viewMatrix)
+ * @param localRect optional rect that specifies local coords to map onto
+ * rect. If NULL then rect serves as the local coords.
+ * @param localMatrix optional matrix applied to localRect. If
* srcRect is non-NULL and srcMatrix is non-NULL
* then srcRect will be transformed by srcMatrix.
* srcMatrix can be NULL when no srcMatrix is desired.
- * @param stage the stage to be given explicit texture coordinates.
- * Ignored if srcRect is NULL.
*/
virtual void drawRect(const GrRect& rect,
const SkMatrix* matrix,
- const GrRect* srcRect,
- const SkMatrix* srcMatrix,
- int stage);
+ const GrRect* localRect,
+ const SkMatrix* localMatrix);
/**
- * Helper for drawRect when the caller doesn't need separate src rects or
- * matrices.
+ * Helper for drawRect when the caller doesn't need separate local rects or matrices.
*/
void drawSimpleRect(const GrRect& rect, const SkMatrix* matrix = NULL) {
- drawRect(rect, matrix, NULL, NULL, 0);
+ drawRect(rect, matrix, NULL, NULL);
}
void drawSimpleRect(const GrIRect& irect, const SkMatrix* matrix = NULL) {
SkRect rect = SkRect::MakeFromIRect(irect);
- this->drawRect(rect, matrix, NULL, NULL, 0);
+ this->drawRect(rect, matrix, NULL, NULL);
}
/**
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 31b1a57c1f..6966858eae 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -74,9 +74,8 @@ void get_vertex_bounds(const void* vertices,
void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
const SkMatrix* matrix,
- const GrRect* srcRect,
- const SkMatrix* srcMatrix,
- int stage) {
+ const GrRect* localRect,
+ const SkMatrix* localMatrix) {
GrAttribBindings bindings = GrDrawState::kDefault_AttribBindings;
GrDrawState::AutoColorRestore acr;
@@ -86,7 +85,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
GrColor color = drawState->getColor();
GrVertexAttribArray<3> attribs;
size_t currentOffset = 0;
- int colorOffset = -1, texOffset = -1;
+ int colorOffset = -1, localOffset = -1;
// set position attrib
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, attribs.count());
@@ -115,15 +114,13 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
acr.set(drawState, 0xFFFFFFFF);
}
- uint32_t explicitCoordMask = 0;
- if (NULL != srcRect) {
- bindings |= GrDrawState::ExplicitTexCoordAttribBindingsBit(stage);
- drawState->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, attribs.count());
+ if (NULL != localRect) {
+ bindings |= GrDrawState::kLocalCoords_AttribBindingsBit;
+ drawState->setAttribIndex(GrDrawState::kLocalCoords_AttribIndex, attribs.count());
currAttrib.set(kVec2f_GrVertexAttribType, currentOffset);
attribs.push_back(currAttrib);
- texOffset = currentOffset;
+ localOffset = currentOffset;
currentOffset += sizeof(GrPoint);
- explicitCoordMask = (1 << stage);
}
drawState->setVertexAttribs(attribs.begin(), attribs.count());
@@ -145,7 +142,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
// When the caller has provided an explicit source rect for a stage then we don't want to
// modify that stage's matrix. Otherwise if the effect is generating its source rect from
// the vertex positions then we have to account for the view matrix change.
- GrDrawState::AutoDeviceCoordDraw adcd(drawState, explicitCoordMask);
+ GrDrawState::AutoDeviceCoordDraw adcd(drawState);
if (!adcd.succeeded()) {
return;
}
@@ -161,15 +158,13 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
// unnecessary clipping in our onDraw().
get_vertex_bounds(geo.vertices(), vsize, 4, &devBounds);
- if (texOffset >= 0) {
- GrAssert(explicitCoordMask != 0);
- GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
- texOffset);
- coords->setRectFan(srcRect->fLeft, srcRect->fTop,
- srcRect->fRight, srcRect->fBottom,
+ if (localOffset >= 0) {
+ GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) + localOffset);
+ coords->setRectFan(localRect->fLeft, localRect->fTop,
+ localRect->fRight, localRect->fBottom,
vsize);
- if (NULL != srcMatrix) {
- srcMatrix->mapPointsWithStride(coords, vsize, 4);
+ if (NULL != localMatrix) {
+ localMatrix->mapPointsWithStride(coords, vsize, 4);
}
}
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index f04bb846d6..cb51bc4672 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -78,9 +78,8 @@ public:
GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
virtual void drawRect(const GrRect& rect,
const SkMatrix* matrix,
- const GrRect* srcRect,
- const SkMatrix* srcMatrix,
- int stage) SK_OVERRIDE;
+ const GrRect* localRect,
+ const SkMatrix* localMatrix) SK_OVERRIDE;
protected:
virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE;
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index fe9fd8228b..2cf56d63d6 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -197,18 +197,29 @@ void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture,
// && edge rendering (kEdgeEffectStage in GrContext)
kPathMaskStage = GrPaint::kTotalStages,
};
- GrAssert(!drawState->isStageEnabled(kPathMaskStage));
- drawState->createTextureEffect(kPathMaskStage, texture, SkMatrix::I());
- SkScalar w = SkIntToScalar(rect.width());
- SkScalar h = SkIntToScalar(rect.height());
- GrRect maskRect = GrRect::MakeWH(w / texture->width(),
- h / texture->height());
GrRect dstRect = GrRect::MakeLTRB(
SK_Scalar1 * rect.fLeft,
SK_Scalar1 * rect.fTop,
SK_Scalar1 * rect.fRight,
SK_Scalar1 * rect.fBottom);
- target->drawRect(dstRect, NULL, &maskRect, NULL, kPathMaskStage);
+
+ // We want to use device coords to compute the texture coordinates. We set our matrix to be
+ // equal to the view matrix followed by a translation so that the top-left of the device bounds
+ // maps to 0,0, and then a scaling matrix to normalized coords. We apply this matrix to the
+ // vertex positions rather than local coords.
+ SkMatrix maskMatrix;
+ maskMatrix.setIDiv(texture->width(), texture->height());
+ maskMatrix.preTranslate(SkIntToScalar(-rect.fLeft), SkIntToScalar(-rect.fTop));
+ maskMatrix.preConcat(drawState->getViewMatrix());
+
+ GrAssert(!drawState->isStageEnabled(kPathMaskStage));
+ drawState->setEffect(kPathMaskStage,
+ GrSimpleTextureEffect::Create(texture,
+ maskMatrix,
+ false,
+ GrEffect::kPosition_CoordsType))->unref();
+
+ target->drawSimpleRect(dstRect);
drawState->disableStage(kPathMaskStage);
}
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index 5ff13b0fdc..ab2bc424d6 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -18,12 +18,10 @@
#include "SkPath.h"
#include "SkStrokeRec.h"
-enum {
- // glyph rendering shares this stage with edge rendering
- // (kEdgeEffectStage in GrContext) && SW path rendering
- // (kPathMaskStage in GrSWMaskHelper)
- kGlyphMaskStage = GrPaint::kTotalStages,
-};
+// glyph rendering shares this stage with edge rendering (kEdgeEffectStage in GrContext) && SW path
+// rendering (kPathMaskStage in GrSWMaskHelper)
+static const int kGlyphMaskStage = GrPaint::kTotalStages;
+static const int kGlyphCoordsAttributeIndex = 1;
void GrTextContext::flushGlyphs() {
if (NULL == fDrawTarget) {
@@ -35,7 +33,11 @@ void GrTextContext::flushGlyphs() {
GrAssert(GrIsALIGN4(fCurrVertex));
GrAssert(fCurrTexture);
GrTextureParams params(SkShader::kRepeat_TileMode, false);
- drawState->createTextureEffect(kGlyphMaskStage, fCurrTexture, SkMatrix::I(), params);
+
+ // This effect could be stored with one of the cache objects (atlas?)
+ drawState->setEffect(kGlyphMaskStage,
+ GrSimpleTextureEffect::CreateWithCustomCoords(fCurrTexture, params),
+ kGlyphCoordsAttributeIndex)->unref();
if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
@@ -195,7 +197,7 @@ HAS_ATLAS:
{kVec2f_GrVertexAttribType, 0},
{kVec2f_GrVertexAttribType, sizeof(GrPoint)}
};
- static const GrAttribBindings kAttribBindings = GrDrawState::ExplicitTexCoordAttribBindingsBit(kGlyphMaskStage);
+ static const GrAttribBindings kAttribBindings = 0;
// If we need to reserve vertices allow the draw target to suggest
// a number of verts to reserve and whether to perform a flush.
@@ -214,7 +216,6 @@ HAS_ATLAS:
fDrawTarget->drawState()->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
}
fDrawTarget->drawState()->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
- fDrawTarget->drawState()->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, 1);
fDrawTarget->drawState()->setAttribBindings(kAttribBindings);
fMaxVertices = kDefaultRequestedVerts;
// ignore return, no point in flushing again.
diff --git a/src/gpu/effects/GrCircleEdgeEffect.cpp b/src/gpu/effects/GrCircleEdgeEffect.cpp
index ba7350226b..4ecdedbcde 100644
--- a/src/gpu/effects/GrCircleEdgeEffect.cpp
+++ b/src/gpu/effects/GrCircleEdgeEffect.cpp
@@ -17,29 +17,27 @@
class GrGLCircleEdgeEffect : public GrGLEffect {
public:
- GrGLCircleEdgeEffect(const GrBackendEffectFactory& factory, const GrEffectRef&)
+ GrGLCircleEdgeEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
: INHERITED (factory) {}
virtual void emitCode(GrGLShaderBuilder* builder,
- const GrEffectStage& stage,
+ const GrDrawEffect& drawEffect,
EffectKey key,
- const char* vertexCoords,
const char* outputColor,
const char* inputColor,
const TextureSamplerArray& samplers) SK_OVERRIDE {
- const GrCircleEdgeEffect& effect = GetEffectFromStage<GrCircleEdgeEffect>(stage);
-
+ const GrCircleEdgeEffect& circleEffect = drawEffect.castEffect<GrCircleEdgeEffect>();
const char *vsName, *fsName;
builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName);
const SkString* attrName =
- builder->getEffectAttributeName(stage.getVertexAttribIndices()[0]);
+ builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
builder->fsCodeAppendf("\tfloat d = distance(%s.xy, %s.xy);\n",
builder->fragmentPosition(), fsName);
builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0);\n", fsName);
- if (effect.isStroked()) {
+ if (circleEffect.isStroked()) {
builder->fsCodeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0, 1.0);\n", fsName);
builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n");
}
@@ -48,13 +46,13 @@ public:
builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
}
- static inline EffectKey GenKey(const GrEffectStage& stage, const GrGLCaps&) {
- const GrCircleEdgeEffect& effect = GetEffectFromStage<GrCircleEdgeEffect>(stage);
+ static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+ const GrCircleEdgeEffect& circleEffect = drawEffect.castEffect<GrCircleEdgeEffect>();
- return effect.isStroked() ? 0x1 : 0x0;
+ return circleEffect.isStroked() ? 0x1 : 0x0;
}
- virtual void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) SK_OVERRIDE {
+ virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {
}
private:
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index 5cc05e2f39..df8ab8d835 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -16,21 +16,22 @@
class GrGLConfigConversionEffect : public GrGLEffect {
public:
GrGLConfigConversionEffect(const GrBackendEffectFactory& factory,
- const GrEffectRef& s) : INHERITED (factory) {
- const GrConfigConversionEffect& effect = CastEffect<GrConfigConversionEffect>(s);
+ const GrDrawEffect& drawEffect)
+ : INHERITED (factory)
+ , fEffectMatrix(drawEffect.castEffect<GrConfigConversionEffect>().coordsType()) {
+ const GrConfigConversionEffect& effect = drawEffect.castEffect<GrConfigConversionEffect>();
fSwapRedAndBlue = effect.swapsRedAndBlue();
fPMConversion = effect.pmConversion();
}
virtual void emitCode(GrGLShaderBuilder* builder,
- const GrEffectStage&,
+ const GrDrawEffect&,
EffectKey key,
- const char* vertexCoords,
const char* outputColor,
const char* inputColor,
const TextureSamplerArray& samplers) SK_OVERRIDE {
const char* coords;
- GrSLType coordsType = fEffectMatrix.emitCode(builder, key, vertexCoords, &coords);
+ GrSLType coordsType = fEffectMatrix.emitCode(builder, key, &coords);
builder->fsCodeAppendf("\t\t%s = ", outputColor);
builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType,
samplers[0],
@@ -71,23 +72,19 @@ public:
builder->fsCodeAppend(modulate.c_str());
}
- void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
- const GrConfigConversionEffect& effect =
- GetEffectFromStage<GrConfigConversionEffect>(stage);
- fEffectMatrix.setData(uman,
- effect.getMatrix(),
- stage.getCoordChangeMatrix(),
- effect.texture(0));
+ void setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
+ const GrConfigConversionEffect& conv = drawEffect.castEffect<GrConfigConversionEffect>();
+ fEffectMatrix.setData(uman, conv.getMatrix(), drawEffect, conv.texture(0));
}
- static inline EffectKey GenKey(const GrEffectStage& s, const GrGLCaps&) {
- const GrConfigConversionEffect& effect = GetEffectFromStage<GrConfigConversionEffect>(s);
- EffectKey key = static_cast<EffectKey>(effect.swapsRedAndBlue()) |
- (effect.pmConversion() << 1);
+ static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+ const GrConfigConversionEffect& conv = drawEffect.castEffect<GrConfigConversionEffect>();
+ EffectKey key = static_cast<EffectKey>(conv.swapsRedAndBlue()) | (conv.pmConversion() << 1);
key <<= GrGLEffectMatrix::kKeyBits;
- EffectKey matrixKey = GrGLEffectMatrix::GenKey(effect.getMatrix(),
- s.getCoordChangeMatrix(),
- effect.texture(0));
+ EffectKey matrixKey = GrGLEffectMatrix::GenKey(conv.getMatrix(),
+ drawEffect,
+ conv.coordsType(),
+ conv.texture(0));
GrAssert(!(matrixKey & key));
return matrixKey | key;
}
diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp
index 794a9367df..924b03c177 100644
--- a/src/gpu/effects/GrConvolutionEffect.cpp
+++ b/src/gpu/effects/GrConvolutionEffect.cpp
@@ -18,19 +18,18 @@ static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidU
class GrGLConvolutionEffect : public GrGLEffect {
public:
- GrGLConvolutionEffect(const GrBackendEffectFactory&, const GrEffectRef&);
+ GrGLConvolutionEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
virtual void emitCode(GrGLShaderBuilder*,
- const GrEffectStage&,
+ const GrDrawEffect&,
EffectKey,
- const char* vertexCoords,
const char* outputColor,
const char* inputColor,
const TextureSamplerArray&) SK_OVERRIDE;
- virtual void setData(const GrGLUniformManager& uman, const GrEffectStage&) SK_OVERRIDE;
+ virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect&) SK_OVERRIDE;
- static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
+ static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
private:
int width() const { return Gr1DKernelEffect::WidthFromRadius(fRadius); }
@@ -44,23 +43,23 @@ private:
};
GrGLConvolutionEffect::GrGLConvolutionEffect(const GrBackendEffectFactory& factory,
- const GrEffectRef& effect)
+ const GrDrawEffect& drawEffect)
: INHERITED(factory)
, fKernelUni(kInvalidUniformHandle)
- , fImageIncrementUni(kInvalidUniformHandle) {
- const GrConvolutionEffect& c = CastEffect<GrConvolutionEffect>(effect);
+ , fImageIncrementUni(kInvalidUniformHandle)
+ , fEffectMatrix(drawEffect.castEffect<GrConvolutionEffect>().coordsType()) {
+ const GrConvolutionEffect& c = drawEffect.castEffect<GrConvolutionEffect>();
fRadius = c.radius();
}
void GrGLConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
- const GrEffectStage&,
+ const GrDrawEffect&,
EffectKey key,
- const char* vertexCoords,
const char* outputColor,
const char* inputColor,
const TextureSamplerArray& samplers) {
const char* coords;
- fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords);
+ fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kVec2f_GrSLType, "ImageIncrement");
fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_ShaderType,
@@ -90,8 +89,9 @@ void GrGLConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
builder->fsCodeAppend(modulate.c_str());
}
-void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
- const GrConvolutionEffect& conv = GetEffectFromStage<GrConvolutionEffect>(stage);
+void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman,
+ const GrDrawEffect& drawEffect) {
+ const GrConvolutionEffect& conv = drawEffect.castEffect<GrConvolutionEffect>();
GrTexture& texture = *conv.texture(0);
// the code we generated was for a specific kernel radius
GrAssert(conv.radius() == fRadius);
@@ -108,15 +108,17 @@ void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman, const GrEffe
}
uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement);
uman.set1fv(fKernelUni, 0, this->width(), conv.kernel());
- fEffectMatrix.setData(uman, conv.getMatrix(), stage.getCoordChangeMatrix(), conv.texture(0));
+ fEffectMatrix.setData(uman, conv.getMatrix(), drawEffect, conv.texture(0));
}
-GrGLEffect::EffectKey GrGLConvolutionEffect::GenKey(const GrEffectStage& s, const GrGLCaps&) {
- const GrConvolutionEffect& conv = GetEffectFromStage<GrConvolutionEffect>(s);
+GrGLEffect::EffectKey GrGLConvolutionEffect::GenKey(const GrDrawEffect& drawEffect,
+ const GrGLCaps&) {
+ const GrConvolutionEffect& conv = drawEffect.castEffect<GrConvolutionEffect>();
EffectKey key = conv.radius();
key <<= GrGLEffectMatrix::kKeyBits;
EffectKey matrixKey = GrGLEffectMatrix::GenKey(conv.getMatrix(),
- s.getCoordChangeMatrix(),
+ drawEffect,
+ conv.coordsType(),
conv.texture(0));
return key | matrixKey;
}
diff --git a/src/gpu/effects/GrEllipseEdgeEffect.cpp b/src/gpu/effects/GrEllipseEdgeEffect.cpp
index 37432f0565..12f3197d55 100644
--- a/src/gpu/effects/GrEllipseEdgeEffect.cpp
+++ b/src/gpu/effects/GrEllipseEdgeEffect.cpp
@@ -15,29 +15,28 @@
class GrGLEllipseEdgeEffect : public GrGLEffect {
public:
- GrGLEllipseEdgeEffect(const GrBackendEffectFactory& factory, const GrEffectRef&)
+ GrGLEllipseEdgeEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
: INHERITED (factory) {}
virtual void emitCode(GrGLShaderBuilder* builder,
- const GrEffectStage& stage,
+ const GrDrawEffect& drawEffect,
EffectKey key,
- const char* vertexCoords,
const char* outputColor,
const char* inputColor,
const TextureSamplerArray& samplers) SK_OVERRIDE {
- const GrEllipseEdgeEffect& effect = GetEffectFromStage<GrEllipseEdgeEffect>(stage);
+ const GrEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<GrEllipseEdgeEffect>();
const char *vsCenterName, *fsCenterName;
const char *vsEdgeName, *fsEdgeName;
builder->addVarying(kVec2f_GrSLType, "EllipseCenter", &vsCenterName, &fsCenterName);
const SkString* attr0Name =
- builder->getEffectAttributeName(stage.getVertexAttribIndices()[0]);
+ builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
builder->vsCodeAppendf("\t%s = %s;\n", vsCenterName, attr0Name->c_str());
builder->addVarying(kVec4f_GrSLType, "EllipseEdge", &vsEdgeName, &fsEdgeName);
const SkString* attr1Name =
- builder->getEffectAttributeName(stage.getVertexAttribIndices()[1]);
+ builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]);
builder->vsCodeAppendf("\t%s = %s;\n", vsEdgeName, attr1Name->c_str());
// translate to origin
@@ -50,7 +49,7 @@ public:
// compare outer lengths against xOuterRadius
builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.x-dOuter, 0.0, 1.0);\n", fsEdgeName);
- if (effect.isStroked()) {
+ if (ellipseEffect.isStroked()) {
builder->fsCodeAppendf("\tinnerOffset.y *= %s.w;\n", fsEdgeName);
builder->fsCodeAppend("\tfloat dInner = length(innerOffset);\n");
@@ -64,13 +63,13 @@ public:
builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
}
- static inline EffectKey GenKey(const GrEffectStage& stage, const GrGLCaps&) {
- const GrEllipseEdgeEffect& effect = GetEffectFromStage<GrEllipseEdgeEffect>(stage);
+ static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+ const GrEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<GrEllipseEdgeEffect>();
- return effect.isStroked() ? 0x1 : 0x0;
+ return ellipseEffect.isStroked() ? 0x1 : 0x0;
}
- virtual void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) SK_OVERRIDE {
+ virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {
}
private:
diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp
index 37e6eb4b25..80627aabd2 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.cpp
+++ b/src/gpu/effects/GrSimpleTextureEffect.cpp
@@ -15,41 +15,69 @@
class GrGLSimpleTextureEffect : public GrGLEffect {
public:
- GrGLSimpleTextureEffect(const GrBackendEffectFactory& factory, const GrEffectRef&)
- : INHERITED (factory) {}
+ GrGLSimpleTextureEffect(const GrBackendEffectFactory& factory, const GrDrawEffect& drawEffect)
+ : INHERITED (factory) {
+ GrEffect::CoordsType coordsType =
+ drawEffect.castEffect<GrSimpleTextureEffect>().coordsType();
+ if (GrEffect::kCustom_CoordsType != coordsType) {
+ SkNEW_IN_TLAZY(&fEffectMatrix, GrGLEffectMatrix, (coordsType));
+ }
+ }
virtual void emitCode(GrGLShaderBuilder* builder,
- const GrEffectStage&,
+ const GrDrawEffect& drawEffect,
EffectKey key,
- const char* vertexCoords,
const char* outputColor,
const char* inputColor,
const TextureSamplerArray& samplers) SK_OVERRIDE {
- const char* coordName;
- GrSLType coordType = fEffectMatrix.emitCode(builder, key, vertexCoords, &coordName);
+ const GrSimpleTextureEffect& ste = drawEffect.castEffect<GrSimpleTextureEffect>();
+ const char* fsCoordName;
+ GrSLType fsCoordSLType;
+ if (GrEffect::kCustom_CoordsType == ste.coordsType()) {
+ GrAssert(ste.getMatrix().isIdentity());
+ GrAssert(1 == ste.numVertexAttribs());
+ fsCoordSLType = kVec2f_GrSLType;
+ const char* vsVaryingName;
+ builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsVaryingName, &fsCoordName);
+ const char* attrName =
+ builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str();
+ builder->vsCodeAppendf("\t%s = %s;", vsVaryingName, attrName);
+ } else {
+ fsCoordSLType = fEffectMatrix.get()->emitCode(builder, key, &fsCoordName);
+ }
builder->fsCodeAppendf("\t%s = ", outputColor);
builder->appendTextureLookupAndModulate(GrGLShaderBuilder::kFragment_ShaderType,
inputColor,
samplers[0],
- coordName,
- coordType);
+ fsCoordName,
+ fsCoordSLType);
builder->fsCodeAppend(";\n");
}
- static inline EffectKey GenKey(const GrEffectStage& stage, const GrGLCaps&) {
- const GrSimpleTextureEffect& ste = GetEffectFromStage<GrSimpleTextureEffect>(stage);
- return GrGLEffectMatrix::GenKey(ste.getMatrix(),
- stage.getCoordChangeMatrix(),
- ste.texture(0));
+ static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+ const GrSimpleTextureEffect& ste = drawEffect.castEffect<GrSimpleTextureEffect>();
+ if (GrEffect::kCustom_CoordsType == ste.coordsType()) {
+ return 1 << GrGLEffectMatrix::kKeyBits;
+ } else {
+ return GrGLEffectMatrix::GenKey(ste.getMatrix(),
+ drawEffect,
+ ste.coordsType(),
+ ste.texture(0));
+ }
}
- virtual void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) SK_OVERRIDE {
- const GrSimpleTextureEffect& ste = GetEffectFromStage<GrSimpleTextureEffect>(stage);
- fEffectMatrix.setData(uman, ste.getMatrix(), stage.getCoordChangeMatrix(), ste.texture(0));
+ virtual void setData(const GrGLUniformManager& uman,
+ const GrDrawEffect& drawEffect) SK_OVERRIDE {
+ const GrSimpleTextureEffect& ste = drawEffect.castEffect<GrSimpleTextureEffect>();
+ if (GrEffect::kCustom_CoordsType == ste.coordsType()) {
+ GrAssert(ste.getMatrix().isIdentity());
+ } else {
+ fEffectMatrix.get()->setData(uman, ste.getMatrix(), drawEffect, ste.texture(0));
+ }
}
private:
- GrGLEffectMatrix fEffectMatrix;
+ SkTLazy<GrGLEffectMatrix> fEffectMatrix;
typedef GrGLEffect INHERITED;
};
@@ -72,6 +100,28 @@ GrEffectRef* GrSimpleTextureEffect::TestCreate(SkMWCRandom* random,
GrTexture* textures[]) {
int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
GrEffectUnitTest::kAlphaTextureIdx;
- const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
- return GrSimpleTextureEffect::Create(textures[texIdx], matrix);
+ static const SkShader::TileMode kTileModes[] = {
+ SkShader::kClamp_TileMode,
+ SkShader::kRepeat_TileMode,
+ SkShader::kMirror_TileMode,
+ };
+ SkShader::TileMode tileModes[] = {
+ kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
+ kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
+ };
+ GrTextureParams params(tileModes, random->nextBool());
+
+ static const CoordsType kCoordsTypes[] = {
+ kLocal_CoordsType,
+ kPosition_CoordsType,
+ kCustom_CoordsType
+ };
+ CoordsType coordsType = kCoordsTypes[random->nextULessThan(GR_ARRAY_COUNT(kCoordsTypes))];
+
+ if (kCustom_CoordsType == coordsType) {
+ return GrSimpleTextureEffect::CreateWithCustomCoords(textures[texIdx], params);
+ } else {
+ const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
+ return GrSimpleTextureEffect::Create(textures[texIdx], matrix);
+ }
}
diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h
index ffc05e5b52..661f40f037 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.h
+++ b/src/gpu/effects/GrSimpleTextureEffect.h
@@ -14,25 +14,50 @@ class GrGLSimpleTextureEffect;
/**
* The output color of this effect is a modulation of the input color and a sample from a texture.
- * The coord to sample the texture is determine by a matrix. It allows explicit specification of
- * the filtering and wrap modes (GrTextureParams).
+ * It allows explicit specification of the filtering and wrap modes (GrTextureParams). It can use
+ * local coords, positions, or a custom vertex attribute as input texture coords. The input coords
+ * can have a matrix applied in the VS in both the local and position cases but not with a custom
+ * attribute coords at this time. It will add a varying to input interpolate texture coords to the
+ * FS.
*/
class GrSimpleTextureEffect : public GrSingleTextureEffect {
public:
/* unfiltered, clamp mode */
- static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix) {
- AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix)));
+ static GrEffectRef* Create(GrTexture* tex,
+ const SkMatrix& matrix,
+ CoordsType coordsType = kLocal_CoordsType) {
+ GrAssert(kLocal_CoordsType == coordsType || kPosition_CoordsType == coordsType);
+ AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, false, coordsType)));
return CreateEffectRef(effect);
}
/* clamp mode */
- static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, bool bilerp) {
- AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, bilerp)));
+ static GrEffectRef* Create(GrTexture* tex,
+ const SkMatrix& matrix,
+ bool bilerp,
+ CoordsType coordsType = kLocal_CoordsType) {
+ GrAssert(kLocal_CoordsType == coordsType || kPosition_CoordsType == coordsType);
+ AutoEffectUnref effect(
+ SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, bilerp, coordsType)));
return CreateEffectRef(effect);
}
- static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, const GrTextureParams& p) {
- AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, p)));
+ static GrEffectRef* Create(GrTexture* tex,
+ const SkMatrix& matrix,
+ const GrTextureParams& p,
+ CoordsType coordsType = kLocal_CoordsType) {
+ GrAssert(kLocal_CoordsType == coordsType || kPosition_CoordsType == coordsType);
+ AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, p, coordsType)));
+ return CreateEffectRef(effect);
+ }
+
+ /** Variant that requires the client to install a custom kVec2 vertex attribute that will be
+ the source of the coords. No matrix is allowed in this mode. */
+ static GrEffectRef* CreateWithCustomCoords(GrTexture* tex, const GrTextureParams& p) {
+ AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex,
+ SkMatrix::I(),
+ p,
+ kCustom_CoordsType)));
return CreateEffectRef(effect);
}
@@ -47,16 +72,28 @@ public:
virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
private:
- GrSimpleTextureEffect(GrTexture* texture, const SkMatrix& matrix)
- : GrSingleTextureEffect(texture, matrix) {}
- GrSimpleTextureEffect(GrTexture* texture, const SkMatrix& matrix, bool bilerp)
- : GrSingleTextureEffect(texture, matrix, bilerp) {}
- GrSimpleTextureEffect(GrTexture* texture, const SkMatrix& matrix, const GrTextureParams& params)
- : GrSingleTextureEffect(texture, matrix, params) {}
+ GrSimpleTextureEffect(GrTexture* texture,
+ const SkMatrix& matrix,
+ bool bilerp,
+ CoordsType coordsType)
+ : GrSingleTextureEffect(texture, matrix, bilerp, coordsType) {
+ GrAssert(kLocal_CoordsType == coordsType || kPosition_CoordsType == coordsType);
+ }
+
+ GrSimpleTextureEffect(GrTexture* texture,
+ const SkMatrix& matrix,
+ const GrTextureParams& params,
+ CoordsType coordsType)
+ : GrSingleTextureEffect(texture, matrix, params, coordsType) {
+ if (kCustom_CoordsType == coordsType) {
+ GrAssert(matrix.isIdentity());
+ this->addVertexAttrib(kVec2f_GrSLType);
+ }
+ }
virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
const GrSimpleTextureEffect& ste = CastEffect<GrSimpleTextureEffect>(other);
- return this->hasSameTextureParamsAndMatrix(ste);
+ return this->hasSameTextureParamsMatrixAndCoordsType(ste);
}
GR_DECLARE_EFFECT_TEST;
diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp
index 7183ba3244..0c671f16d0 100644
--- a/src/gpu/effects/GrSingleTextureEffect.cpp
+++ b/src/gpu/effects/GrSingleTextureEffect.cpp
@@ -7,23 +7,32 @@
#include "effects/GrSingleTextureEffect.h"
-GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, const SkMatrix& m)
+GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
+ const SkMatrix& m,
+ CoordsType coordsType)
: fTextureAccess(texture)
- , fMatrix(m) {
+ , fMatrix(m)
+ , fCoordsType(coordsType) {
this->addTextureAccess(&fTextureAccess);
}
-GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, const SkMatrix& m, bool bilerp)
+GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
+ const SkMatrix& m,
+ bool bilerp,
+ CoordsType coordsType)
: fTextureAccess(texture, bilerp)
- , fMatrix(m) {
+ , fMatrix(m)
+ , fCoordsType(coordsType) {
this->addTextureAccess(&fTextureAccess);
}
GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
const SkMatrix& m,
- const GrTextureParams& params)
+ const GrTextureParams& params,
+ CoordsType coordsType)
: fTextureAccess(texture, params)
- , fMatrix(m) {
+ , fMatrix(m)
+ , fCoordsType(coordsType) {
this->addTextureAccess(&fTextureAccess);
}
diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h
index 4f25ddb38d..82037cf6e9 100644
--- a/src/gpu/effects/GrSingleTextureEffect.h
+++ b/src/gpu/effects/GrSingleTextureEffect.h
@@ -14,7 +14,8 @@
class GrTexture;
/**
- * A base class for effects that draw a single texture with a texture matrix.
+ * A base class for effects that draw a single texture with a texture matrix. This effect has no
+ * backend implementations. One must be provided by the subclass.
*/
class GrSingleTextureEffect : public GrEffect {
public:
@@ -22,20 +23,29 @@ public:
const SkMatrix& getMatrix() const { return fMatrix; }
+ /** Indicates whether the matrix operates on local coords or positions */
+ CoordsType coordsType() const { return fCoordsType; }
+
protected:
- GrSingleTextureEffect(GrTexture*, const SkMatrix&); /* unfiltered, clamp mode */
- GrSingleTextureEffect(GrTexture*, const SkMatrix&, bool bilerp); /* clamp mode */
- GrSingleTextureEffect(GrTexture*, const SkMatrix&, const GrTextureParams&);
+ /** unfiltered, clamp mode */
+ GrSingleTextureEffect(GrTexture*, const SkMatrix&, CoordsType = kLocal_CoordsType);
+ /** clamp mode */
+ GrSingleTextureEffect(GrTexture*, const SkMatrix&, bool bilerp, CoordsType = kLocal_CoordsType);
+ GrSingleTextureEffect(GrTexture*,
+ const SkMatrix&,
+ const GrTextureParams&,
+ CoordsType = kLocal_CoordsType);
/**
* Helper for subclass onIsEqual() functions.
*/
- bool hasSameTextureParamsAndMatrix(const GrSingleTextureEffect& other) const {
+ bool hasSameTextureParamsMatrixAndCoordsType(const GrSingleTextureEffect& other) const {
const GrTextureAccess& otherAccess = other.fTextureAccess;
// We don't have to check the accesses' swizzles because they are inferred from the texture.
return fTextureAccess.getTexture() == otherAccess.getTexture() &&
fTextureAccess.getParams() == otherAccess.getParams() &&
- this->getMatrix().cheapEqualTo(other.getMatrix());
+ this->getMatrix().cheapEqualTo(other.getMatrix()) &&
+ fCoordsType == other.fCoordsType;
}
/**
@@ -55,6 +65,7 @@ protected:
private:
GrTextureAccess fTextureAccess;
SkMatrix fMatrix;
+ CoordsType fCoordsType;
typedef GrEffect INHERITED;
};
diff --git a/src/gpu/effects/GrTextureDomainEffect.cpp b/src/gpu/effects/GrTextureDomainEffect.cpp
index e54af25ca0..b1fd3ed6d5 100644
--- a/src/gpu/effects/GrTextureDomainEffect.cpp
+++ b/src/gpu/effects/GrTextureDomainEffect.cpp
@@ -14,19 +14,18 @@
class GrGLTextureDomainEffect : public GrGLEffect {
public:
- GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrEffectRef&);
+ GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
virtual void emitCode(GrGLShaderBuilder*,
- const GrEffectStage&,
+ const GrDrawEffect&,
EffectKey,
- const char* vertexCoords,
const char* outputColor,
const char* inputColor,
const TextureSamplerArray&) SK_OVERRIDE;
- virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
+ virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
- static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
+ static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
private:
GrGLUniformManager::UniformHandle fNameUni;
@@ -37,27 +36,27 @@ private:
};
GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& factory,
- const GrEffectRef&)
+ const GrDrawEffect& drawEffect)
: INHERITED(factory)
- , fNameUni(GrGLUniformManager::kInvalidUniformHandle) {
+ , fNameUni(GrGLUniformManager::kInvalidUniformHandle)
+ , fEffectMatrix(drawEffect.castEffect<GrTextureDomainEffect>().coordsType()) {
fPrevDomain[0] = SK_FloatNaN;
}
void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder,
- const GrEffectStage& stage,
+ const GrDrawEffect& drawEffect,
EffectKey key,
- const char* vertexCoords,
const char* outputColor,
const char* inputColor,
const TextureSamplerArray& samplers) {
- const GrTextureDomainEffect& effect = GetEffectFromStage<GrTextureDomainEffect>(stage);
+ const GrTextureDomainEffect& texDom = drawEffect.castEffect<GrTextureDomainEffect>();
const char* coords;
- fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords);
+ fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
const char* domain;
fNameUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kVec4f_GrSLType, "TexDom", &domain);
- if (GrTextureDomainEffect::kClamp_WrapMode == effect.wrapMode()) {
+ if (GrTextureDomainEffect::kClamp_WrapMode == texDom.wrapMode()) {
builder->fsCodeAppendf("\tvec2 clampCoord = clamp(%s, %s.xy, %s.zw);\n",
coords, domain, domain);
@@ -69,7 +68,7 @@ void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder,
"clampCoord");
builder->fsCodeAppend(";\n");
} else {
- GrAssert(GrTextureDomainEffect::kDecal_WrapMode == effect.wrapMode());
+ GrAssert(GrTextureDomainEffect::kDecal_WrapMode == texDom.wrapMode());
if (kImagination_GrGLVendor == builder->ctxInfo().vendor()) {
// On the NexusS and GalaxyNexus, the other path (with the 'any'
@@ -106,9 +105,10 @@ void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder,
}
}
-void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
- const GrTextureDomainEffect& effect = GetEffectFromStage<GrTextureDomainEffect>(stage);
- const GrRect& domain = effect.domain();
+void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman,
+ const GrDrawEffect& drawEffect) {
+ const GrTextureDomainEffect& texDom = drawEffect.castEffect<GrTextureDomainEffect>();
+ const GrRect& domain = texDom.domain();
float values[4] = {
SkScalarToFloat(domain.left()),
@@ -117,7 +117,7 @@ void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEf
SkScalarToFloat(domain.bottom())
};
// vertical flip if necessary
- if (kBottomLeft_GrSurfaceOrigin == effect.texture(0)->origin()) {
+ if (kBottomLeft_GrSurfaceOrigin == texDom.texture(0)->origin()) {
values[1] = 1.0f - values[1];
values[3] = 1.0f - values[3];
// The top and bottom were just flipped, so correct the ordering
@@ -128,18 +128,20 @@ void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEf
uman.set4fv(fNameUni, 0, 1, values);
}
fEffectMatrix.setData(uman,
- effect.getMatrix(),
- stage.getCoordChangeMatrix(),
- effect.texture(0));
+ texDom.getMatrix(),
+ drawEffect,
+ texDom.texture(0));
}
-GrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrEffectStage& stage, const GrGLCaps&) {
- const GrTextureDomainEffect& effect = GetEffectFromStage<GrTextureDomainEffect>(stage);
- EffectKey key = effect.wrapMode();
+GrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrDrawEffect& drawEffect,
+ const GrGLCaps&) {
+ const GrTextureDomainEffect& texDom = drawEffect.castEffect<GrTextureDomainEffect>();
+ EffectKey key = texDom.wrapMode();
key <<= GrGLEffectMatrix::kKeyBits;
- EffectKey matrixKey = GrGLEffectMatrix::GenKey(effect.getMatrix(),
- stage.getCoordChangeMatrix(),
- effect.texture(0));
+ EffectKey matrixKey = GrGLEffectMatrix::GenKey(texDom.getMatrix(),
+ drawEffect,
+ texDom.coordsType(),
+ texDom.texture(0));
return key | matrixKey;
}
@@ -150,7 +152,8 @@ GrEffectRef* GrTextureDomainEffect::Create(GrTexture* texture,
const SkMatrix& matrix,
const GrRect& domain,
WrapMode wrapMode,
- bool bilerp) {
+ bool bilerp,
+ CoordsType coordsType) {
static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1};
if (kClamp_WrapMode == wrapMode && domain.contains(kFullRect)) {
return GrSimpleTextureEffect::Create(texture, matrix, bilerp);
@@ -172,7 +175,8 @@ GrEffectRef* GrTextureDomainEffect::Create(GrTexture* texture,
matrix,
clippedDomain,
wrapMode,
- bilerp)));
+ bilerp,
+ coordsType)));
return CreateEffectRef(effect);
}
@@ -182,8 +186,9 @@ GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
const SkMatrix& matrix,
const GrRect& domain,
WrapMode wrapMode,
- bool bilerp)
- : GrSingleTextureEffect(texture, matrix, bilerp)
+ bool bilerp,
+ CoordsType coordsType)
+ : GrSingleTextureEffect(texture, matrix, bilerp, coordsType)
, fWrapMode(wrapMode)
, fTextureDomain(domain) {
}
@@ -198,7 +203,8 @@ const GrBackendEffectFactory& GrTextureDomainEffect::getFactory() const {
bool GrTextureDomainEffect::onIsEqual(const GrEffect& sBase) const {
const GrTextureDomainEffect& s = CastEffect<GrTextureDomainEffect>(sBase);
- return this->hasSameTextureParamsAndMatrix(s) && this->fTextureDomain == s.fTextureDomain;
+ return this->hasSameTextureParamsMatrixAndCoordsType(s) &&
+ this->fTextureDomain == s.fTextureDomain;
}
void GrTextureDomainEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
@@ -225,5 +231,12 @@ GrEffectRef* GrTextureDomainEffect::TestCreate(SkMWCRandom* random,
domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1);
WrapMode wrapMode = random->nextBool() ? kClamp_WrapMode : kDecal_WrapMode;
const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
- return GrTextureDomainEffect::Create(textures[texIdx], matrix, domain, wrapMode);
+ bool bilerp = random->nextBool();
+ CoordsType coords = random->nextBool() ? kLocal_CoordsType : kPosition_CoordsType;
+ return GrTextureDomainEffect::Create(textures[texIdx],
+ matrix,
+ domain,
+ wrapMode,
+ bilerp,
+ coords);
}
diff --git a/src/gpu/effects/GrTextureDomainEffect.h b/src/gpu/effects/GrTextureDomainEffect.h
index b7f665cba3..8b1f2b6f61 100644
--- a/src/gpu/effects/GrTextureDomainEffect.h
+++ b/src/gpu/effects/GrTextureDomainEffect.h
@@ -38,7 +38,8 @@ public:
const SkMatrix&,
const SkRect& domain,
WrapMode,
- bool bilerp = false);
+ bool bilerp,
+ CoordsType = kLocal_CoordsType);
virtual ~GrTextureDomainEffect();
@@ -75,7 +76,8 @@ private:
const SkMatrix&,
const GrRect& domain,
WrapMode,
- bool bilerp);
+ bool bilerp,
+ CoordsType type);
virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
diff --git a/src/gpu/gl/GrGLEffect.cpp b/src/gpu/gl/GrGLEffect.cpp
index 478d03dee1..e21ab1dab9 100644
--- a/src/gpu/gl/GrGLEffect.cpp
+++ b/src/gpu/gl/GrGLEffect.cpp
@@ -7,6 +7,7 @@
#include "GrGLSL.h"
#include "GrGLEffect.h"
+#include "GrDrawEffect.h"
GrGLEffect::GrGLEffect(const GrBackendEffectFactory& factory)
: fFactory(factory) {
@@ -17,14 +18,15 @@ GrGLEffect::~GrGLEffect() {
///////////////////////////////////////////////////////////////////////////////
-void GrGLEffect::setData(const GrGLUniformManager&, const GrEffectStage&) {
+void GrGLEffect::setData(const GrGLUniformManager&, const GrDrawEffect&) {
}
-GrGLEffect::EffectKey GrGLEffect::GenTextureKey(const GrEffectRef* effect,
+GrGLEffect::EffectKey GrGLEffect::GenTextureKey(const GrDrawEffect& drawEffect,
const GrGLCaps& caps) {
EffectKey key = 0;
- for (int index = 0; index < (*effect)->numTextures(); ++index) {
- const GrTextureAccess& access = (*effect)->textureAccess(index);
+ 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;
GrAssert(0 == (value & key)); // keys for each access ought not to overlap
key |= value;
@@ -32,12 +34,12 @@ GrGLEffect::EffectKey GrGLEffect::GenTextureKey(const GrEffectRef* effect,
return key;
}
-GrGLEffect::EffectKey GrGLEffect::GenAttribKey(const GrEffectStage& stage) {
+GrGLEffect::EffectKey GrGLEffect::GenAttribKey(const GrDrawEffect& drawEffect) {
EffectKey key = 0;
- int numAttributes = stage.getVertexAttribIndexCount();
+ int numAttributes = drawEffect.getVertexAttribIndexCount();
GrAssert(numAttributes <= 2);
- const int* attributeIndices = stage.getVertexAttribIndices();
+ const int* attributeIndices = drawEffect.getVertexAttribIndices();
for (int index = 0; index < numAttributes; ++index) {
EffectKey value = attributeIndices[index] << 3*index;
GrAssert(0 == (value & key)); // keys for each attribute ought not to overlap
diff --git a/src/gpu/gl/GrGLEffect.h b/src/gpu/gl/GrGLEffect.h
index 869fbdad7f..5df22811c4 100644
--- a/src/gpu/gl/GrGLEffect.h
+++ b/src/gpu/gl/GrGLEffect.h
@@ -12,7 +12,6 @@
#include "GrGLShaderBuilder.h"
#include "GrGLShaderVar.h"
#include "GrGLSL.h"
-#include "GrEffectStage.h"
class GrGLTexture;
@@ -21,13 +20,20 @@ class GrGLTexture;
include/gpu/GrEffect.h. Objects of type GrGLEffect are responsible for emitting the
GLSL code that implements a GrEffect and for uploading uniforms at draw time. They also
must have a function:
- static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&)
+ static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&)
that is used to implement a program cache. When two GrEffects produce the same key this means
that their GrGLEffects would emit the same GLSL code.
+ The GrGLEffect subclass must also have a constructor of the form:
+ EffectSubclass::EffectSubclass(const GrBackendEffectFactory&, const GrDrawEffect&)
+ The effect held by the GrDrawEffect is guaranteed to be of the type that generated the
+ GrGLEffect subclass instance.
+
These objects are created by the factory object returned by the GrEffect::getFactory().
*/
+class GrDrawEffect;
+
class GrGLEffect {
public:
@@ -50,14 +56,10 @@ public:
stages.
@param builder Interface used to emit code in the shaders.
- @param stage The effect stage that generated this program stage.
+ @param drawEffect A wrapper on the effect that generated this program stage.
@param key The key that was computed by GenKey() from the generating GrEffect.
Only the bits indicated by GrBackendEffectFactory::kEffectKeyBits are
guaranteed to match the value produced by GenKey();
- @param vertexCoords A vec2 in the VS that holds the position in local coords. This is either
- the pre-view-matrix vertex position or if explicit per-vertex texture
- coords are used with a stage then it is those coordinates. See
- GrVertexLayout.
@param outputColor A predefined vec4 in the FS in which the stage should place its output
color (or coverage).
@param inputColor A vec4 that holds the input color to the stage in the FS. This may be
@@ -70,9 +72,8 @@ public:
reads in the generated code.
*/
virtual void emitCode(GrGLShaderBuilder* builder,
- const GrEffectStage& stage,
+ const GrDrawEffect& drawEffect,
EffectKey key,
- const char* vertexCoords,
const char* outputColor,
const char* inputColor,
const TextureSamplerArray& samplers) = 0;
@@ -81,34 +82,15 @@ public:
key; this function reads data from a stage and uploads any uniform variables required
by the shaders created in emitCode(). The GrEffect installed in the GrEffectStage is
guaranteed to be of the same type that created this GrGLEffect and to have an identical
- EffectKey as the one that created this GrGLEffect. */
- virtual void setData(const GrGLUniformManager&, const GrEffectStage&);
+ 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&);
const char* name() const { return fFactory.name(); }
- static EffectKey GenTextureKey(const GrEffectRef*, const GrGLCaps&);
- static EffectKey GenAttribKey(const GrEffectStage& stage);
-
- /**
- * GrGLEffect subclasses get passed a GrEffectStage in their emitCode and setData functions.
- * The GrGLEffect usually needs to cast the stage's effect to the GrEffect subclass that
- * generated the GrGLEffect. This helper does just that.
- */
- template <typename T>
- static const T& GetEffectFromStage(const GrEffectStage& effectStage) {
- GrAssert(NULL != effectStage.getEffect());
- return CastEffect<T>(*effectStage.getEffect());
- }
-
- /**
- * Extracts the GrEffect from a GrEffectRef and down-casts to a GrEffect subclass. Usually used
- * in a GrGLEffect subclass's constructor (which takes const GrEffectRef&).
- */
- template <typename T>
- static const T& CastEffect(const GrEffectRef& effectRef) {
- GrAssert(NULL != effectRef.get());
- return *static_cast<const T*>(effectRef.get());
- }
+ static EffectKey GenTextureKey(const GrDrawEffect&, const GrGLCaps&);
+ static EffectKey GenAttribKey(const GrDrawEffect& stage);
protected:
const GrBackendEffectFactory& fFactory;
diff --git a/src/gpu/gl/GrGLEffectMatrix.cpp b/src/gpu/gl/GrGLEffectMatrix.cpp
index c37098e2f0..e2e8807726 100644
--- a/src/gpu/gl/GrGLEffectMatrix.cpp
+++ b/src/gpu/gl/GrGLEffectMatrix.cpp
@@ -6,58 +6,67 @@
*/
#include "GrGLEffectMatrix.h"
+#include "GrDrawEffect.h"
#include "GrTexture.h"
GrGLEffect::EffectKey GrGLEffectMatrix::GenKey(const SkMatrix& effectMatrix,
- const SkMatrix& coordChangeMatrix,
+ const GrDrawEffect& drawEffect,
+ CoordsType coordsType,
const GrTexture* texture) {
+ EffectKey key = 0;
SkMatrix::TypeMask type0 = effectMatrix.getType();
- SkMatrix::TypeMask type1 = coordChangeMatrix.getType();
+ SkMatrix::TypeMask type1;
+ if (GrEffect::kLocal_CoordsType == coordsType) {
+ 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.
+ key |= kPositionCoords_Flag;
+ }
+ type1 = SkMatrix::kIdentity_Mask;
+ }
- static const int kNonTransMask = SkMatrix::kAffine_Mask |
- SkMatrix::kScale_Mask |
- SkMatrix::kPerspective_Mask;
int combinedTypes = type0 | type1;
bool reverseY = (NULL != texture) && kBottomLeft_GrSurfaceOrigin == texture->origin();
if (SkMatrix::kPerspective_Mask & combinedTypes) {
- return kGeneral_Key;
- } else if ((kNonTransMask & combinedTypes) || reverseY) {
- return kNoPersp_Key;
- } else if (kTrans_Key & combinedTypes) {
- return kTrans_Key;
+ 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 {
- GrAssert(effectMatrix.isIdentity() && coordChangeMatrix.isIdentity());
- return kIdentity_Key;
+ key |= kIdentity_MatrixType;
}
+ return key;
}
GrSLType GrGLEffectMatrix::emitCode(GrGLShaderBuilder* builder,
EffectKey key,
- const char* vertexCoords,
const char** fsCoordName,
const char** vsCoordName,
const char* suffix) {
GrSLType varyingType;
const char* uniName;
key &= kKeyMask;
- switch (key) {
- case kIdentity_Key:
+ switch (key & kMatrixTypeKeyMask) {
+ case kIdentity_MatrixType:
fUniType = kVoid_GrSLType;
varyingType = kVec2f_GrSLType;
break;
- case kTrans_Key:
+ case kTrans_MatrixType:
fUniType = kVec2f_GrSLType;
uniName = "StageTranslate";
varyingType = kVec2f_GrSLType;
break;
- case kNoPersp_Key:
+ case kNoPersp_MatrixType:
fUniType = kMat33f_GrSLType;
uniName = "StageMatrix";
varyingType = kVec2f_GrSLType;
break;
- case kGeneral_Key:
+ case kGeneral_MatrixType:
fUniType = kMat33f_GrSLType;
uniName = "StageMatrix";
varyingType = kVec3f_GrSLType;
@@ -89,24 +98,39 @@ GrSLType GrGLEffectMatrix::emitCode(GrGLShaderBuilder* builder,
const char* fsVaryingName;
builder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
- // varying = matrix * vertex-coords (logically)
+ const GrGLShaderVar* coords;
+ switch (fCoordsType) {
+ case GrEffect::kLocal_CoordsType:
+ GrAssert(!(kPositionCoords_Flag & key));
+ coords = &builder->localCoordsAttribute();
+ break;
+ case GrEffect::kPosition_CoordsType:
+ GrAssert((kPositionCoords_Flag & key) || !builder->hasExplicitLocalCoords());
+ coords = &builder->positionAttribute();
+ break;
+ default:
+ coords = NULL; // prevents warning
+ GrCrash("Unexpected coords type.");
+ }
+ // varying = matrix * coords (logically)
switch (fUniType) {
case kVoid_GrSLType:
GrAssert(kVec2f_GrSLType == varyingType);
- builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, vertexCoords);
+ builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords->c_str());
break;
case kVec2f_GrSLType:
GrAssert(kVec2f_GrSLType == varyingType);
- builder->vsCodeAppendf("\t%s = %s + %s;\n", vsVaryingName, uniName, vertexCoords);
+ builder->vsCodeAppendf("\t%s = %s + %s;\n",
+ vsVaryingName, uniName, coords->c_str());
break;
case kMat33f_GrSLType: {
GrAssert(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
if (kVec2f_GrSLType == varyingType) {
builder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n",
- vsVaryingName, uniName, vertexCoords);
+ vsVaryingName, uniName, coords->c_str());
} else {
builder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n",
- vsVaryingName, uniName, vertexCoords);
+ vsVaryingName, uniName, coords->c_str());
}
break;
}
@@ -128,7 +152,6 @@ GrSLType GrGLEffectMatrix::emitCode(GrGLShaderBuilder* builder,
*/
void GrGLEffectMatrix::emitCodeMakeFSCoords2D(GrGLShaderBuilder* builder,
EffectKey key,
- const char* vertexCoords,
const char** fsCoordName,
const char** vsVaryingName,
GrSLType* vsVaryingType,
@@ -137,7 +160,6 @@ void GrGLEffectMatrix::emitCodeMakeFSCoords2D(GrGLShaderBuilder* builder,
GrSLType varyingType = this->emitCode(builder,
key,
- vertexCoords,
&fsVaryingName,
vsVaryingName,
suffix);
@@ -164,11 +186,14 @@ void GrGLEffectMatrix::emitCodeMakeFSCoords2D(GrGLShaderBuilder* builder,
}
void GrGLEffectMatrix::setData(const GrGLUniformManager& uniformManager,
- const SkMatrix& matrix,
- const SkMatrix& coordChangeMatrix,
- const GrTexture* texture) {
+ const SkMatrix& matrix,
+ const GrDrawEffect& drawEffect,
+ const GrTexture* texture) {
GrAssert((GrGLUniformManager::kInvalidUniformHandle == fUni) ==
- (kVoid_GrSLType == fUniType));
+ (kVoid_GrSLType == fUniType));
+ const SkMatrix& coordChangeMatrix = GrEffect::kLocal_CoordsType == fCoordsType ?
+ drawEffect.getCoordChangeMatrix() :
+ SkMatrix::I();
switch (fUniType) {
case kVoid_GrSLType:
GrAssert(matrix.isIdentity());
@@ -178,8 +203,8 @@ void GrGLEffectMatrix::setData(const GrGLUniformManager& uniformManager,
case kVec2f_GrSLType: {
GrAssert(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChangeMatrix.getType()));
GrAssert(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->origin());
- SkScalar tx = matrix[SkMatrix::kMTransX] + coordChangeMatrix[SkMatrix::kMTransX];
- SkScalar ty = matrix[SkMatrix::kMTransY] + coordChangeMatrix[SkMatrix::kMTransY];
+ 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);
diff --git a/src/gpu/gl/GrGLEffectMatrix.h b/src/gpu/gl/GrGLEffectMatrix.h
index 1a11656534..fc4b783133 100644
--- a/src/gpu/gl/GrGLEffectMatrix.h
+++ b/src/gpu/gl/GrGLEffectMatrix.h
@@ -14,34 +14,68 @@
class GrTexture;
/**
- * This is a helper to implement a texture matrix in a GrGLEffect.
+ * This is a helper to implement a matrix in a GrGLEffect that operates on incoming coords in the
+ * vertex shader and writes them to an attribute to be used in the fragment shader. When the input
+ * coords in the vertex shader 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 GrGLEffectMatrix will 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 GrGLEffectMatrix {
+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 GrEffect::CoordsType CoordsType;
+
typedef GrGLEffect::EffectKey EffectKey;
+
/**
* The matrix uses kKeyBits of the effect's EffectKey. A GrGLEffect may place these bits at an
* arbitrary shift in its final key. However, when GrGLEffectMatrix::emitCode*() code is called
* the relevant bits must be in the lower kKeyBits of the key parameter.
*/
enum {
- kKeyBits = 2,
+ kKeyBits = kKeyBitsPrivate,
kKeyMask = (1 << kKeyBits) - 1,
};
- GrGLEffectMatrix() : fUni(GrGLUniformManager::kInvalidUniformHandle) {
+ GrGLEffectMatrix(CoordsType coordsType)
+ : fUni(GrGLUniformManager::kInvalidUniformHandle)
+ , fCoordsType(coordsType) {
+ GrAssert(GrEffect::kLocal_CoordsType == coordsType ||
+ GrEffect::kPosition_CoordsType == coordsType);
fPrevMatrix = SkMatrix::InvalidMatrix();
}
/**
* Generates the key for the portion of the code emitted by this class's emitCode() function.
* Pass a texture to make GrGLEffectMatrix automatically adjust for the texture's origin. Pass
- * NULL when not using the EffectMatrix for a texture lookups, or if the GrGLEffect subclass
- * wants to handle origin adjustments in some other manner. coordChangeMatrix is the matrix
- * from GrEffectStage.
+ * NULL when not using the EffectMatrix for a texture lookup, or if the GrGLEffect subclass
+ * wants to handle origin adjustments in some other manner. The coords type param must match the
+ * param that would be used to initialize GrGLEffectMatrix for the generating GrEffect.
*/
static EffectKey GenKey(const SkMatrix& effectMatrix,
- const SkMatrix& coordChangeMatrix,
+ const GrDrawEffect&,
+ CoordsType,
const GrTexture*);
/**
@@ -55,7 +89,6 @@ public:
*/
GrSLType emitCode(GrGLShaderBuilder*,
EffectKey,
- const char* vertexCoords,
const char** fsCoordName, /* optional */
const char** vsCoordName = NULL,
const char* suffix = NULL);
@@ -66,31 +99,23 @@ public:
*/
void emitCodeMakeFSCoords2D(GrGLShaderBuilder*,
EffectKey,
- const char* vertexCoords,
const char** fsCoordName, /* optional */
const char** vsVaryingName = NULL,
GrSLType* vsVaryingType = NULL,
const char* suffix = NULL);
/**
- * Call from a GrGLEffect's subclass to update the texture matrix. The matrix,
- * coordChangeMatrix, and texture params should match those used with GenKey.
+ * Call from a GrGLEffect's subclass to update the texture matrix. The effectMatrix and texture
+ * params should match those used with GenKey.
*/
void setData(const GrGLUniformManager& uniformManager,
const SkMatrix& effectMatrix,
- const SkMatrix& coordChangeMatrix,
+ const GrDrawEffect& drawEffect,
const GrTexture*);
-private:
- enum {
- kIdentity_Key = 0,
- kTrans_Key = 1,
- kNoPersp_Key = 2,
- kGeneral_Key = 3,
- };
-
GrGLUniformManager::UniformHandle fUni;
GrSLType fUniType;
SkMatrix fPrevMatrix;
+ CoordsType fCoordsType;
};
#endif
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 7d6420ead4..21729cd33b 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -9,6 +9,7 @@
#include "GrAllocator.h"
#include "GrEffect.h"
+#include "GrDrawEffect.h"
#include "GrGLEffect.h"
#include "GrGpuGL.h"
#include "GrGLShaderVar.h"
@@ -26,7 +27,6 @@ SK_DEFINE_INST_COUNT(GrGLProgram)
SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false,
"Print the source code for all shaders generated.");
-#define TEX_ATTR_NAME "aTexCoord"
#define COL_ATTR_NAME "aColor"
#define COV_ATTR_NAME "aCoverage"
#define EDGE_ATTR_NAME "aEdge"
@@ -134,7 +134,10 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
lastEnabledStage = s;
const GrEffectRef& effect = *drawState.getStage(s).getEffect();
const GrBackendEffectFactory& factory = effect->getFactory();
- desc->fEffectKeys[s] = factory.glEffectKey(drawState.getStage(s), gpu->glCaps());
+ bool explicitLocalCoords = (drawState.getAttribBindings() &
+ GrDrawState::kLocalCoords_AttribBindingsBit);
+ GrDrawEffect drawEffect(drawState.getStage(s), explicitLocalCoords);
+ desc->fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps());
} else {
desc->fEffectKeys[s] = 0;
}
@@ -207,8 +210,8 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
if (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
desc->fEdgeAttributeIndex = drawState.getAttribIndex(GrDrawState::kEdge_AttribIndex);
}
- if (GrDrawState::AttributesBindExplicitTexCoords(desc->fAttribBindings)) {
- desc->fTexCoordAttributeIndex = drawState.getAttribIndex(GrDrawState::kTexCoord_AttribIndex);
+ if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
+ desc->fLocalCoordsAttributeIndex = drawState.getAttribIndex(GrDrawState::kLocalCoords_AttribIndex);
}
#if GR_DEBUG
@@ -227,10 +230,10 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
if (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
GrAssert(desc->fEdgeAttributeIndex < GrDrawState::kVertexAttribCnt);
GrAssert(kAttribLayouts[vertexAttribs[desc->fEdgeAttributeIndex].fType].fCount == 4);
- }
- if (GrDrawState::AttributesBindExplicitTexCoords(desc->fAttribBindings)) {
- GrAssert(desc->fTexCoordAttributeIndex < GrDrawState::kVertexAttribCnt);
- GrAssert(kAttribLayouts[vertexAttribs[desc->fTexCoordAttributeIndex].fType].fCount == 2);
+ }
+ if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
+ GrAssert(desc->fLocalCoordsAttributeIndex < GrDrawState::kVertexAttribCnt);
+ GrAssert(kAttribLayouts[vertexAttribs[desc->fLocalCoordsAttributeIndex].fType].fCount == 2);
}
#endif
}
@@ -679,8 +682,10 @@ bool GrGLProgram::compileShaders(const GrGLShaderBuilder& builder) {
bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
GrAssert(0 == fProgramID);
- GrGLShaderBuilder builder(fContext.info(), fUniformManager);
const GrAttribBindings& attribBindings = fDesc.fAttribBindings;
+ bool hasExplicitLocalCoords =
+ SkToBool(attribBindings & GrDrawState::kLocalCoords_AttribBindingsBit);
+ GrGLShaderBuilder builder(fContext.info(), fUniformManager, hasExplicitLocalCoords);
#if GR_GL_EXPERIMENTAL_GS
builder.fUsesGS = fDesc.fExperimentalGS;
@@ -760,11 +765,6 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
builder.vsCodeAppend("\tgl_PointSize = 1.0;\n");
}
- // add texture coordinates that are used to the list of vertex attr decls
- if (GrDrawState::AttributesBindExplicitTexCoords(attribBindings)) {
- builder.addAttribute(kVec2f_GrSLType, TEX_ATTR_NAME);
- }
-
///////////////////////////////////////////////////////////////////////////
// compute the final color
@@ -779,21 +779,11 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
outColor.appendS32(s);
builder.fsCodeAppendf("\tvec4 %s;\n", outColor.c_str());
- const char* inCoords;
- // figure out what our input coords are
- if (!GrDrawState::StageBindsExplicitTexCoords(attribBindings, s)) {
- inCoords = builder.positionAttribute().c_str();
- } else {
- // must have input tex coordinates if stage is enabled.
- inCoords = TEX_ATTR_NAME;
- }
-
builder.setCurrentStage(s);
fEffects[s] = builder.createAndEmitGLEffect(*stages[s],
fDesc.fEffectKeys[s],
inColor.size() ? inColor.c_str() : NULL,
outColor.c_str(),
- inCoords,
&fUniformHandles.fSamplerUnis[s]);
builder.setNonStage();
inColor = outColor;
@@ -871,16 +861,6 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
outCoverage.appendS32(s);
builder.fsCodeAppendf("\tvec4 %s;\n", outCoverage.c_str());
- const char* inCoords;
- // figure out what our input coords are
- if (!GrDrawState::StageBindsExplicitTexCoords(attribBindings, s)) {
- inCoords = builder.positionAttribute().c_str();
- } else {
- // must have input tex coordinates if stage is
- // enabled.
- inCoords = TEX_ATTR_NAME;
- }
-
// stages don't know how to deal with a scalar input. (Maybe they should. We
// could pass a GrGLShaderVar)
if (inCoverageIsScalar) {
@@ -894,7 +874,6 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
fDesc.fEffectKeys[s],
inCoverage.size() ? inCoverage.c_str() : NULL,
outCoverage.c_str(),
- inCoords,
&fUniformHandles.fSamplerUnis[s]);
builder.setNonStage();
inCoverage = outCoverage;
@@ -1008,8 +987,10 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& buil
if (fDesc.fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
GL_CALL(BindAttribLocation(fProgramID, fDesc.fEdgeAttributeIndex, EDGE_ATTR_NAME));
}
- if (GrDrawState::AttributesBindExplicitTexCoords(fDesc.fAttribBindings)) {
- GL_CALL(BindAttribLocation(fProgramID, fDesc.fTexCoordAttributeIndex, TEX_ATTR_NAME));
+ if (fDesc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
+ GL_CALL(BindAttribLocation(fProgramID,
+ fDesc.fLocalCoordsAttributeIndex,
+ builder.localCoordsAttribute().c_str()));
}
const GrGLShaderBuilder::AttributePair* attribEnd = builder.getEffectAttributes().end();
@@ -1088,7 +1069,11 @@ void GrGLProgram::setData(GrGpuGL* gpu,
if (NULL != fEffects[s]) {
const GrEffectStage& stage = drawState.getStage(s);
GrAssert(NULL != stage.getEffect());
- fEffects[s]->setData(fUniformManager, stage);
+
+ bool explicitLocalCoords =
+ (fDesc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit);
+ GrDrawEffect drawEffect(stage, explicitLocalCoords);
+ fEffects[s]->setData(fUniformManager, drawEffect);
int numSamplers = fUniformHandles.fSamplerUnis[s].count();
for (int u = 0; u < numSamplers; ++u) {
UniformHandle handle = fUniformHandles.fSamplerUnis[s][u];
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index cde918b54b..9fd01fd816 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -192,7 +192,7 @@ public:
int8_t fColorAttributeIndex;
int8_t fCoverageAttributeIndex;
int8_t fEdgeAttributeIndex;
- int8_t fTexCoordAttributeIndex;
+ int8_t fLocalCoordsAttributeIndex;
friend class GrGLProgram;
};
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index b3b09cc477..117962633f 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -8,6 +8,7 @@
#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLProgram.h"
#include "gl/GrGLUniformHandle.h"
+#include "GrDrawEffect.h"
#include "GrTexture.h"
// number of each input/output type in a single allocation block
@@ -82,7 +83,8 @@ void append_swizzle(SkString* outAppend,
//const int GrGLShaderBuilder::fCoordDims = 2;
GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo,
- GrGLUniformManager& uniformManager)
+ GrGLUniformManager& uniformManager,
+ bool explicitLocalCoords)
: fUniforms(kVarsPerBlock)
, fVSAttrs(kVarsPerBlock)
, fVSOutputs(kVarsPerBlock)
@@ -99,6 +101,14 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo,
fPositionVar = &fVSAttrs.push_back();
fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
+ if (explicitLocalCoords) {
+ fLocalCoordsVar = &fVSAttrs.push_back();
+ fLocalCoordsVar->set(kVec2f_GrSLType,
+ GrGLShaderVar::kAttribute_TypeModifier,
+ "aLocalCoords");
+ } else {
+ fLocalCoordsVar = fPositionVar;
+ }
}
void GrGLShaderBuilder::codeAppendf(ShaderType type, const char format[], va_list args) {
@@ -494,7 +504,6 @@ GrGLEffect* GrGLShaderBuilder::createAndEmitGLEffect(
GrGLEffect::EffectKey key,
const char* fsInColor,
const char* fsOutColor,
- const char* vsInCoord,
SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles) {
GrAssert(NULL != stage.getEffect());
@@ -506,6 +515,7 @@ GrGLEffect* GrGLShaderBuilder::createAndEmitGLEffect(
textureSamplers[i].init(this, &effect->textureAccess(i), i);
samplerHandles->push_back(textureSamplers[i].fSamplerUniform);
}
+ GrDrawEffect drawEffect(stage, this->hasExplicitLocalCoords());
int numAttributes = stage.getVertexAttribIndexCount();
const int* attributeIndices = stage.getVertexAttribIndices();
@@ -519,15 +529,15 @@ GrGLEffect* GrGLShaderBuilder::createAndEmitGLEffect(
}
}
- GrGLEffect* glEffect = effect->getFactory().createGLInstance(effect);
+ GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
// Enclose custom code in a block to avoid namespace conflicts
this->fVSCode.appendf("\t{ // %s\n", glEffect->name());
this->fFSCode.appendf("\t{ // %s \n", glEffect->name());
+
glEffect->emitCode(this,
- stage,
+ drawEffect,
key,
- vsInCoord,
fsOutColor,
fsInColor,
textureSamplers);
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h
index 524a8853ca..9d64143802 100644
--- a/src/gpu/gl/GrGLShaderBuilder.h
+++ b/src/gpu/gl/GrGLShaderBuilder.h
@@ -17,6 +17,7 @@
#include <stdarg.h>
class GrGLContextInfo;
+class GrEffectStage;
/**
Contains all the incremental state of a shader as it is being built,as well as helpers to
@@ -80,7 +81,7 @@ public:
kFragment_ShaderType = 0x4,
};
- GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&);
+ GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&, bool explicitLocalCoords);
/**
* Called by GrGLEffects to add code to one of the shaders.
@@ -205,6 +206,16 @@ public:
*/
const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
+ /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
+ as positionAttribute() or it may not be. It depends upon whether the rendering code
+ specified explicit local coords or not in the GrDrawState. */
+ const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
+
+ /**
+ * Are explicit local coordinates provided as input to the vertex shader.
+ */
+ bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
+
/**
* Interfaces used by GrGLProgram.
* TODO: Hide these from the GrEffects using friend or splitting this into two related classes.
@@ -223,7 +234,6 @@ public:
GrBackendEffectFactory::EffectKey key,
const char* fsInColor, // NULL means no incoming color
const char* fsOutColor,
- const char* vsInCoord,
SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles);
GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
@@ -290,6 +300,8 @@ private:
SkSTArray<10, AttributePair, true> fEffectAttributes;
GrGLShaderVar* fPositionVar;
+ GrGLShaderVar* fLocalCoordsVar;
+
};
#endif