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