Index: src/gpu/GrContext.cpp |
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp |
index 20c633dc67878d09bc9cff88e82cb04a2f72da1c..4d5551e4946e4477ce45594461b0b5c7cdae06cd 100644 |
--- a/src/gpu/GrContext.cpp |
+++ b/src/gpu/GrContext.cpp |
@@ -681,9 +681,8 @@ static bool isIRect(const SkRect& r) { |
static bool apply_aa_to_rect(GrDrawTarget* target, |
const SkRect& rect, |
SkScalar strokeWidth, |
- const SkMatrix* matrix, |
- SkMatrix* combinedMatrix, |
- SkRect* devRect, |
+ const SkMatrix& combinedMatrix, |
+ SkRect* devBoundRect, |
bool* useVertexCoverage) { |
// we use a simple coverage ramp to do aa on axis-aligned rects |
// we check if the rect will be axis-aligned, and the rect won't land on |
@@ -716,52 +715,32 @@ static bool apply_aa_to_rect(GrDrawTarget* target, |
#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) |
if (strokeWidth >= 0) { |
#endif |
- if (!drawState.getViewMatrix().preservesAxisAlignment()) { |
+ if (!combinedMatrix.preservesAxisAlignment()) { |
return false; |
} |
- if (NULL != matrix && !matrix->preservesAxisAlignment()) { |
- return false; |
- } |
#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) |
} else { |
- if (!drawState.getViewMatrix().preservesAxisAlignment() && |
- !drawState.getViewMatrix().preservesRightAngles()) { |
- return false; |
- } |
- |
- if (NULL != matrix && !matrix->preservesRightAngles()) { |
+ if (!combinedMatrix.preservesRightAngles()) { |
return false; |
} |
} |
#endif |
- *combinedMatrix = drawState.getViewMatrix(); |
- if (NULL != matrix) { |
- combinedMatrix->preConcat(*matrix); |
- |
-#if GR_DEBUG |
-#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) |
- if (strokeWidth >= 0) { |
-#endif |
- GrAssert(combinedMatrix->preservesAxisAlignment()); |
-#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) |
- } else { |
- GrAssert(combinedMatrix->preservesRightAngles()); |
- } |
-#endif |
-#endif |
- } |
- |
- combinedMatrix->mapRect(devRect, rect); |
+ combinedMatrix.mapRect(devBoundRect, rect); |
if (strokeWidth < 0) { |
- return !isIRect(*devRect); |
+ return !isIRect(*devBoundRect); |
} else { |
return true; |
} |
} |
+static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& point) { |
+ return point.fX >= rect.fLeft && point.fX <= rect.fRight && |
+ point.fY >= rect.fTop && point.fY <= rect.fBottom; |
+} |
+ |
void GrContext::drawRect(const GrPaint& paint, |
const SkRect& rect, |
SkScalar width, |
@@ -771,13 +750,51 @@ void GrContext::drawRect(const GrPaint& paint, |
AutoRestoreEffects are; |
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are); |
- SkRect devRect; |
- SkMatrix combinedMatrix; |
+ SkMatrix combinedMatrix = target->drawState()->getViewMatrix(); |
+ if (NULL != matrix) { |
+ combinedMatrix.preConcat(*matrix); |
+ } |
+ |
+ // Check if this is a full RT draw and can be replaced with a clear. We don't bother checking |
+ // cases where the RT is fully inside a stroke. |
+ if (width < 0) { |
+ SkRect rtRect; |
+ target->getDrawState().getRenderTarget()->getBoundsRect(&rtRect); |
+ SkRect clipSpaceRTRect = rtRect; |
+ bool checkClip = false; |
+ if (NULL != this->getClip()) { |
+ checkClip = true; |
+ clipSpaceRTRect.offset(SkIntToScalar(this->getClip()->fOrigin.fX), |
+ SkIntToScalar(this->getClip()->fOrigin.fY)); |
+ } |
+ // Does the clip contain the entire RT? |
+ if (!checkClip || target->getClip()->fClipStack->quickContains(clipSpaceRTRect)) { |
+ SkMatrix invM; |
+ if (!combinedMatrix.invert(&invM)) { |
+ return; |
+ } |
+ // Does the rect bound the RT? |
+ SkPoint srcSpaceRTQuad[4]; |
+ invM.mapRectToQuad(srcSpaceRTQuad, rtRect); |
+ if (rect_contains_inclusive(rect, srcSpaceRTQuad[0]) && |
+ rect_contains_inclusive(rect, srcSpaceRTQuad[1]) && |
+ rect_contains_inclusive(rect, srcSpaceRTQuad[2]) && |
+ rect_contains_inclusive(rect, srcSpaceRTQuad[3])) { |
+ // Will it blend? |
+ GrColor clearColor; |
+ if (paint.isOpaqueAndConstantColor(&clearColor)) { |
+ target->clear(NULL, clearColor); |
+ return; |
+ } |
+ } |
+ } |
+ } |
+ |
+ SkRect devBoundRect; |
bool useVertexCoverage; |
bool needAA = paint.isAntiAlias() && |
!target->getDrawState().getRenderTarget()->isMultisampled(); |
- bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, |
- &combinedMatrix, &devRect, |
+ bool doAA = needAA && apply_aa_to_rect(target, rect, width, combinedMatrix, &devBoundRect, |
&useVertexCoverage); |
if (doAA) { |
GrDrawState::AutoViewMatrixRestore avmr; |
@@ -786,12 +803,12 @@ void GrContext::drawRect(const GrPaint& paint, |
} |
if (width >= 0) { |
fAARectRenderer->strokeAARect(this->getGpu(), target, |
- rect, combinedMatrix, devRect, |
+ rect, combinedMatrix, devBoundRect, |
width, useVertexCoverage); |
} else { |
// filled AA rect |
fAARectRenderer->fillAARect(this->getGpu(), target, |
- rect, combinedMatrix, devRect, |
+ rect, combinedMatrix, devBoundRect, |
useVertexCoverage); |
} |
return; |