Simplify drawloopers and drawfilters. This allows the canvas to keep its
promise that const SkPaint& stay const (so we don't have bugs if a const paint
is referenced from two threads in pictures)
git-svn-id: http://skia.googlecode.com/svn/trunk@1074 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index a0e7e6e..1926d89 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -280,65 +280,65 @@
class AutoDrawLooper {
public:
- AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, SkDrawFilter::Type t)
- : fCanvas(canvas), fPaint((SkPaint*)&paint), fType(t) {
- if ((fLooper = paint.getLooper()) != NULL) {
- fLooper->init(canvas, (SkPaint*)&paint);
- } else {
- fOnce = true;
- }
+ AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint) : fOrigPaint(paint) {
+ fCanvas = canvas;
+ fLooper = paint.getLooper();
fFilter = canvas->getDrawFilter();
- fNeedFilterRestore = false;
- }
+ fPaint = NULL;
+ fSaveCount = canvas->getSaveCount();
+ fDone = false;
+ if (fLooper) {
+ fLooper->init(canvas);
+ }
+ }
+
~AutoDrawLooper() {
- if (fNeedFilterRestore) {
- SkASSERT(fFilter);
- fFilter->restore(fCanvas, fPaint, fType);
- }
- if (NULL != fLooper) {
- fLooper->restore();
- }
+ SkASSERT(fCanvas->getSaveCount() == fSaveCount);
}
-
- bool next() {
- SkDrawFilter* filter = fFilter;
-
- // if we drew earlier with a filter, then we need to restore first
- if (fNeedFilterRestore) {
- SkASSERT(filter);
- filter->restore(fCanvas, fPaint, fType);
- fNeedFilterRestore = false;
- }
-
- bool result;
-
- if (NULL != fLooper) {
- result = fLooper->next();
- } else {
- result = fOnce;
- fOnce = false;
- }
-
- // if we're gonna draw, give the filter a chance to do its work
- if (result && NULL != filter) {
- fNeedFilterRestore = result = filter->filter(fCanvas, fPaint,
- fType);
- }
- return result;
+
+ const SkPaint& paint() const {
+ SkASSERT(fPaint);
+ return *fPaint;
}
-
+
+ bool next(SkDrawFilter::Type drawType);
+
private:
- SkDrawLooper* fLooper;
- SkDrawFilter* fFilter;
- SkCanvas* fCanvas;
- SkPaint* fPaint;
- SkDrawFilter::Type fType;
- bool fOnce;
- bool fNeedFilterRestore;
-
+ SkTLazy<SkPaint> fLazyPaint;
+ SkCanvas* fCanvas;
+ const SkPaint& fOrigPaint;
+ SkDrawLooper* fLooper;
+ SkDrawFilter* fFilter;
+ const SkPaint* fPaint;
+ int fSaveCount;
+ bool fDone;
};
+bool AutoDrawLooper::next(SkDrawFilter::Type drawType) {
+ if (fDone) {
+ fPaint = NULL;
+ return false;
+ }
+ if (!fLooper && !fFilter) {
+ fDone = true;
+ fPaint = &fOrigPaint;
+ return true;
+ }
+
+ SkPaint* paint = fLazyPaint.set(fOrigPaint);
+ if (fLooper && !fLooper->next(fCanvas, paint)) {
+ fDone = true;
+ fPaint = NULL;
+ return false;
+ }
+ if (fFilter) {
+ fFilter->filter(paint, drawType);
+ }
+ fPaint = paint;
+ return true;
+}
+
/* Stack helper for managing a SkBounder. In the destructor, if we were
given a bounder, we call its commit() method, signifying that we are
done accumulating bounds for that draw.
@@ -380,14 +380,14 @@
////////// macros to place around the internal draw calls //////////////////
-#define ITER_BEGIN(paint, type) \
+#define LOOPER_BEGIN(paint, type) \
/* AutoValidator validator(fMCRec->fTopLayer->fDevice); */ \
- AutoDrawLooper looper(this, paint, type); \
- while (looper.next()) { \
+ AutoDrawLooper looper(this, paint); \
+ while (looper.next(type)) { \
SkAutoBounderCommit ac(fBounder); \
SkDrawIter iter(this);
-#define ITER_END }
+#define LOOPER_END }
////////////////////////////////////////////////////////////////////////////
@@ -853,12 +853,12 @@
paint = &tmp;
}
- ITER_BEGIN(*paint, SkDrawFilter::kBitmap_Type)
+ LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type)
while (iter.next()) {
iter.fDevice->drawDevice(iter, device, x - iter.getX(), y - iter.getY(),
- *paint);
+ looper.paint());
}
- ITER_END
+ LOOPER_END
}
/////////////////////////////////////////////////////////////////////////////
@@ -1190,13 +1190,13 @@
//////////////////////////////////////////////////////////////////////////////
void SkCanvas::drawPaint(const SkPaint& paint) {
- ITER_BEGIN(paint, SkDrawFilter::kPaint_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type)
while (iter.next()) {
- iter.fDevice->drawPaint(iter, paint);
+ iter.fDevice->drawPaint(iter, looper.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
@@ -1207,13 +1207,13 @@
SkASSERT(pts != NULL);
- ITER_BEGIN(paint, SkDrawFilter::kPoint_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type)
while (iter.next()) {
- iter.fDevice->drawPoints(iter, mode, count, pts, paint);
+ iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) {
@@ -1225,13 +1225,13 @@
}
}
- ITER_BEGIN(paint, SkDrawFilter::kRect_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type)
while (iter.next()) {
- iter.fDevice->drawRect(iter, r, paint);
+ iter.fDevice->drawRect(iter, r, looper.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
@@ -1244,13 +1244,13 @@
}
}
- ITER_BEGIN(paint, SkDrawFilter::kPath_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type)
while (iter.next()) {
- iter.fDevice->drawPath(iter, path, paint);
+ iter.fDevice->drawPath(iter, path, looper.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
@@ -1328,13 +1328,13 @@
const SkMatrix& matrix, const SkPaint& paint) {
SkDEBUGCODE(bitmap.validate();)
- ITER_BEGIN(paint, SkDrawFilter::kBitmap_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kBitmap_Type)
while (iter.next()) {
- iter.fDevice->drawBitmap(iter, bitmap, srcRect, matrix, paint);
+ iter.fDevice->drawBitmap(iter, bitmap, srcRect, matrix, looper.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y,
@@ -1350,13 +1350,13 @@
paint = &tmp;
}
- ITER_BEGIN(*paint, SkDrawFilter::kBitmap_Type)
+ LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type)
while (iter.next()) {
iter.fDevice->drawSprite(iter, bitmap, x - iter.getX(), y - iter.getY(),
- *paint);
+ looper.paint());
}
- ITER_END
+ LOOPER_END
}
class SkDeviceFilteredPaint {
@@ -1382,54 +1382,54 @@
void SkCanvas::drawText(const void* text, size_t byteLength,
SkScalar x, SkScalar y, const SkPaint& paint) {
- ITER_BEGIN(paint, SkDrawFilter::kText_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
while (iter.next()) {
- SkDeviceFilteredPaint dfp(iter.fDevice, paint);
+ SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawPosText(const void* text, size_t byteLength,
const SkPoint pos[], const SkPaint& paint) {
- ITER_BEGIN(paint, SkDrawFilter::kText_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
while (iter.next()) {
- SkDeviceFilteredPaint dfp(iter.fDevice, paint);
+ SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 0, 2,
dfp.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawPosTextH(const void* text, size_t byteLength,
const SkScalar xpos[], SkScalar constY,
const SkPaint& paint) {
- ITER_BEGIN(paint, SkDrawFilter::kText_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
while (iter.next()) {
- SkDeviceFilteredPaint dfp(iter.fDevice, paint);
+ SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
iter.fDevice->drawPosText(iter, text, byteLength, xpos, constY, 1,
dfp.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawTextOnPath(const void* text, size_t byteLength,
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint) {
- ITER_BEGIN(paint, SkDrawFilter::kText_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
while (iter.next()) {
iter.fDevice->drawTextOnPath(iter, text, byteLength, path,
- matrix, paint);
+ matrix, looper.paint());
}
- ITER_END
+ LOOPER_END
}
#ifdef ANDROID
@@ -1437,14 +1437,14 @@
const SkPoint pos[], const SkPaint& paint,
const SkPath& path, const SkMatrix* matrix) {
- ITER_BEGIN(paint, SkDrawFilter::kText_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
while (iter.next()) {
iter.fDevice->drawPosTextOnPath(iter, text, byteLength, pos,
- paint, path, matrix);
+ looper.paint(), path, matrix);
}
- ITER_END
+ LOOPER_END
}
#endif
@@ -1453,14 +1453,15 @@
const SkColor colors[], SkXfermode* xmode,
const uint16_t indices[], int indexCount,
const SkPaint& paint) {
- ITER_BEGIN(paint, SkDrawFilter::kPath_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type)
while (iter.next()) {
iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs,
- colors, xmode, indices, indexCount, paint);
+ colors, xmode, indices, indexCount,
+ looper.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawData(const void* data, size_t length) {