Created SW clip mask creation helper class (in GrSoftwarePathRenderer)

http://codereview.appspot.com/6198070/



git-svn-id: http://skia.googlecode.com/svn/trunk@3925 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
robertphillips@google.com 2012-05-14 17:37:05 +00:00
parent 4debcac8c3
commit 6f31a3b7d7

View File

@ -94,19 +94,21 @@ bool get_path_and_clip_bounds(const GrDrawTarget* target,
return true; return true;
} }
////////////////////////////////////////////////////////////////////////////////
/** /**
* sw rasterizes path to A8 mask using the context's matrix and uploads to a * The GrSWMaskHelper helps generate clip masks using the software rendering
* scratch texture. * path.
*/ */
class GrSWMaskHelper : public GrNoncopyable {
public:
GrSWMaskHelper(GrContext* context)
: fContext(context) {
bool sw_draw_path_to_mask_texture(const SkPath& clientPath, }
const GrIRect& pathDevBounds,
GrPathFill fill, /**
GrContext* context, * Draw a single element of the clip stack into the accumulation bitmap
const GrPoint* translate, */
GrAutoScratchTexture* tex, void draw(const SkPath& clientPath, GrPathFill fill, bool antiAlias) {
bool antiAlias) {
SkPaint paint; SkPaint paint;
SkPath tmpPath; SkPath tmpPath;
const SkPath* pathToDraw = &clientPath; const SkPath* pathToDraw = &clientPath;
@ -125,49 +127,94 @@ bool sw_draw_path_to_mask_texture(const SkPath& clientPath,
paint.setAntiAlias(antiAlias); paint.setAntiAlias(antiAlias);
paint.setColor(SK_ColorWHITE); paint.setColor(SK_ColorWHITE);
GrMatrix matrix = context->getMatrix(); fDraw.drawPath(*pathToDraw, paint);
if (NULL != translate) {
matrix.postTranslate(translate->fX, translate->fY);
} }
matrix.postTranslate(-pathDevBounds.fLeft * SK_Scalar1, 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); -pathDevBounds.fTop * SK_Scalar1);
GrIRect bounds = GrIRect::MakeWH(pathDevBounds.width(), GrIRect bounds = GrIRect::MakeWH(pathDevBounds.width(),
pathDevBounds.height()); pathDevBounds.height());
SkBitmap bm; fBM.setConfig(SkBitmap::kA8_Config, bounds.fRight, bounds.fBottom);
bm.setConfig(SkBitmap::kA8_Config, bounds.fRight, bounds.fBottom); if (!fBM.allocPixels()) {
if (!bm.allocPixels()) {
return false; return false;
} }
sk_bzero(bm.getPixels(), bm.getSafeSize()); sk_bzero(fBM.getPixels(), fBM.getSafeSize());
SkDraw draw; sk_bzero(&fDraw, sizeof(fDraw));
sk_bzero(&draw, sizeof(draw)); fRasterClip.setRect(bounds);
SkRasterClip rc(bounds); fDraw.fRC = &fRasterClip;
draw.fRC = &rc; fDraw.fClip = &fRasterClip.bwRgn();
draw.fClip = &rc.bwRgn(); fDraw.fMatrix = &fMatrix;
draw.fMatrix = &matrix; fDraw.fBitmap = &fBM;
draw.fBitmap = &bm; return true;
draw.drawPath(*pathToDraw, paint); }
/**
* Move the result of the software mask generation back to the gpu
*/
bool toTexture(GrAutoScratchTexture* tex) {
const GrTextureDesc desc = { const GrTextureDesc desc = {
kNone_GrTextureFlags, kNone_GrTextureFlags,
bounds.fRight, fBM.width(),
bounds.fBottom, fBM.height(),
kAlpha_8_GrPixelConfig, kAlpha_8_GrPixelConfig,
0 // samples 0 // samples
}; };
tex->set(context, desc); tex->set(fContext, desc);
GrTexture* texture = tex->texture(); GrTexture* texture = tex->texture();
if (NULL == texture) { if (NULL == texture) {
return false; return false;
} }
SkAutoLockPixels alp(bm); SkAutoLockPixels alp(fBM);
texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
bm.getPixels(), bm.rowBytes()); 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,
GrContext* context,
const GrPoint* translate,
GrAutoScratchTexture* tex,
bool antiAlias) {
GrSWMaskHelper helper(context);
if (!helper.init(pathDevBounds, translate)) {
return false;
}
helper.draw(clientPath, fill, antiAlias);
if (!helper.toTexture(tex)) {
return false;
}
return true; return true;
} }