| 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;
|
|
|