Fix direct-to-stencil clippath rendering logic in GrGpu.
Review URL: http://codereview.appspot.com/4273104/
git-svn-id: http://skia.googlecode.com/svn/trunk@1001 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index 2d763e2..d60287b 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -414,43 +414,63 @@
// enabled at bottom of loop
this->disableState(kModifyStencilClip_StateBit);
- bool canDrawDirectToClip;
+ bool canRenderDirectToStencil; // can the clip element be drawn
+ // directly to the stencil buffer
+ // with a non-inverted fill rule
+ // without extra passes to
+ // resolve in/out status.
if (kRect_ClipType == clip.getElementType(c)) {
- canDrawDirectToClip = true;
+ canRenderDirectToStencil = true;
fill = kEvenOdd_PathFill;
} else {
fill = clip.getPathFill(c);
GrPathRenderer* pr = this->getPathRenderer();
- canDrawDirectToClip = pr->requiresStencilPass(this, clip.getPath(c), fill);
+ canRenderDirectToStencil =
+ !pr->requiresStencilPass(this, clip.getPath(c),
+ NonInvertedFill(fill));
}
GrSetOp op = firstElement == c ? kReplace_SetOp : clip.getOp(c);
int passes;
GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClipPasses];
- canDrawDirectToClip = GrStencilSettings::GetClipPasses(op, canDrawDirectToClip,
- clipBit, IsFillInverted(fill),
- &passes, stencilSettings);
+ bool canDrawDirectToClip; // Given the renderer, the element,
+ // fill rule, and set operation can
+ // we render the element directly to
+ // stencil bit used for clipping.
+ canDrawDirectToClip =
+ GrStencilSettings::GetClipPasses(op,
+ canRenderDirectToStencil,
+ clipBit,
+ IsFillInverted(fill),
+ &passes, stencilSettings);
// draw the element to the client stencil bits if necessary
if (!canDrawDirectToClip) {
+ static const GrStencilSettings gDrawToStencil = {
+ kIncClamp_StencilOp, kIncClamp_StencilOp,
+ kIncClamp_StencilOp, kIncClamp_StencilOp,
+ kAlways_StencilFunc, kAlways_StencilFunc,
+ 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff,
+ };
+ SET_RANDOM_COLOR
if (kRect_ClipType == clip.getElementType(c)) {
- static const GrStencilSettings gDrawToStencil = {
- kIncClamp_StencilOp, kIncClamp_StencilOp,
- kIncClamp_StencilOp, kIncClamp_StencilOp,
- kAlways_StencilFunc, kAlways_StencilFunc,
- 0xffffffff, 0xffffffff,
- 0x00000000, 0x00000000,
- 0xffffffff, 0xffffffff,
- };
this->setStencil(gDrawToStencil);
- SET_RANDOM_COLOR
this->drawSimpleRect(clip.getRect(c), NULL, 0);
} else {
- SET_RANDOM_COLOR
- getPathRenderer()->drawPathToStencil(this, clip.getPath(c),
- NonInvertedFill(fill),
- NULL);
+ if (canRenderDirectToStencil) {
+ this->setStencil(gDrawToStencil);
+ getPathRenderer()->drawPath(this, 0,
+ clip.getPath(c),
+ NonInvertedFill(fill),
+ NULL);
+ } else {
+ getPathRenderer()->drawPathToStencil(this, clip.getPath(c),
+ NonInvertedFill(fill),
+ NULL);
+ }
}
}
@@ -465,6 +485,7 @@
this->drawSimpleRect(clip.getRect(c), NULL, 0);
} else {
SET_RANDOM_COLOR
+ GrAssert(!IsFillInverted(fill));
getPathRenderer()->drawPath(this, 0,
clip.getPath(c),
fill, NULL);
diff --git a/gpu/src/GrPathRenderer.cpp b/gpu/src/GrPathRenderer.cpp
index 6d7aabb..fc3c124 100644
--- a/gpu/src/GrPathRenderer.cpp
+++ b/gpu/src/GrPathRenderer.cpp
@@ -294,7 +294,7 @@
bool GrDefaultPathRenderer::requiresStencilPass(const GrDrawTarget* target,
GrPathIter* path,
GrPathFill fill) const {
- return single_pass_path(*target, *path, fill);
+ return !single_pass_path(*target, *path, fill);
}
void GrDefaultPathRenderer::drawPathHelper(GrDrawTarget* target,
diff --git a/gpu/src/GrPathRenderer.h b/gpu/src/GrPathRenderer.h
index 19e284f..30bdb5a 100644
--- a/gpu/src/GrPathRenderer.h
+++ b/gpu/src/GrPathRenderer.h
@@ -68,7 +68,8 @@
*
* @param target target that the path will be rendered to
* @param path the path that will be drawn
- * @param fill the fill rule that will be used
+ * @param fill the fill rule that will be used, will never be an inverse
+ * rule.
*
* @return false if this path renderer can generate interior-only fragments
* without changing the stencil settings on the target. If it
diff --git a/gpu/src/GrStencil.cpp b/gpu/src/GrStencil.cpp
index a1c8c09..c366f61 100644
--- a/gpu/src/GrStencil.cpp
+++ b/gpu/src/GrStencil.cpp
@@ -249,7 +249,7 @@
bool invertedFill,
int* numPasses,
GrStencilSettings settings[kMaxStencilClipPasses]) {
- if (canBeDirect) {
+ if (canBeDirect && !invertedFill) {
*numPasses = 0;
switch (op) {
case kReplace_SetOp: