aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-08 17:15:55 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-08 17:15:55 +0000
commit2fdcdeb86788206c23410109b3e2b7976747fd11 (patch)
treefd780e51a91a279ddfa9147cf54a573d15208c00 /src
parent0f11e1ab5b6e53f6176dde2dbb25a8e3ae34858f (diff)
Make GrDrawState::AutoRestoreViewMatrix handle sampler matrices.
R=robertphillips@google.com Review URL: https://codereview.appspot.com/6618065 git-svn-id: http://skia.googlecode.com/svn/trunk@5853 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrContext.cpp21
-rw-r--r--src/gpu/GrDrawState.cpp71
-rw-r--r--src/gpu/GrDrawState.h82
-rw-r--r--src/gpu/GrStencilAndCoverPathRenderer.cpp10
4 files changed, 108 insertions, 76 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index ef59ca5a4d..d702031733 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -800,9 +800,7 @@ void GrContext::drawRect(const GrPaint& paint,
GrDrawState::AutoViewMatrixRestore avmr;
if (NULL != matrix) {
GrDrawState* drawState = target->drawState();
- avmr.set(drawState);
- drawState->preConcatViewMatrix(*matrix);
- drawState->preConcatSamplerMatrices(*matrix);
+ avmr.set(drawState, *matrix);
}
target->drawNonIndexed(primType, 0, vertCount);
@@ -815,7 +813,6 @@ void GrContext::drawRect(const GrPaint& paint,
}
target->setVertexSourceToBuffer(0, sqVB);
GrDrawState* drawState = target->drawState();
- GrDrawState::AutoViewMatrixRestore avmr(drawState);
GrMatrix m;
m.setAll(rect.width(), 0, rect.fLeft,
0, rect.height(), rect.fTop,
@@ -824,8 +821,7 @@ void GrContext::drawRect(const GrPaint& paint,
if (NULL != matrix) {
m.postConcat(*matrix);
}
- drawState->preConcatViewMatrix(m);
- drawState->preConcatSamplerMatrices(m);
+ GrDrawState::AutoViewMatrixRestore avmr(drawState, m);
target->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
#else
@@ -852,7 +848,6 @@ void GrContext::drawRectToRect(const GrPaint& paint,
#if GR_STATIC_RECT_VB
GrDrawState::AutoStageDisable atr(fDrawState);
GrDrawState* drawState = target->drawState();
- GrDrawState::AutoViewMatrixRestore avmr(drawState);
GrMatrix m;
@@ -862,15 +857,11 @@ void GrContext::drawRectToRect(const GrPaint& paint,
if (NULL != dstMatrix) {
m.postConcat(*dstMatrix);
}
- drawState->preConcatViewMatrix(m);
- // we explicitly setup the correct coords for the first stage. The others
- // must know about the view matrix change.
- for (int s = 1; s < GrPaint::kTotalStages; ++s) {
- if (drawState->isStageEnabled(s)) {
- drawState->sampler(s)->preConcatMatrix(m);
- }
- }
+ // 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);
m.setAll(srcRect.width(), 0, srcRect.fLeft,
0, srcRect.height(), srcRect.fTop,
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index b9b708e4bf..b0bbd06a16 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -49,11 +49,64 @@ void GrDrawState::setFromPaint(const GrPaint& paint) {
////////////////////////////////////////////////////////////////////////////////
-GrDrawState::AutoDeviceCoordDraw::AutoDeviceCoordDraw(GrDrawState* drawState,
- uint32_t explicitCoordStageMask) {
+void GrDrawState::AutoViewMatrixRestore::restore() {
+ if (NULL != fDrawState) {
+ fDrawState->setViewMatrix(fViewMatrix);
+ for (int s = 0; s < GrDrawState::kNumStages; ++s) {
+ if (fRestoreMask & (1 << s)) {
+ *fDrawState->sampler(s)->matrix() = fSamplerMatrices[s];
+ }
+ }
+ }
+ fDrawState = NULL;
+}
+
+void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
+ const GrMatrix& preconcatMatrix,
+ uint32_t explicitCoordStageMask) {
+ this->restore();
+
+ fDrawState = drawState;
+ if (NULL == drawState) {
+ return;
+ }
+
+ fRestoreMask = 0;
+ fViewMatrix = drawState->getViewMatrix();
+ drawState->preConcatViewMatrix(preconcatMatrix);
+ for (int s = 0; s < GrDrawState::kNumStages; ++s) {
+ if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) {
+ fRestoreMask |= (1 << s);
+ drawState->sampler(s)->preConcatMatrix(preconcatMatrix);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrDrawState::AutoDeviceCoordDraw::restore() {
+ if (NULL != fDrawState) {
+ fDrawState->setViewMatrix(fViewMatrix);
+ for (int s = 0; s < GrDrawState::kNumStages; ++s) {
+ if (fRestoreMask & (1 << s)) {
+ *fDrawState->sampler(s)->matrix() = fSamplerMatrices[s];
+ }
+ }
+ }
+ fDrawState = NULL;
+}
+
+bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState,
+ uint32_t explicitCoordStageMask) {
GrAssert(NULL != drawState);
+ this->restore();
+
fDrawState = drawState;
+ if (NULL == fDrawState) {
+ return false;
+ }
+
fViewMatrix = drawState->getViewMatrix();
fRestoreMask = 0;
GrMatrix invVM;
@@ -64,7 +117,7 @@ GrDrawState::AutoDeviceCoordDraw::AutoDeviceCoordDraw(GrDrawState* drawState,
if (!inverted && !fViewMatrix.invert(&invVM)) {
// sad trombone sound
fDrawState = NULL;
- return;
+ return false;
} else {
inverted = true;
}
@@ -75,15 +128,5 @@ GrDrawState::AutoDeviceCoordDraw::AutoDeviceCoordDraw(GrDrawState* drawState,
}
}
drawState->viewMatrix()->reset();
-}
-
-GrDrawState::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() {
- if (NULL != fDrawState) {
- fDrawState->setViewMatrix(fViewMatrix);
- for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- if (fRestoreMask & (1 << s)) {
- *fDrawState->sampler(s)->matrix() = fSamplerMatrices[s];
- }
- }
- }
+ return true;
}
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index ea8f418364..5dccb1581d 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -467,70 +467,72 @@ public:
////////////////////////////////////////////////////////////////////////////
/**
- * TODO: Automatically handle stage matrices.
+ * Preconcats the current view matrix and restores the previous view matrix in the destructor.
+ * Stage matrices are automatically adjusted to compensate.
*/
class AutoViewMatrixRestore : public ::GrNoncopyable {
public:
AutoViewMatrixRestore() : fDrawState(NULL) {}
- AutoViewMatrixRestore(GrDrawState* ds, const GrMatrix& newMatrix) {
- fDrawState = NULL;
- this->set(ds, newMatrix);
- }
- AutoViewMatrixRestore(GrDrawState* ds) {
+
+ AutoViewMatrixRestore(GrDrawState* ds,
+ const GrMatrix& preconcatMatrix,
+ uint32_t explicitCoordStageMask = 0) {
fDrawState = NULL;
- this->set(ds);
- }
- ~AutoViewMatrixRestore() {
- this->set(NULL, GrMatrix::I());
- }
- void set(GrDrawState* ds, const GrMatrix& newMatrix) {
- if (NULL != fDrawState) {
- fDrawState->setViewMatrix(fSavedMatrix);
- }
- if (NULL != ds) {
- fSavedMatrix = ds->getViewMatrix();
- ds->setViewMatrix(newMatrix);
- }
- fDrawState = ds;
- }
- void set(GrDrawState* ds) {
- if (NULL != fDrawState) {
- fDrawState->setViewMatrix(fSavedMatrix);
- }
- if (NULL != ds) {
- fSavedMatrix = ds->getViewMatrix();
- }
- fDrawState = ds;
+ this->set(ds, preconcatMatrix, explicitCoordStageMask);
}
+
+ ~AutoViewMatrixRestore() { this->restore(); }
+
+ void restore();
+
+ void set(GrDrawState* drawState,
+ const GrMatrix& preconcatMatrix,
+ uint32_t explicitCoordStageMask = 0);
+
bool isSet() const { return NULL != fDrawState; }
+
private:
- GrDrawState* fDrawState;
- GrMatrix fSavedMatrix;
+ GrDrawState* fDrawState;
+ GrMatrix fViewMatrix;
+ GrMatrix fSamplerMatrices[GrDrawState::kNumStages];
+ uint32_t fRestoreMask;
};
////////////////////////////////////////////////////////////////////////////
/**
- * This sets the view matrix to identity and adjusts stage matrices to
- * compensate. The destructor undoes the changes, restoring the view matrix
- * that was set before the constructor.
+ * This sets the view matrix to identity and adjusts stage matrices to compensate. The
+ * destructor undoes the changes, restoring the view matrix that was set before the
+ * constructor. It is similar to passing the inverse of the current view matrix to
+ * AutoViewMatrixRestore, but lazily computes the inverse only if necessary.
*/
class AutoDeviceCoordDraw : ::GrNoncopyable {
public:
+ AutoDeviceCoordDraw() : fDrawState(NULL) {}
/**
- * If a stage's texture matrix is applied to explicit per-vertex coords,
- * rather than to positions, then we don't want to modify its matrix.
- * The explicitCoordStageMask is used to specify such stages.
+ * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to
+ * 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);
+ uint32_t explicitCoordStageMask = 0) {
+ fDrawState = NULL;
+ this->set(drawState, explicitCoordStageMask);
+ }
+
+ bool set(GrDrawState* drawState, uint32_t explicitCoordStageMask = 0);
+
bool succeeded() const { return NULL != fDrawState; }
- ~AutoDeviceCoordDraw();
+
+ void restore();
+
+ ~AutoDeviceCoordDraw() { this->restore(); }
+
private:
GrDrawState* fDrawState;
GrMatrix fViewMatrix;
GrMatrix fSamplerMatrices[GrDrawState::kNumStages];
- int fRestoreMask;
+ uint32_t fRestoreMask;
};
/// @}
diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp
index 5a6b9db106..a3f57cd9a2 100644
--- a/src/gpu/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/GrStencilAndCoverPathRenderer.cpp
@@ -66,7 +66,6 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
GrAssert(drawState->getStencil().isDisabled());
SkAutoTUnref<GrPath> p(fGpu->createPath(path));
- GrDrawState::AutoViewMatrixRestore avmr;
GrPathFill nonInvertedFill = GrNonInvertedFill(fill);
target->stencilPath(p, nonInvertedFill);
@@ -77,6 +76,8 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
// fill the path, zero out the stencil
GrRect bounds = p->getBounds();
GrScalar bloat = drawState->getViewMatrix().getMaxStretch() * GR_ScalarHalf;
+ GrDrawState::AutoDeviceCoordDraw adcd;
+
if (nonInvertedFill == fill) {
GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
kZero_StencilOp,
@@ -107,12 +108,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
// theoretically could set bloat = 0, instead leave it because of matrix inversion
// precision.
} else {
- avmr.set(drawState);
- if (!drawState->preConcatSamplerMatricesWithInverse(drawState->getViewMatrix())) {
- GrPrintf("Could not invert matrix.\n");
- return false;
- }
- drawState->viewMatrix()->reset();
+ adcd.set(drawState);
bloat = 0;
}
*drawState->stencil() = kInvertedStencilPass;