diff options
-rw-r--r-- | src/gpu/GrSoftwarePathRenderer.cpp | 159 |
1 files changed, 103 insertions, 56 deletions
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp index 22e4a2641a..ae2c8931a2 100644 --- a/src/gpu/GrSoftwarePathRenderer.cpp +++ b/src/gpu/GrSoftwarePathRenderer.cpp @@ -94,12 +94,108 @@ bool get_path_and_clip_bounds(const GrDrawTarget* target, return true; } +/** + * The GrSWMaskHelper helps generate clip masks using the software rendering + * path. + */ +class GrSWMaskHelper : public GrNoncopyable { +public: + GrSWMaskHelper(GrContext* context) + : fContext(context) { + + } + + /** + * Draw a single element of the clip stack into the accumulation bitmap + */ + void draw(const SkPath& clientPath, GrPathFill fill, bool antiAlias) { + SkPaint paint; + SkPath tmpPath; + const SkPath* pathToDraw = &clientPath; + if (kHairLine_PathFill == fill) { + paint.setStyle(SkPaint::kStroke_Style); + paint.setStrokeWidth(SK_Scalar1); + } else { + paint.setStyle(SkPaint::kFill_Style); + SkPath::FillType skfill = gr_fill_to_sk_fill(fill); + if (skfill != pathToDraw->getFillType()) { + tmpPath = *pathToDraw; + tmpPath.setFillType(skfill); + pathToDraw = &tmpPath; + } + } + paint.setAntiAlias(antiAlias); + paint.setColor(SK_ColorWHITE); + + fDraw.drawPath(*pathToDraw, paint); + } + + bool init(const GrIRect& pathDevBounds, const GrPoint* translate) { + fMatrix = fContext->getMatrix(); + if (NULL != translate) { + fMatrix.postTranslate(translate->fX, translate->fY); + } + + fMatrix.postTranslate(-pathDevBounds.fLeft * SK_Scalar1, + -pathDevBounds.fTop * SK_Scalar1); + GrIRect bounds = GrIRect::MakeWH(pathDevBounds.width(), + pathDevBounds.height()); + + fBM.setConfig(SkBitmap::kA8_Config, bounds.fRight, bounds.fBottom); + if (!fBM.allocPixels()) { + return false; + } + sk_bzero(fBM.getPixels(), fBM.getSafeSize()); + + sk_bzero(&fDraw, sizeof(fDraw)); + fRasterClip.setRect(bounds); + fDraw.fRC = &fRasterClip; + fDraw.fClip = &fRasterClip.bwRgn(); + fDraw.fMatrix = &fMatrix; + fDraw.fBitmap = &fBM; + return true; + } + + /** + * Move the result of the software mask generation back to the gpu + */ + bool toTexture(GrAutoScratchTexture* tex) { + const GrTextureDesc desc = { + kNone_GrTextureFlags, + fBM.width(), + fBM.height(), + kAlpha_8_GrPixelConfig, + 0 // samples + }; + + tex->set(fContext, desc); + GrTexture* texture = tex->texture(); + + if (NULL == texture) { + return false; + } + SkAutoLockPixels alp(fBM); + texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, + fBM.getPixels(), fBM.rowBytes()); + return true; + } + +protected: +private: + GrContext* fContext; + GrMatrix fMatrix; + SkBitmap fBM; + SkDraw fDraw; + SkRasterClip fRasterClip; + + typedef GrPathRenderer INHERITED; +}; + //////////////////////////////////////////////////////////////////////////////// /** * sw rasterizes path to A8 mask using the context's matrix and uploads to a * scratch texture. */ - bool sw_draw_path_to_mask_texture(const SkPath& clientPath, const GrIRect& pathDevBounds, GrPathFill fill, @@ -107,67 +203,18 @@ bool sw_draw_path_to_mask_texture(const SkPath& clientPath, const GrPoint* translate, GrAutoScratchTexture* tex, bool antiAlias) { - SkPaint paint; - SkPath tmpPath; - const SkPath* pathToDraw = &clientPath; - if (kHairLine_PathFill == fill) { - paint.setStyle(SkPaint::kStroke_Style); - paint.setStrokeWidth(SK_Scalar1); - } else { - paint.setStyle(SkPaint::kFill_Style); - SkPath::FillType skfill = gr_fill_to_sk_fill(fill); - if (skfill != pathToDraw->getFillType()) { - tmpPath = *pathToDraw; - tmpPath.setFillType(skfill); - pathToDraw = &tmpPath; - } - } - paint.setAntiAlias(antiAlias); - paint.setColor(SK_ColorWHITE); + GrSWMaskHelper helper(context); - GrMatrix matrix = context->getMatrix(); - if (NULL != translate) { - matrix.postTranslate(translate->fX, translate->fY); + if (!helper.init(pathDevBounds, translate)) { + return false; } - matrix.postTranslate(-pathDevBounds.fLeft * SK_Scalar1, - -pathDevBounds.fTop * SK_Scalar1); - GrIRect bounds = GrIRect::MakeWH(pathDevBounds.width(), - pathDevBounds.height()); + helper.draw(clientPath, fill, antiAlias); - SkBitmap bm; - bm.setConfig(SkBitmap::kA8_Config, bounds.fRight, bounds.fBottom); - if (!bm.allocPixels()) { - return false; - } - sk_bzero(bm.getPixels(), bm.getSafeSize()); - - SkDraw draw; - sk_bzero(&draw, sizeof(draw)); - SkRasterClip rc(bounds); - draw.fRC = &rc; - draw.fClip = &rc.bwRgn(); - draw.fMatrix = &matrix; - draw.fBitmap = &bm; - draw.drawPath(*pathToDraw, paint); - - const GrTextureDesc desc = { - kNone_GrTextureFlags, - bounds.fRight, - bounds.fBottom, - kAlpha_8_GrPixelConfig, - 0 // samples - }; - - tex->set(context, desc); - GrTexture* texture = tex->texture(); - - if (NULL == texture) { + if (!helper.toTexture(tex)) { return false; } - SkAutoLockPixels alp(bm); - texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, - bm.getPixels(), bm.rowBytes()); + return true; } |