aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkDrawLooper.h57
-rw-r--r--include/effects/SkBlurDrawLooper.h18
-rw-r--r--include/effects/SkLayerDrawLooper.h19
-rw-r--r--src/core/SkCanvas.cpp20
-rw-r--r--src/core/SkDrawLooper.cpp17
-rw-r--r--src/core/SkSmallAllocator.h15
-rw-r--r--src/effects/SkBlurDrawLooper.cpp26
-rw-r--r--src/effects/SkLayerDrawLooper.cpp20
-rw-r--r--tests/LayerDrawLooperTest.cpp31
-rw-r--r--tests/QuickRejectTest.cpp33
10 files changed, 168 insertions, 88 deletions
diff --git a/include/core/SkDrawLooper.h b/include/core/SkDrawLooper.h
index 4609c1dcf9..65650d88e8 100644
--- a/include/core/SkDrawLooper.h
+++ b/include/core/SkDrawLooper.h
@@ -30,24 +30,49 @@ public:
SK_DECLARE_INST_COUNT(SkDrawLooper)
/**
- * Called right before something is being drawn. This will be followed by
- * calls to next() until next() returns false.
+ * Holds state during a draw. Users call next() until it returns false.
+ *
+ * Subclasses of SkDrawLooper should create a subclass of this object to
+ * hold state specific to their subclass.
*/
- virtual void init(SkCanvas*) = 0;
+ class SK_API Context : public SkNoncopyable {
+ public:
+ Context() {}
+ virtual ~Context() {}
+
+ /**
+ * Called in a loop on objects returned by SkDrawLooper::createContext().
+ * Each time true is returned, the object is drawn (possibly with a modified
+ * canvas and/or paint). When false is finally returned, drawing for the object
+ * stops.
+ *
+ * On each call, the paint will be in its original state, but the
+ * canvas will be as it was following the previous call to next() or
+ * createContext().
+ *
+ * The implementation must ensure that, when next() finally returns
+ * false, the canvas has been restored to the state it was
+ * initially, before createContext() was first called.
+ */
+ virtual bool next(SkCanvas* canvas, SkPaint* paint) = 0;
+ };
/**
- * Called in a loop (after init()). Each time true is returned, the object
- * is drawn (possibly with a modified canvas and/or paint). When false is
- * finally returned, drawing for the object stops.
- *
- * On each call, the paint will be in its original state, but the canvas
- * will be as it was following the previous call to next() or init().
- *
- * The implementation must ensure that, when next() finally returns false,
- * that the canvas has been restored to the state it was initially, before
- * init() was first called.
+ * Called right before something is being drawn. Returns a Context
+ * whose next() method should be called until it returns false.
+ * The caller has to ensure that the storage pointer provides enough
+ * memory for the Context. The required size can be queried by calling
+ * contextSize(). It is also the caller's responsibility to destroy the
+ * object after use.
*/
- virtual bool next(SkCanvas*, SkPaint* paint) = 0;
+ virtual Context* createContext(SkCanvas*, void* storage) const = 0;
+
+ /**
+ * Returns the number of bytes needed to store subclasses of Context (belonging to the
+ * corresponding SkDrawLooper subclass).
+ */
+ virtual size_t contextSize() const = 0;
+
/**
* The fast bounds functions are used to enable the paint to be culled early
@@ -59,9 +84,9 @@ public:
* storage rect, where the storage rect is with the union of the src rect
* and the looper's bounding rect.
*/
- virtual bool canComputeFastBounds(const SkPaint& paint);
+ virtual bool canComputeFastBounds(const SkPaint& paint) const;
virtual void computeFastBounds(const SkPaint& paint,
- const SkRect& src, SkRect* dst);
+ const SkRect& src, SkRect* dst) const;
SkDEVCODE(virtual void toString(SkString* str) const = 0;)
SK_DEFINE_FLATTENABLE_TYPE(SkDrawLooper)
diff --git a/include/effects/SkBlurDrawLooper.h b/include/effects/SkBlurDrawLooper.h
index 46b154debc..9a230e59ff 100644
--- a/include/effects/SkBlurDrawLooper.h
+++ b/include/effects/SkBlurDrawLooper.h
@@ -43,9 +43,9 @@ public:
uint32_t flags = kNone_BlurFlag);
virtual ~SkBlurDrawLooper();
- // overrides from SkDrawLooper
- virtual void init(SkCanvas*);
- virtual bool next(SkCanvas*, SkPaint* paint);
+ virtual SkDrawLooper::Context* createContext(SkCanvas*, void* storage) const SK_OVERRIDE;
+
+ virtual size_t contextSize() const SK_OVERRIDE { return sizeof(BlurDrawLooperContext); }
SK_DEVELOPER_TO_STRING()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurDrawLooper)
@@ -66,7 +66,17 @@ private:
kAfterEdge,
kDone
};
- State fState;
+
+ class BlurDrawLooperContext : public SkDrawLooper::Context {
+ public:
+ explicit BlurDrawLooperContext(const SkBlurDrawLooper* looper);
+
+ virtual bool next(SkCanvas* canvas, SkPaint* paint) SK_OVERRIDE;
+
+ private:
+ const SkBlurDrawLooper* fLooper;
+ State fState;
+ };
void init(SkScalar sigma, SkScalar dx, SkScalar dy, SkColor color, uint32_t flags);
diff --git a/include/effects/SkLayerDrawLooper.h b/include/effects/SkLayerDrawLooper.h
index 241b3b2494..7a13b7a7b9 100644
--- a/include/effects/SkLayerDrawLooper.h
+++ b/include/effects/SkLayerDrawLooper.h
@@ -94,9 +94,9 @@ public:
/// Similar to addLayer, but adds a layer to the top.
SkPaint* addLayerOnTop(const LayerInfo&);
- // overrides from SkDrawLooper
- virtual void init(SkCanvas*);
- virtual bool next(SkCanvas*, SkPaint* paint);
+ virtual SkDrawLooper::Context* createContext(SkCanvas*, void* storage) const SK_OVERRIDE;
+
+ virtual size_t contextSize() const SK_OVERRIDE { return sizeof(LayerDrawLooperContext); }
SK_DEVELOPER_TO_STRING()
@@ -118,9 +118,18 @@ private:
int fCount;
// state-machine during the init/next cycle
- Rec* fCurrRec;
+ class LayerDrawLooperContext : public SkDrawLooper::Context {
+ public:
+ explicit LayerDrawLooperContext(const SkLayerDrawLooper* looper);
+
+ protected:
+ virtual bool next(SkCanvas*, SkPaint* paint) SK_OVERRIDE;
- static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&);
+ private:
+ Rec* fCurrRec;
+
+ static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&);
+ };
class MyRegistrar : public SkFlattenable::Registrar {
public:
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index bd75f7dbde..3b7cc5bea0 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -19,6 +19,7 @@
#include "SkPicture.h"
#include "SkRasterClip.h"
#include "SkRRect.h"
+#include "SkSmallAllocator.h"
#include "SkSurface_Base.h"
#include "SkTemplates.h"
#include "SkTextFormatParams.h"
@@ -337,7 +338,6 @@ public:
bool skipLayerForImageFilter = false,
const SkRect* bounds = NULL) : fOrigPaint(paint) {
fCanvas = canvas;
- fLooper = paint.getLooper();
fFilter = canvas->getDrawFilter();
fPaint = NULL;
fSaveCount = canvas->getSaveCount();
@@ -354,10 +354,13 @@ public:
fDoClearImageFilter = true;
}
- if (fLooper) {
- fLooper->init(canvas);
+ if (SkDrawLooper* looper = paint.getLooper()) {
+ void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Context>(
+ looper->contextSize());
+ fLooperContext = looper->createContext(canvas, buffer);
fIsSimple = false;
} else {
+ fLooperContext = NULL;
// can we be marked as simple?
fIsSimple = !fFilter && !fDoClearImageFilter;
}
@@ -391,13 +394,14 @@ private:
SkLazyPaint fLazyPaint;
SkCanvas* fCanvas;
const SkPaint& fOrigPaint;
- SkDrawLooper* fLooper;
SkDrawFilter* fFilter;
const SkPaint* fPaint;
int fSaveCount;
bool fDoClearImageFilter;
bool fDone;
bool fIsSimple;
+ SkDrawLooper::Context* fLooperContext;
+ SkSmallAllocator<1, 32> fLooperContextAllocator;
bool doNext(SkDrawFilter::Type drawType);
};
@@ -405,7 +409,7 @@ private:
bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) {
fPaint = NULL;
SkASSERT(!fIsSimple);
- SkASSERT(fLooper || fFilter || fDoClearImageFilter);
+ SkASSERT(fLooperContext || fFilter || fDoClearImageFilter);
SkPaint* paint = fLazyPaint.set(fOrigPaint);
@@ -413,7 +417,7 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) {
paint->setImageFilter(NULL);
}
- if (fLooper && !fLooper->next(fCanvas, paint)) {
+ if (fLooperContext && !fLooperContext->next(fCanvas, paint)) {
fDone = true;
return false;
}
@@ -422,7 +426,7 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) {
fDone = true;
return false;
}
- if (NULL == fLooper) {
+ if (NULL == fLooperContext) {
// no looper means we only draw once
fDone = true;
}
@@ -430,7 +434,7 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) {
fPaint = paint;
// if we only came in here for the imagefilter, mark us as done
- if (!fLooper && !fFilter) {
+ if (!fLooperContext && !fFilter) {
fDone = true;
}
diff --git a/src/core/SkDrawLooper.cpp b/src/core/SkDrawLooper.cpp
index bac2d969c0..c620cd08da 100644
--- a/src/core/SkDrawLooper.cpp
+++ b/src/core/SkDrawLooper.cpp
@@ -10,14 +10,17 @@
#include "SkMatrix.h"
#include "SkPaint.h"
#include "SkRect.h"
+#include "SkSmallAllocator.h"
-bool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) {
+bool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) const {
SkCanvas canvas;
+ SkSmallAllocator<1, 32> allocator;
+ void* buffer = allocator.reserveT<SkDrawLooper::Context>(this->contextSize());
- this->init(&canvas);
+ SkDrawLooper::Context* context = this->createContext(&canvas, buffer);
for (;;) {
SkPaint p(paint);
- if (this->next(&canvas, &p)) {
+ if (context->next(&canvas, &p)) {
p.setLooper(NULL);
if (!p.canComputeFastBounds()) {
return false;
@@ -30,14 +33,16 @@ bool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) {
}
void SkDrawLooper::computeFastBounds(const SkPaint& paint, const SkRect& src,
- SkRect* dst) {
+ SkRect* dst) const {
SkCanvas canvas;
+ SkSmallAllocator<1, 32> allocator;
+ void* buffer = allocator.reserveT<SkDrawLooper::Context>(this->contextSize());
*dst = src; // catch case where there are no loops
- this->init(&canvas);
+ SkDrawLooper::Context* context = this->createContext(&canvas, buffer);
for (bool firstTime = true;; firstTime = false) {
SkPaint p(paint);
- if (this->next(&canvas, &p)) {
+ if (context->next(&canvas, &p)) {
SkRect r(src);
p.setLooper(NULL);
diff --git a/src/core/SkSmallAllocator.h b/src/core/SkSmallAllocator.h
index d5ebf3b7d4..2eddb510cd 100644
--- a/src/core/SkSmallAllocator.h
+++ b/src/core/SkSmallAllocator.h
@@ -96,20 +96,21 @@ public:
return static_cast<T*>(buf);
}
-private:
/*
- * Helper function to provide space for one T. The space will be in
- * fStorage if there is room, or on the heap otherwise. Either way, this
- * class will call ~T() in its destructor and free the heap allocation if
- * necessary.
+ * Reserve a specified amount of space (must be enough space for one T).
+ * The space will be in fStorage if there is room, or on the heap otherwise.
+ * Either way, this class will call ~T() in its destructor and free the heap
+ * allocation if necessary.
+ * Unlike createT(), this method will not call the constructor of T.
*/
- template<typename T> void* reserveT() {
+ template<typename T> void* reserveT(size_t storageRequired = sizeof(T)) {
SkASSERT(fNumObjects < kMaxObjects);
+ SkASSERT(storageRequired >= sizeof(T));
if (kMaxObjects == fNumObjects) {
return NULL;
}
const size_t storageRemaining = SkAlign4(kTotalBytes) - fStorageUsed;
- const size_t storageRequired = SkAlign4(sizeof(T));
+ storageRequired = SkAlign4(storageRequired);
Rec* rec = &fRecs[fNumObjects];
if (storageRequired > storageRemaining) {
// Allocate on the heap. Ideally we want to avoid this situation,
diff --git a/src/effects/SkBlurDrawLooper.cpp b/src/effects/SkBlurDrawLooper.cpp
index 3a5c697371..0bbc184049 100644
--- a/src/effects/SkBlurDrawLooper.cpp
+++ b/src/effects/SkBlurDrawLooper.cpp
@@ -33,7 +33,6 @@ void SkBlurDrawLooper::init(SkScalar sigma, SkScalar dx, SkScalar dy,
fDy = dy;
fBlurColor = color;
fBlurFlags = flags;
- fState = kDone;
SkASSERT(flags <= kAll_BlurFlag);
if (sigma > 0) {
@@ -90,11 +89,16 @@ void SkBlurDrawLooper::flatten(SkWriteBuffer& buffer) const {
buffer.writeUInt(fBlurFlags);
}
-void SkBlurDrawLooper::init(SkCanvas*) {
- fState = kBeforeEdge;
+SkDrawLooper::Context* SkBlurDrawLooper::createContext(SkCanvas*, void* storage) const {
+ return SkNEW_PLACEMENT_ARGS(storage, BlurDrawLooperContext, (this));
}
-bool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
+SkBlurDrawLooper::BlurDrawLooperContext::BlurDrawLooperContext(
+ const SkBlurDrawLooper* looper)
+ : fLooper(looper), fState(SkBlurDrawLooper::kBeforeEdge) {}
+
+bool SkBlurDrawLooper::BlurDrawLooperContext::next(SkCanvas* canvas,
+ SkPaint* paint) {
switch (fState) {
case kBeforeEdge:
// we do nothing if a maskfilter is already installed
@@ -104,23 +108,23 @@ bool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
}
#ifdef SK_BUILD_FOR_ANDROID
SkColor blurColor;
- blurColor = fBlurColor;
+ blurColor = fLooper->fBlurColor;
if (SkColorGetA(blurColor) == 255) {
blurColor = SkColorSetA(blurColor, paint->getAlpha());
}
paint->setColor(blurColor);
#else
- paint->setColor(fBlurColor);
+ paint->setColor(fLooper->fBlurColor);
#endif
- paint->setMaskFilter(fBlur);
- paint->setColorFilter(fColorFilter);
+ paint->setMaskFilter(fLooper->fBlur);
+ paint->setColorFilter(fLooper->fColorFilter);
canvas->save(SkCanvas::kMatrix_SaveFlag);
- if (fBlurFlags & kIgnoreTransform_BlurFlag) {
+ if (fLooper->fBlurFlags & kIgnoreTransform_BlurFlag) {
SkMatrix transform(canvas->getTotalMatrix());
- transform.postTranslate(fDx, fDy);
+ transform.postTranslate(fLooper->fDx, fLooper->fDy);
canvas->setMatrix(transform);
} else {
- canvas->translate(fDx, fDy);
+ canvas->translate(fLooper->fDx, fLooper->fDy);
}
fState = kAfterEdge;
return true;
diff --git a/src/effects/SkLayerDrawLooper.cpp b/src/effects/SkLayerDrawLooper.cpp
index cfe673db92..6d31c23a06 100644
--- a/src/effects/SkLayerDrawLooper.cpp
+++ b/src/effects/SkLayerDrawLooper.cpp
@@ -24,8 +24,7 @@ SkLayerDrawLooper::LayerInfo::LayerInfo() {
SkLayerDrawLooper::SkLayerDrawLooper()
: fRecs(NULL),
fTopRec(NULL),
- fCount(0),
- fCurrRec(NULL) {
+ fCount(0) {
}
SkLayerDrawLooper::~SkLayerDrawLooper() {
@@ -75,9 +74,9 @@ SkPaint* SkLayerDrawLooper::addLayerOnTop(const LayerInfo& info) {
return &rec->fPaint;
}
-void SkLayerDrawLooper::init(SkCanvas* canvas) {
- fCurrRec = fRecs;
+SkLayerDrawLooper::Context* SkLayerDrawLooper::createContext(SkCanvas* canvas, void* storage) const {
canvas->save(SkCanvas::kMatrix_SaveFlag);
+ return SkNEW_PLACEMENT_ARGS(storage, LayerDrawLooperContext, (this));
}
static SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) {
@@ -98,8 +97,8 @@ static SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) {
// Even with kEntirePaint_Bits, we always ensure that the master paint's
// text-encoding is respected, since that controls how we interpret the
// text/length parameters of a draw[Pos]Text call.
-void SkLayerDrawLooper::ApplyInfo(SkPaint* dst, const SkPaint& src,
- const LayerInfo& info) {
+void SkLayerDrawLooper::LayerDrawLooperContext::ApplyInfo(
+ SkPaint* dst, const SkPaint& src, const LayerInfo& info) {
dst->setColor(xferColor(src.getColor(), dst->getColor(), info.fColorMode));
@@ -167,7 +166,11 @@ static void postTranslate(SkCanvas* canvas, SkScalar dx, SkScalar dy) {
canvas->setMatrix(m);
}
-bool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
+SkLayerDrawLooper::LayerDrawLooperContext::LayerDrawLooperContext(
+ const SkLayerDrawLooper* looper) : fCurrRec(looper->fRecs) {}
+
+bool SkLayerDrawLooper::LayerDrawLooperContext::next(SkCanvas* canvas,
+ SkPaint* paint) {
canvas->restore();
if (NULL == fCurrRec) {
return false;
@@ -180,7 +183,8 @@ bool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
postTranslate(canvas, fCurrRec->fInfo.fOffset.fX,
fCurrRec->fInfo.fOffset.fY);
} else {
- canvas->translate(fCurrRec->fInfo.fOffset.fX, fCurrRec->fInfo.fOffset.fY);
+ canvas->translate(fCurrRec->fInfo.fOffset.fX,
+ fCurrRec->fInfo.fOffset.fY);
}
fCurrRec = fCurrRec->fNext;
diff --git a/tests/LayerDrawLooperTest.cpp b/tests/LayerDrawLooperTest.cpp
index 68dd5e06e7..1facb23b51 100644
--- a/tests/LayerDrawLooperTest.cpp
+++ b/tests/LayerDrawLooperTest.cpp
@@ -15,6 +15,7 @@
#include "SkRect.h"
#include "SkRefCnt.h"
#include "SkScalar.h"
+#include "SkSmallAllocator.h"
#include "SkXfermode.h"
#include "Test.h"
@@ -57,10 +58,12 @@ static void test_frontToBack(skiatest::Reporter* reporter) {
SkCanvas canvas(&device);
SkPaint paint;
SkAutoTUnref<SkLayerDrawLooper> looper(looperBuilder.detachLooper());
- looper->init(&canvas);
+ SkSmallAllocator<1, 32> allocator;
+ void* buffer = allocator.reserveT<SkDrawLooper::Context>(looper->contextSize());
+ SkDrawLooper::Context* context = looper->createContext(&canvas, buffer);
// The back layer should come first.
- REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
+ REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
@@ -68,14 +71,14 @@ static void test_frontToBack(skiatest::Reporter* reporter) {
paint.reset();
// Then the front layer.
- REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
+ REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
// Only two layers were added, so that should be the end.
- REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
+ REPORTER_ASSERT(reporter, !context->next(&canvas, &paint));
}
static void test_backToFront(skiatest::Reporter* reporter) {
@@ -95,10 +98,12 @@ static void test_backToFront(skiatest::Reporter* reporter) {
SkCanvas canvas(&device);
SkPaint paint;
SkAutoTUnref<SkLayerDrawLooper> looper(looperBuilder.detachLooper());
- looper->init(&canvas);
+ SkSmallAllocator<1, 32> allocator;
+ void* buffer = allocator.reserveT<SkDrawLooper::Context>(looper->contextSize());
+ SkDrawLooper::Context* context = looper->createContext(&canvas, buffer);
// The back layer should come first.
- REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
+ REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
@@ -106,14 +111,14 @@ static void test_backToFront(skiatest::Reporter* reporter) {
paint.reset();
// Then the front layer.
- REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
+ REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
// Only two layers were added, so that should be the end.
- REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
+ REPORTER_ASSERT(reporter, !context->next(&canvas, &paint));
}
static void test_mixed(skiatest::Reporter* reporter) {
@@ -133,10 +138,12 @@ static void test_mixed(skiatest::Reporter* reporter) {
SkCanvas canvas(&device);
SkPaint paint;
SkAutoTUnref<SkLayerDrawLooper> looper(looperBuilder.detachLooper());
- looper->init(&canvas);
+ SkSmallAllocator<1, 32> allocator;
+ void* buffer = allocator.reserveT<SkDrawLooper::Context>(looper->contextSize());
+ SkDrawLooper::Context* context = looper->createContext(&canvas, buffer);
// The back layer should come first.
- REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
+ REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
@@ -144,14 +151,14 @@ static void test_mixed(skiatest::Reporter* reporter) {
paint.reset();
// Then the front layer.
- REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
+ REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
// Only two layers were added, so that should be the end.
- REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
+ REPORTER_ASSERT(reporter, !context->next(&canvas, &paint));
}
DEF_TEST(LayerDrawLooper, reporter) {
diff --git a/tests/QuickRejectTest.cpp b/tests/QuickRejectTest.cpp
index 2d367389bb..ef145525e9 100644
--- a/tests/QuickRejectTest.cpp
+++ b/tests/QuickRejectTest.cpp
@@ -7,6 +7,7 @@
#include "SkCanvas.h"
#include "SkDrawLooper.h"
+#include "SkTypes.h"
#include "Test.h"
/*
@@ -14,20 +15,12 @@
*/
class TestLooper : public SkDrawLooper {
public:
- bool fOnce;
- virtual void init(SkCanvas*) SK_OVERRIDE {
- fOnce = true;
+ virtual SkDrawLooper::Context* createContext(SkCanvas*, void* storage) const SK_OVERRIDE {
+ return SkNEW_PLACEMENT(storage, TestDrawLooperContext);
}
- virtual bool next(SkCanvas* canvas, SkPaint*) SK_OVERRIDE {
- if (fOnce) {
- fOnce = false;
- canvas->translate(SkIntToScalar(10), 0);
- return true;
- }
- return false;
- }
+ virtual size_t contextSize() const SK_OVERRIDE { return sizeof(TestDrawLooperContext); }
#ifdef SK_DEVELOPER
virtual void toString(SkString* str) const SK_OVERRIDE {
@@ -35,6 +28,24 @@ public:
}
#endif
+private:
+ class TestDrawLooperContext : public SkDrawLooper::Context {
+ public:
+ TestDrawLooperContext() : fOnce(true) {}
+ virtual ~TestDrawLooperContext() {}
+
+ virtual bool next(SkCanvas* canvas, SkPaint*) SK_OVERRIDE {
+ if (fOnce) {
+ fOnce = false;
+ canvas->translate(SkIntToScalar(10), 0);
+ return true;
+ }
+ return false;
+ }
+ private:
+ bool fOnce;
+ };
+
SK_DECLARE_UNFLATTENABLE_OBJECT()
};