aboutsummaryrefslogtreecommitdiffhomepage
path: root/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-06-14 18:46:24 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-06-14 18:46:24 +0000
commit7ac249bdc7a86bc44610e02abeeaa0c14ba8163a (patch)
treee09b8d36b52e5c27256341116a9540e8a2906cda /gpu
parentbaa677b24896b67ecb08fc3b13c4c36953243a7d (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.h17
-rw-r--r--gpu/src/GrContext.cpp30
-rw-r--r--gpu/src/GrDrawTarget.cpp37
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]);
+ }
+ }
+}
+