Minor refactoring/enhancement of GrSWMaskHelper to prepare for wider use
http://codereview.appspot.com/6188082/
git-svn-id: http://skia.googlecode.com/svn/trunk@3931 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index ae2c893..410223c 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -94,103 +94,135 @@
return true;
}
-/**
- * The GrSWMaskHelper helps generate clip masks using the software rendering
- * path.
+
+/*
+ * Convert a boolean operation into a transfer mode code
*/
-class GrSWMaskHelper : public GrNoncopyable {
-public:
- GrSWMaskHelper(GrContext* context)
- : fContext(context) {
+SkXfermode::Mode op_to_mode(SkRegion::Op op) {
+ static const SkXfermode::Mode modeMap[] = {
+ SkXfermode::kSrcOut_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) {
+ SkPaint paint;
+
+ SkXfermode* mode = SkXfermode::Create(op_to_mode(op));
+
+ paint.setXfermode(mode);
+ paint.setAntiAlias(antiAlias);
+ paint.setColor(SK_ColorWHITE);
+
+ 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) {
+
+ 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;
+ }
+ }
+ SkXfermode* mode = SkXfermode::Create(op_to_mode(op));
+
+ paint.setXfermode(mode);
+ paint.setAntiAlias(antiAlias);
+ paint.setColor(SK_ColorWHITE);
+
+ fDraw.drawPath(*pathToDraw, paint);
+
+ SkSafeUnref(mode);
+}
+
+bool GrSWMaskHelper::init(const GrIRect& pathDevBounds, const GrPoint* translate) {
+ fMatrix = fContext->getMatrix();
+ if (NULL != translate) {
+ fMatrix.postTranslate(translate->fX, translate->fY);
}
- /**
- * 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);
+ fMatrix.postTranslate(-pathDevBounds.fLeft * SK_Scalar1,
+ -pathDevBounds.fTop * SK_Scalar1);
+ GrIRect bounds = GrIRect::MakeWH(pathDevBounds.width(),
+ pathDevBounds.height());
- fDraw.drawPath(*pathToDraw, paint);
+ 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) {
+ 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;
}
- bool init(const GrIRect& pathDevBounds, const GrPoint* translate) {
- fMatrix = fContext->getMatrix();
- if (NULL != translate) {
- fMatrix.postTranslate(translate->fX, translate->fY);
- }
+ return true;
+}
- fMatrix.postTranslate(-pathDevBounds.fLeft * SK_Scalar1,
- -pathDevBounds.fTop * SK_Scalar1);
- GrIRect bounds = GrIRect::MakeWH(pathDevBounds.width(),
- pathDevBounds.height());
+/**
+ * Move the result of the software mask generation back to the gpu
+ */
+void GrSWMaskHelper::toTexture(GrTexture *texture) {
+ SkAutoLockPixels alp(fBM);
+ texture->writePixels(0, 0, fBM.width(), fBM.height(),
+ kAlpha_8_GrPixelConfig,
+ fBM.getPixels(), fBM.rowBytes());
+}
- 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;
-};
-
+namespace {
////////////////////////////////////////////////////////////////////////////////
/**
* sw rasterizes path to A8 mask using the context's matrix and uploads to a
@@ -209,12 +241,14 @@
return false;
}
- helper.draw(clientPath, fill, antiAlias);
+ helper.draw(clientPath, SkRegion::kReplace_Op, fill, antiAlias);
- if (!helper.toTexture(tex)) {
+ if (!helper.getTexture(tex)) {
return false;
}
+ helper.toTexture(tex->texture());
+
return true;
}