diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-06-14 18:46:24 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-06-14 18:46:24 +0000 |
commit | 7ac249bdc7a86bc44610e02abeeaa0c14ba8163a (patch) | |
tree | e09b8d36b52e5c27256341116a9540e8a2906cda /gpu | |
parent | baa677b24896b67ecb08fc3b13c4c36953243a7d (diff) |
Enable SSAA on inverse filled paths
Review URL: http://codereview.appspot.com/4613044/
git-svn-id: http://skia.googlecode.com/svn/trunk@1584 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/include/GrDrawTarget.h | 17 | ||||
-rw-r--r-- | gpu/src/GrContext.cpp | 30 | ||||
-rw-r--r-- | gpu/src/GrDrawTarget.cpp | 37 |
3 files changed, 81 insertions, 3 deletions
diff --git a/gpu/include/GrDrawTarget.h b/gpu/include/GrDrawTarget.h index cd70d3e7c5..d8d0498ae3 100644 --- a/gpu/include/GrDrawTarget.h +++ b/gpu/include/GrDrawTarget.h @@ -891,6 +891,23 @@ public: /////////////////////////////////////////////////////////////////////////// + /** + * Sets the view matrix to I and preconcats all stage matrices enabled in + * mask by the view inverse. Destructor undoes these changes. + */ + class AutoDeviceCoordDraw : ::GrNoncopyable { + public: + AutoDeviceCoordDraw(GrDrawTarget* target, int stageMask); + ~AutoDeviceCoordDraw(); + private: + GrDrawTarget* fDrawTarget; + GrMatrix fViewMatrix; + GrMatrix fSamplerMatrices[kNumStages]; + int fStageMask; + }; + + /////////////////////////////////////////////////////////////////////////// + class AutoReleaseGeometry : ::GrNoncopyable { public: AutoReleaseGeometry(GrDrawTarget* target, diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp index 773c5738d1..ab5ac06839 100644 --- a/gpu/src/GrContext.cpp +++ b/gpu/src/GrContext.cpp @@ -1226,8 +1226,7 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path, GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); GrPathRenderer* pr = this->getPathRenderer(target, path, fill); - if (!IsFillInverted(fill) && // will be relaxed soon - !pr->supportsAA(target, path, fill) && + if (!pr->supportsAA(target, path, fill) && this->doOffscreenAA(target, paint, kHairLine_PathFill == fill)) { bool needsStencil = pr->requiresStencilPass(target, path, fill); @@ -1235,8 +1234,8 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path, // compute bounds as intersection of rt size, clip, and path GrIRect bound = SkIRect::MakeWH(target->getRenderTarget()->width(), target->getRenderTarget()->height()); + GrIRect clipIBounds; if (target->getClip().hasConservativeBounds()) { - GrIRect clipIBounds; target->getClip().getConservativeBounds().roundOut(&clipIBounds); if (!bound.intersect(clipIBounds)) { return; @@ -1265,6 +1264,31 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path, } } this->cleanupOffscreenAA(target, &record); + if (IsFillInverted(fill) && bound != clipIBounds) { + int stageMask = paint.getActiveStageMask(); + GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); + GrRect rect; + if (clipIBounds.fTop < bound.fTop) { + rect.setLTRB(clipIBounds.fLeft, clipIBounds.fTop, + clipIBounds.fRight, bound.fTop); + target->drawSimpleRect(rect, NULL, stageMask); + } + if (clipIBounds.fLeft < bound.fLeft) { + rect.setLTRB(clipIBounds.fLeft, bound.fTop, + bound.fLeft, bound.fBottom); + target->drawSimpleRect(rect, NULL, stageMask); + } + if (clipIBounds.fRight > bound.fRight) { + rect.setLTRB(bound.fRight, bound.fTop, + clipIBounds.fRight, bound.fBottom); + target->drawSimpleRect(rect, NULL, stageMask); + } + if (clipIBounds.fBottom > bound.fBottom) { + rect.setLTRB(clipIBounds.fLeft, bound.fBottom, + clipIBounds.fRight, clipIBounds.fBottom); + target->drawSimpleRect(rect, NULL, stageMask); + } + } return; } } diff --git a/gpu/src/GrDrawTarget.cpp b/gpu/src/GrDrawTarget.cpp index 2848999fe4..b5f92598e1 100644 --- a/gpu/src/GrDrawTarget.cpp +++ b/gpu/src/GrDrawTarget.cpp @@ -649,6 +649,7 @@ void GrDrawTarget::SetRectVertices(const GrRect& rect, } /////////////////////////////////////////////////////////////////////////////// + GrDrawTarget::AutoStateRestore::AutoStateRestore() { fDrawTarget = NULL; } @@ -677,3 +678,39 @@ void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target) { fDrawTarget = target; } } + +/////////////////////////////////////////////////////////////////////////////// + +GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(GrDrawTarget* target, + int stageMask) { + GrAssert(NULL != target); + + fDrawTarget = target; + fViewMatrix = target->getViewMatrix(); + fStageMask = stageMask; + if (fStageMask) { + GrMatrix invVM; + if (fViewMatrix.invert(&invVM)) { + for (int s = 0; s < kNumStages; ++s) { + if (fStageMask & (1 << s)) { + fSamplerMatrices[s] = target->getSamplerMatrix(s); + } + } + target->preConcatSamplerMatrices(fStageMask, invVM); + } else { + // sad trombone sound + fStageMask = 0; + } + } + target->setViewMatrix(GrMatrix::I()); +} + +GrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() { + fDrawTarget->setViewMatrix(fViewMatrix); + for (int s = 0; s < kNumStages; ++s) { + if (fStageMask & (1 << s)) { + fDrawTarget->setSamplerMatrix(s, fSamplerMatrices[s]); + } + } +} + |