diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrClipMaskManager.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrSWMaskHelper.cpp | 181 | ||||
-rw-r--r-- | src/gpu/GrSWMaskHelper.h | 63 | ||||
-rw-r--r-- | src/gpu/GrSoftwarePathRenderer.cpp | 175 | ||||
-rw-r--r-- | src/gpu/GrSoftwarePathRenderer.h | 43 |
5 files changed, 246 insertions, 220 deletions
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 0c4353a3e0..cb543e1979 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -15,9 +15,7 @@ #include "SkRasterClip.h" #include "GrAAConvexPathRenderer.h" #include "GrAAHairLinePathRenderer.h" - -// TODO: move GrSWMaskHelper out of GrSoftwarePathRender.h & remove this include -#include "GrSoftwarePathRenderer.h" +#include "GrSWMaskHelper.h" //#define GR_AA_CLIP 1 //#define GR_SW_CLIP 1 diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp new file mode 100644 index 0000000000..f67336fe6c --- /dev/null +++ b/src/gpu/GrSWMaskHelper.cpp @@ -0,0 +1,181 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrSWMaskHelper.h" +#include "GrDrawState.h" +#include "GrGpu.h" + +// TODO: try to remove this #include +#include "GrContext.h" + +namespace { +/* + * Convert a boolean operation into a transfer mode code + */ +SkXfermode::Mode op_to_mode(SkRegion::Op op) { + + static const SkXfermode::Mode modeMap[] = { + SkXfermode::kDstOut_Mode, // kDifference_Op + SkXfermode::kMultiply_Mode, // kIntersect_Op + SkXfermode::kSrcOver_Mode, // kUnion_Op + SkXfermode::kXor_Mode, // kXOR_Op + SkXfermode::kClear_Mode, // kReverseDifference_Op + SkXfermode::kSrc_Mode, // kReplace_Op + }; + + return modeMap[op]; +} + +//////////////////////////////////////////////////////////////////////////////// +SkPath::FillType gr_fill_to_sk_fill(GrPathFill fill) { + switch (fill) { + case kWinding_GrPathFill: + return SkPath::kWinding_FillType; + case kEvenOdd_GrPathFill: + return SkPath::kEvenOdd_FillType; + case kInverseWinding_GrPathFill: + return SkPath::kInverseWinding_FillType; + case kInverseEvenOdd_GrPathFill: + return SkPath::kInverseEvenOdd_FillType; + default: + GrCrash("Unexpected fill."); + return SkPath::kWinding_FillType; + } +} + +} + +/** + * Draw a single rect element of the clip stack into the accumulation bitmap + */ +void GrSWMaskHelper::draw(const GrRect& clientRect, SkRegion::Op op, + bool antiAlias, GrColor color) { + SkPaint paint; + + SkXfermode* mode = SkXfermode::Create(op_to_mode(op)); + + paint.setXfermode(mode); + paint.setAntiAlias(antiAlias); + paint.setColor(color); + + fDraw.drawRect(clientRect, paint); + + SkSafeUnref(mode); +} + +/** + * Draw a single path element of the clip stack into the accumulation bitmap + */ +void GrSWMaskHelper::draw(const SkPath& clientPath, SkRegion::Op op, + GrPathFill fill, bool antiAlias, GrColor color) { + + SkPaint paint; + SkPath tmpPath; + const SkPath* pathToDraw = &clientPath; + if (kHairLine_GrPathFill == 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; + } + } + SkXfermode* mode = SkXfermode::Create(op_to_mode(op)); + + paint.setXfermode(mode); + paint.setAntiAlias(antiAlias); + paint.setColor(color); + + fDraw.drawPath(*pathToDraw, paint); + + SkSafeUnref(mode); +} + +bool GrSWMaskHelper::init(const GrIRect& pathDevBounds, + const GrPoint* translate, + bool useMatrix) { + if (useMatrix) { + fMatrix = fContext->getMatrix(); + } else { + fMatrix.setIdentity(); + } + + 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; +} + +/** + * Get a texture (from the texture cache) of the correct size & format + */ +bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* tex) { + GrTextureDesc desc; + desc.fWidth = fBM.width(); + desc.fHeight = fBM.height(); + desc.fConfig = kAlpha_8_GrPixelConfig; + + tex->set(fContext, desc); + GrTexture* texture = tex->texture(); + + if (NULL == texture) { + return false; + } + + return true; +} + +/** + * Move the result of the software mask generation back to the gpu + */ +void GrSWMaskHelper::toTexture(GrTexture *texture, bool clearToWhite) { + SkAutoLockPixels alp(fBM); + + // The destination texture is almost always larger than "fBM". Clear + // it appropriately so we don't get mask artifacts outside of the path's + // bounding box + + // "texture" needs to be installed as the render target for the clear + // and the texture upload but cannot remain the render target upon + // returned. Callers typically use it as a texture and it would then + // be both source and dest. + GrDrawState::AutoRenderTargetRestore artr(fContext->getGpu()->drawState(), + texture->asRenderTarget()); + + if (clearToWhite) { + fContext->getGpu()->clear(NULL, SK_ColorWHITE); + } else { + fContext->getGpu()->clear(NULL, 0x00000000); + } + + texture->writePixels(0, 0, fBM.width(), fBM.height(), + kAlpha_8_GrPixelConfig, + fBM.getPixels(), fBM.rowBytes()); +} + diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h new file mode 100644 index 0000000000..b789f99131 --- /dev/null +++ b/src/gpu/GrSWMaskHelper.h @@ -0,0 +1,63 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrSWMaskHelper_DEFINED +#define GrSWMaskHelper_DEFINED + +#include "GrColor.h" +#include "GrMatrix.h" +#include "GrNoncopyable.h" +#include "SkBitmap.h" +#include "SkDraw.h" +#include "SkRasterClip.h" +#include "SkRegion.h" + +class GrAutoScratchTexture; +class GrContext; +class GrTexture; +class SkPath; + +/** + * The GrSWMaskHelper helps generate clip masks using the software rendering + * path. + */ +class GrSWMaskHelper : public GrNoncopyable { +public: + GrSWMaskHelper(GrContext* context) + : fContext(context) { + } + + void draw(const GrRect& clientRect, SkRegion::Op op, + bool antiAlias, GrColor color); + + void draw(const SkPath& clientPath, SkRegion::Op op, + GrPathFill fill, bool antiAlias, GrColor color); + + bool init(const GrIRect& pathDevBounds, + const GrPoint* translate, + bool useMatrix); + + bool getTexture(GrAutoScratchTexture* tex); + + void toTexture(GrTexture* texture, bool clearToWhite); + + void clear(GrColor color) { + fBM.eraseColor(color); + } + +protected: +private: + GrContext* fContext; + GrMatrix fMatrix; + SkBitmap fBM; + SkDraw fDraw; + SkRasterClip fRasterClip; + + typedef GrNoncopyable INHERITED; +}; + +#endif GrSWMaskHelper_DEFINED diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp index 5e4f6f1735..2566a53db6 100644 --- a/src/gpu/GrSoftwarePathRenderer.cpp +++ b/src/gpu/GrSoftwarePathRenderer.cpp @@ -7,13 +7,8 @@ */ #include "GrSoftwarePathRenderer.h" -#include "GrPaint.h" -#include "SkPaint.h" -#include "GrRenderTarget.h" #include "GrContext.h" -#include "SkDraw.h" -#include "SkRasterClip.h" -#include "GrGpu.h" +#include "GrSWMaskHelper.h" //////////////////////////////////////////////////////////////////////////////// bool GrSoftwarePathRenderer::canDrawPath(const SkPath& path, @@ -36,23 +31,6 @@ bool GrSoftwarePathRenderer::canDrawPath(const SkPath& path, namespace { //////////////////////////////////////////////////////////////////////////////// -SkPath::FillType gr_fill_to_sk_fill(GrPathFill fill) { - switch (fill) { - case kWinding_GrPathFill: - return SkPath::kWinding_FillType; - case kEvenOdd_GrPathFill: - return SkPath::kEvenOdd_FillType; - case kInverseWinding_GrPathFill: - return SkPath::kInverseWinding_FillType; - case kInverseEvenOdd_GrPathFill: - return SkPath::kInverseEvenOdd_FillType; - default: - GrCrash("Unexpected fill."); - return SkPath::kWinding_FillType; - } -} - -//////////////////////////////////////////////////////////////////////////////// // gets device coord bounds of path (not considering the fill) and clip. The // path bounds will be a subset of the clip bounds. returns false if // path bounds would be empty. @@ -98,157 +76,6 @@ bool get_path_and_clip_bounds(const GrDrawTarget* target, return true; } - -/* - * Convert a boolean operation into a transfer mode code - */ -SkXfermode::Mode op_to_mode(SkRegion::Op op) { - - static const SkXfermode::Mode modeMap[] = { - SkXfermode::kDstOut_Mode, // kDifference_Op - SkXfermode::kMultiply_Mode, // kIntersect_Op - SkXfermode::kSrcOver_Mode, // kUnion_Op - SkXfermode::kXor_Mode, // kXOR_Op - SkXfermode::kClear_Mode, // kReverseDifference_Op - SkXfermode::kSrc_Mode, // kReplace_Op - }; - - return modeMap[op]; -} - -} - -/** - * Draw a single rect element of the clip stack into the accumulation bitmap - */ -void GrSWMaskHelper::draw(const GrRect& clientRect, SkRegion::Op op, - bool antiAlias, GrColor color) { - SkPaint paint; - - SkXfermode* mode = SkXfermode::Create(op_to_mode(op)); - - paint.setXfermode(mode); - paint.setAntiAlias(antiAlias); - paint.setColor(color); - - fDraw.drawRect(clientRect, paint); - - SkSafeUnref(mode); -} - -/** - * Draw a single path element of the clip stack into the accumulation bitmap - */ -void GrSWMaskHelper::draw(const SkPath& clientPath, SkRegion::Op op, - GrPathFill fill, bool antiAlias, GrColor color) { - - SkPaint paint; - SkPath tmpPath; - const SkPath* pathToDraw = &clientPath; - if (kHairLine_GrPathFill == 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; - } - } - SkXfermode* mode = SkXfermode::Create(op_to_mode(op)); - - paint.setXfermode(mode); - paint.setAntiAlias(antiAlias); - paint.setColor(color); - - fDraw.drawPath(*pathToDraw, paint); - - SkSafeUnref(mode); -} - -bool GrSWMaskHelper::init(const GrIRect& pathDevBounds, - const GrPoint* translate, - bool useMatrix) { - if (useMatrix) { - fMatrix = fContext->getMatrix(); - } else { - fMatrix.setIdentity(); - } - - 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; -} - -/** - * Get a texture (from the texture cache) of the correct size & format - */ -bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* tex) { - GrTextureDesc desc; - desc.fWidth = fBM.width(); - desc.fHeight = fBM.height(); - desc.fConfig = kAlpha_8_GrPixelConfig; - - tex->set(fContext, desc); - GrTexture* texture = tex->texture(); - - if (NULL == texture) { - return false; - } - - return true; -} - -/** - * Move the result of the software mask generation back to the gpu - */ -void GrSWMaskHelper::toTexture(GrTexture *texture, bool clearToWhite) { - SkAutoLockPixels alp(fBM); - - // The destination texture is almost always larger than "fBM". Clear - // it appropriately so we don't get mask artifacts outside of the path's - // bounding box - - // "texture" needs to be installed as the render target for the clear - // and the texture upload but cannot remain the render target upon - // returned. Callers typically use it as a texture and it would then - // be both source and dest. - GrDrawState::AutoRenderTargetRestore artr(fContext->getGpu()->drawState(), - texture->asRenderTarget()); - - if (clearToWhite) { - fContext->getGpu()->clear(NULL, SK_ColorWHITE); - } else { - fContext->getGpu()->clear(NULL, 0x00000000); - } - - texture->writePixels(0, 0, fBM.width(), fBM.height(), - kAlpha_8_GrPixelConfig, - fBM.getPixels(), fBM.rowBytes()); -} - -namespace { //////////////////////////////////////////////////////////////////////////////// /** * sw rasterizes path to A8 mask using the context's matrix and uploads to a diff --git a/src/gpu/GrSoftwarePathRenderer.h b/src/gpu/GrSoftwarePathRenderer.h index cb84506d27..a42090cbe7 100644 --- a/src/gpu/GrSoftwarePathRenderer.h +++ b/src/gpu/GrSoftwarePathRenderer.h @@ -11,53 +11,10 @@ #include "GrPathRenderer.h" -#include "SkDraw.h" -#include "SkRasterClip.h" - class GrContext; class GrAutoScratchTexture; /** - * The GrSWMaskHelper helps generate clip masks using the software rendering - * path. - */ -class GrSWMaskHelper : public GrNoncopyable { -public: - GrSWMaskHelper(GrContext* context) - : fContext(context) { - - } - - void draw(const GrRect& clientRect, SkRegion::Op op, - bool antiAlias, GrColor color); - - void draw(const SkPath& clientPath, SkRegion::Op op, - GrPathFill fill, bool antiAlias, GrColor color); - - bool init(const GrIRect& pathDevBounds, - const GrPoint* translate, - bool useMatrix); - - bool getTexture(GrAutoScratchTexture* tex); - - void toTexture(GrTexture* texture, bool clearToWhite); - - void clear(GrColor color) { - fBM.eraseColor(color); - } - -protected: -private: - GrContext* fContext; - GrMatrix fMatrix; - SkBitmap fBM; - SkDraw fDraw; - SkRasterClip fRasterClip; - - typedef GrPathRenderer INHERITED; -}; - -/** * This class uses the software side to render a path to an SkBitmap and * then uploads the result to the gpu */ |