Refactor SkRecord opts, converting playback optimizations where possible.
This adds back two optimizations from SkPicture: drawPosText strength reduction to drawPosTextH, and pointless save-foo-restore blocks are noop'd away.
The small-T optimization in SkRecord gets in the way of implementing replace(), so I removed it.
Just to keep the API focused, I removed the methods on SkRecord that iterate over i for you; it's just as efficient to do it yourself, and all of the interesting code does its own custom iteration.
BUG=skia:2378
R=fmalita@chromium.org, mtklein@google.com
Author: mtklein@chromium.org
Review URL: https://codereview.chromium.org/245853002
git-svn-id: http://skia.googlecode.com/svn/trunk@14300 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/record/SkRecords.h b/src/record/SkRecords.h
index 1080656..7a89740 100644
--- a/src/record/SkRecords.h
+++ b/src/record/SkRecords.h
@@ -19,36 +19,39 @@
//
// We leave this SK_RECORD_TYPES macro defined for use by code that wants to operate on SkRecords
// types polymorphically. (See SkRecord::Record::{visit,mutate} for an example.)
-#define SK_RECORD_TYPES(M) \
- M(Restore) \
- M(Save) \
- M(SaveLayer) \
- M(Concat) \
- M(SetMatrix) \
- M(ClipPath) \
- M(ClipRRect) \
- M(ClipRect) \
- M(ClipRegion) \
- M(Clear) \
- M(DrawBitmap) \
- M(DrawBitmapMatrix) \
- M(DrawBitmapNine) \
- M(DrawBitmapRectToRect) \
- M(DrawDRRect) \
- M(DrawOval) \
- M(DrawPaint) \
- M(DrawPath) \
- M(DrawPoints) \
- M(DrawPosText) \
- M(DrawPosTextH) \
- M(DrawRRect) \
- M(DrawRect) \
- M(DrawSprite) \
- M(DrawText) \
- M(DrawTextOnPath) \
- M(DrawVertices) \
- M(PushCull) \
- M(PopCull)
+#define SK_RECORD_TYPES(M) \
+ M(NoOp) \
+ M(Restore) \
+ M(Save) \
+ M(SaveLayer) \
+ M(Concat) \
+ M(SetMatrix) \
+ M(ClipPath) \
+ M(ClipRRect) \
+ M(ClipRect) \
+ M(ClipRegion) \
+ M(Clear) \
+ M(DrawBitmap) \
+ M(DrawBitmapMatrix) \
+ M(DrawBitmapNine) \
+ M(DrawBitmapRectToRect) \
+ M(DrawDRRect) \
+ M(DrawOval) \
+ M(DrawPaint) \
+ M(DrawPath) \
+ M(DrawPoints) \
+ M(DrawPosText) \
+ M(DrawPosTextH) \
+ M(DrawRRect) \
+ M(DrawRect) \
+ M(DrawSprite) \
+ M(DrawText) \
+ M(DrawTextOnPath) \
+ M(DrawVertices) \
+ M(PushCull) \
+ M(PopCull) \
+ M(PairedPushCull) /*From SkRecordAnnotateCullingPairs*/ \
+ M(BoundedDrawPosTextH) /*From SkRecordBoundDrawPosTextH*/
// Defines SkRecords::Type, an enum of all record types.
#define ENUM(T) T##_Type,
@@ -107,6 +110,12 @@
A a; B b; C c; D d; E e; \
};
+#define ACT_AS_PTR(ptr) \
+ operator T*() { return ptr; } \
+ operator const T*() const { return ptr; } \
+ T* operator->() { return ptr; } \
+ const T* operator->() const { return ptr; }
+
// An Optional doesn't own the pointer's memory, but may need to destroy non-POD data.
template <typename T>
class Optional : SkNoncopyable {
@@ -114,8 +123,19 @@
Optional(T* ptr) : fPtr(ptr) {}
~Optional() { if (fPtr) fPtr->~T(); }
- operator T*() { return fPtr; }
- operator const T*() const { return fPtr; }
+ ACT_AS_PTR(fPtr);
+private:
+ T* fPtr;
+};
+
+// Like Optional, but ptr must not be NULL.
+template <typename T>
+class Adopted : SkNoncopyable {
+public:
+ Adopted(T* ptr) : fPtr(ptr) { SkASSERT(fPtr); }
+ ~Adopted() { fPtr->~T(); }
+
+ ACT_AS_PTR(fPtr);
private:
T* fPtr;
};
@@ -126,8 +146,7 @@
public:
PODArray(T* ptr) : fPtr(ptr) {}
- operator T*() { return fPtr; }
- operator const T*() const { return fPtr; }
+ ACT_AS_PTR(fPtr);
private:
T* fPtr;
};
@@ -151,15 +170,13 @@
SkBitmap fBitmap;
};
-// None of these records manages the lifetimes of pointers, except for DrawVertices handling its
-// Xfermode specially.
+RECORD0(NoOp);
RECORD0(Restore);
RECORD1(Save, SkCanvas::SaveFlags, flags);
RECORD3(SaveLayer, Optional<SkRect>, bounds, Optional<SkPaint>, paint, SkCanvas::SaveFlags, flags);
-static const unsigned kUnsetPopOffset = 0;
-RECORD2(PushCull, SkRect, rect, unsigned, popOffset);
+RECORD1(PushCull, SkRect, rect);
RECORD0(PopCull);
RECORD1(Concat, SkMatrix, matrix);
@@ -247,6 +264,10 @@
SkPaint paint;
};
+// Records added by optimizations.
+RECORD2(PairedPushCull, Adopted<PushCull>, base, unsigned, skip);
+RECORD3(BoundedDrawPosTextH, Adopted<DrawPosTextH>, base, SkScalar, minY, SkScalar, maxY);
+
#undef RECORD0
#undef RECORD1
#undef RECORD2