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:
parent
4debcac8c3
commit
6f31a3b7d7
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user