From 5dfb67219a308edecafbe09eebb35c5e149db6e6 Mon Sep 17 00:00:00 2001 From: "robertphillips@google.com" Date: Mon, 9 Jul 2012 16:32:28 +0000 Subject: [PATCH] Left over cleanup from r4416 (fix for lingering AA clip mask bug) http://codereview.appspot.com/6356058/ git-svn-id: http://skia.googlecode.com/svn/trunk@4474 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/gpu/GrClipMaskManager.cpp | 39 ++++++------------------ src/gpu/GrSWMaskHelper.cpp | 61 +++++++++++++++++++++++++++++--------- src/gpu/GrSWMaskHelper.h | 30 ++++++++++++++----- src/gpu/GrSoftwarePathRenderer.cpp | 50 ++++++++++--------------------- 4 files changed, 94 insertions(+), 86 deletions(-) diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index cdc13f0..c37affa 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -360,40 +360,19 @@ bool draw_path_in_software(GrContext* context, bool doAA, const GrIRect& resultBounds) { - GrAutoScratchTexture ast; - - if (!GrSWMaskHelper::DrawToTexture(context, path, resultBounds, fill, - &ast, doAA, NULL)) { + SkAutoTUnref texture( + GrSWMaskHelper::DrawPathMaskToTexture(context, path, + resultBounds, fill, + doAA, NULL)); + if (NULL == texture) { return false; } - // TODO: merge this with the similar code in the GrSoftwarePathRenderer.cpp - SkAutoTUnref texture(ast.detach()); - GrAssert(NULL != texture); + // The ClipMaskManager accumulates the clip mask in the UL corner + GrIRect rect = GrIRect::MakeWH(resultBounds.width(), resultBounds.height()); + + GrSWMaskHelper::DrawToTargetWithPathMask(texture, gpu, 0, rect); - GrDrawState::StageMask stageMask = 0; - GrDrawTarget::AutoDeviceCoordDraw adcd(gpu, stageMask); - enum { - // the SW path renderer shares this stage with glyph - // rendering (kGlyphMaskStage in GrBatchedTextContext) - kPathMaskStage = GrPaint::kTotalStages, - }; - GrAssert(NULL == gpu->drawState()->getTexture(kPathMaskStage)); - gpu->drawState()->setTexture(kPathMaskStage, texture); - gpu->drawState()->sampler(kPathMaskStage)->reset(); - GrScalar w = GrIntToScalar(resultBounds.width()); - GrScalar h = GrIntToScalar(resultBounds.height()); - GrRect maskRect = GrRect::MakeWH(w / texture->width(), - h / texture->height()); - - const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; - srcRects[kPathMaskStage] = &maskRect; - stageMask |= 1 << kPathMaskStage; - GrRect dstRect = GrRect::MakeWH( - SK_Scalar1* resultBounds.width(), - SK_Scalar1* resultBounds.height()); - gpu->drawRect(dstRect, NULL, stageMask, srcRects, NULL); - gpu->drawState()->setTexture(kPathMaskStage, NULL); GrAssert(!GrIsFillInverted(fill)); return true; } diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index e34151c..fe32110 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -169,30 +169,63 @@ void GrSWMaskHelper::toTexture(GrTexture *texture, uint8_t alpha) { //////////////////////////////////////////////////////////////////////////////// /** * Software rasterizes path to A8 mask (possibly using the context's matrix) - * and uploads the result to a scratch texture. Returns true on success; - * false on failure. + * and uploads the result to a scratch texture. Returns the resulting + * texture on success; NULL on failure. */ -bool GrSWMaskHelper::DrawToTexture(GrContext* context, - const SkPath& path, - const GrIRect& resultBounds, - GrPathFill fill, - GrAutoScratchTexture* result, - bool antiAlias, - GrMatrix* matrix) { +GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrContext* context, + const SkPath& path, + const GrIRect& resultBounds, + GrPathFill fill, + bool antiAlias, + GrMatrix* matrix) { + GrAutoScratchTexture ast; + GrSWMaskHelper helper(context); if (!helper.init(resultBounds, matrix)) { - return false; + return NULL; } helper.draw(path, SkRegion::kReplace_Op, fill, antiAlias, 0xFF); - if (!helper.getTexture(result)) { - return false; + if (!helper.getTexture(&ast)) { + return NULL; } - helper.toTexture(result->texture(), 0x00); + helper.toTexture(ast.texture(), 0x00); - return true; + return ast.detach(); +} + +void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture, + GrDrawTarget* target, + GrDrawState::StageMask stageMask, + const GrIRect& rect) { + GrDrawState* drawState = target->drawState(); + + GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); + enum { + // the SW path renderer shares this stage with glyph + // rendering (kGlyphMaskStage in GrBatchedTextContext) + kPathMaskStage = GrPaint::kTotalStages, + }; + GrAssert(!drawState->isStageEnabled(kPathMaskStage)); + drawState->setTexture(kPathMaskStage, texture); + drawState->sampler(kPathMaskStage)->reset(); + GrScalar w = GrIntToScalar(rect.width()); + GrScalar h = GrIntToScalar(rect.height()); + GrRect maskRect = GrRect::MakeWH(w / texture->width(), + h / texture->height()); + + const GrRect* srcRects[GrDrawState::kNumStages] = { NULL }; + srcRects[kPathMaskStage] = &maskRect; + stageMask |= 1 << kPathMaskStage; + GrRect dstRect = GrRect::MakeLTRB( + SK_Scalar1 * rect.fLeft, + SK_Scalar1 * rect.fTop, + SK_Scalar1 * rect.fRight, + SK_Scalar1 * rect.fBottom); + target->drawRect(dstRect, NULL, stageMask, srcRects, NULL); + drawState->setTexture(kPathMaskStage, NULL); } diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h index 54ae089..c8a9f2a 100644 --- a/src/gpu/GrSWMaskHelper.h +++ b/src/gpu/GrSWMaskHelper.h @@ -15,11 +15,13 @@ #include "SkDraw.h" #include "SkRasterClip.h" #include "SkRegion.h" +#include "GrDrawState.h" class GrAutoScratchTexture; class GrContext; class GrTexture; class SkPath; +class GrDrawTarget; /** * The GrSWMaskHelper helps generate clip masks using the software rendering @@ -70,13 +72,27 @@ public: // Canonical usage utility that draws a single path and uploads it // to the GPU. The result is returned in "result". - static bool DrawToTexture(GrContext* context, - const SkPath& path, - const GrIRect& resultBounds, - GrPathFill fill, - GrAutoScratchTexture* result, - bool antiAlias, - GrMatrix* matrix); + static GrTexture* DrawPathMaskToTexture(GrContext* context, + const SkPath& path, + const GrIRect& resultBounds, + GrPathFill fill, + bool antiAlias, + GrMatrix* matrix); + + // This utility routine is used to add a path's mask to some other draw. + // The ClipMaskManager uses it to accumulate clip masks while the + // GrSoftwarePathRenderer uses it to fulfill a drawPath call. + // It draws with "texture" as a path mask into "target" using "rect" as + // geometry and the current drawState. The current drawState is altered to + // accommodate the mask. + // Note that this method assumes that the GrPaint::kTotalStages slot in + // the draw state can be used to hold the mask texture stage. + // This method is really only intended to be used with the + // output of DrawPathMaskToTexture. + static void DrawToTargetWithPathMask(GrTexture* texture, + GrDrawTarget* target, + GrDrawState::StageMask stageMask, + const GrIRect& rect); protected: private: diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp index f1c87a4..bccfc47 100644 --- a/src/gpu/GrSoftwarePathRenderer.cpp +++ b/src/gpu/GrSoftwarePathRenderer.cpp @@ -123,7 +123,6 @@ bool GrSoftwarePathRenderer::onDrawPath(const SkPath& path, vm.postTranslate(translate->fX, translate->fY); } - GrAutoScratchTexture ast; GrIRect pathBounds, clipBounds; if (!get_path_and_clip_bounds(target, path, vm, &pathBounds, &clipBounds)) { @@ -134,40 +133,21 @@ bool GrSoftwarePathRenderer::onDrawPath(const SkPath& path, return true; } - if (GrSWMaskHelper::DrawToTexture(fContext, path, pathBounds, fill, - &ast, antiAlias, &vm)) { - SkAutoTUnref texture(ast.detach()); - GrAssert(NULL != texture); - GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); - enum { - // the SW path renderer shares this stage with glyph - // rendering (kGlyphMaskStage in GrBatchedTextContext) - kPathMaskStage = GrPaint::kTotalStages, - }; - GrAssert(NULL == drawState->getTexture(kPathMaskStage)); - drawState->setTexture(kPathMaskStage, texture); - drawState->sampler(kPathMaskStage)->reset(); - GrScalar w = GrIntToScalar(pathBounds.width()); - GrScalar h = GrIntToScalar(pathBounds.height()); - GrRect maskRect = GrRect::MakeWH(w / texture->width(), - h / texture->height()); - - const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; - srcRects[kPathMaskStage] = &maskRect; - stageMask |= 1 << kPathMaskStage; - GrRect dstRect = GrRect::MakeLTRB( - SK_Scalar1* pathBounds.fLeft, - SK_Scalar1* pathBounds.fTop, - SK_Scalar1* pathBounds.fRight, - SK_Scalar1* pathBounds.fBottom); - target->drawRect(dstRect, NULL, stageMask, srcRects, NULL); - drawState->setTexture(kPathMaskStage, NULL); - if (GrIsFillInverted(fill)) { - draw_around_inv_path(target, stageMask, - clipBounds, pathBounds); - } - return true; + SkAutoTUnref texture( + GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, + pathBounds, fill, + antiAlias, &vm)); + if (NULL == texture) { + return false; } - return false; + GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, + stageMask, pathBounds); + + if (GrIsFillInverted(fill)) { + draw_around_inv_path(target, stageMask, + clipBounds, pathBounds); + } + + return true; } -- 2.7.4