diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-10-08 17:15:55 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-10-08 17:15:55 +0000 |
commit | 2fdcdeb86788206c23410109b3e2b7976747fd11 (patch) | |
tree | fd780e51a91a279ddfa9147cf54a573d15208c00 /src | |
parent | 0f11e1ab5b6e53f6176dde2dbb25a8e3ae34858f (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.cpp | 21 | ||||
-rw-r--r-- | src/gpu/GrDrawState.cpp | 71 | ||||
-rw-r--r-- | src/gpu/GrDrawState.h | 82 | ||||
-rw-r--r-- | src/gpu/GrStencilAndCoverPathRenderer.cpp | 10 |
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; |