Turn on all pixel-perfect SkRecord optimizations.

BUG=skia:
R=robertphillips@google.com, mtklein@google.com

Author: mtklein@chromium.org

Review URL: https://codereview.chromium.org/550083006
diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp
index 9cfa6a0..f595f74 100644
--- a/src/core/SkPicture.cpp
+++ b/src/core/SkPicture.cpp
@@ -40,6 +40,7 @@
 
 #include "SkRecord.h"
 #include "SkRecordDraw.h"
+#include "SkRecordOpts.h"
 #include "SkRecorder.h"
 
 template <typename T> int SafeCount(const T* obj) {
@@ -271,7 +272,7 @@
 static SkPicture* backport(const SkRecord& src, const SkRect& cullRect) {
     SkPictureRecorder recorder;
     SkRecordDraw(src,
-                 recorder.DEPRECATED_beginRecording(cullRect.width(), cullRect.height()), 
+                 recorder.DEPRECATED_beginRecording(cullRect.width(), cullRect.height()),
                  NULL/*bbh*/, NULL/*callback*/);
     return recorder.endRecording();
 }
@@ -460,7 +461,7 @@
     SkAutoTDelete<SkRecord> record(SkNEW(SkRecord));
     SkRecorder canvas(record.get(), src.cullRect().width(), src.cullRect().height());
     src.playback(&canvas);
-    return SkNEW_ARGS(SkPicture, (src.cullRect().width(), src.cullRect().height(), 
+    return SkNEW_ARGS(SkPicture, (src.cullRect().width(), src.cullRect().height(),
                                   record.detach(), NULL/*bbh*/));
 }
 
@@ -645,6 +646,8 @@
     , fRecord(record)
     , fBBH(SkSafeRef(bbh))
     , fAnalysis(*record) {
+    // TODO: move optimization before we construct fAnalysis?
+    SkRecordOptimize(record);
     // TODO: delay as much of this work until just before first playback?
     if (fBBH.get()) {
         SkRecordFillBounds(*record, fBBH.get());
diff --git a/src/core/SkRecordOpts.cpp b/src/core/SkRecordOpts.cpp
index 146e161..428d1ca 100644
--- a/src/core/SkRecordOpts.cpp
+++ b/src/core/SkRecordOpts.cpp
@@ -14,12 +14,10 @@
 using namespace SkRecords;
 
 void SkRecordOptimize(SkRecord* record) {
-    // TODO(mtklein): fuse independent optimizations to reduce number of passes?
-    SkRecordNoopSaveRestores(record);
-    // TODO(mtklein): figure out why we draw differently and reenable
+    // TODO(mtklein): rebaseline and re-enable
     //SkRecordNoopSaveLayerDrawRestores(record);
-
-    SkRecordReduceDrawPosTextStrength(record);  // Helpful to run this before BoundDrawPosTextH.
+    SkRecordNoopSaveRestores(record);
+    SkRecordReduceDrawPosTextStrength(record);
 }
 
 // Most of the optimizations in this file are pattern-based.  These are all defined as structs with:
diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp
index b1cdf7e..8755440 100644
--- a/tests/PictureTest.cpp
+++ b/tests/PictureTest.cpp
@@ -914,7 +914,7 @@
         {
             SkPictureRecorder recorder;
 
-            SkCanvas* c = recorder.beginRecording(SkIntToScalar(kWidth), 
+            SkCanvas* c = recorder.beginRecording(SkIntToScalar(kWidth),
                                                   SkIntToScalar(kHeight));
             // 1)
             c->saveLayer(NULL, NULL); // layer #0
@@ -990,7 +990,7 @@
 
             REPORTER_ASSERT(reporter, info0.fValid);
             REPORTER_ASSERT(reporter, pict->uniqueID() == info0.fPictureID);
-            REPORTER_ASSERT(reporter, kWidth == info0.fSize.fWidth && 
+            REPORTER_ASSERT(reporter, kWidth == info0.fSize.fWidth &&
                                       kHeight == info0.fSize.fHeight);
             REPORTER_ASSERT(reporter, info0.fOriginXform.isIdentity());
             REPORTER_ASSERT(reporter, 0 == info0.fOffset.fX && 0 == info0.fOffset.fY);
@@ -999,12 +999,12 @@
 
             REPORTER_ASSERT(reporter, info1.fValid);
             REPORTER_ASSERT(reporter, pict->uniqueID() == info1.fPictureID);
-            REPORTER_ASSERT(reporter, kWidth == info1.fSize.fWidth && 
+            REPORTER_ASSERT(reporter, kWidth == info1.fSize.fWidth &&
                                       kHeight == info1.fSize.fHeight);
             REPORTER_ASSERT(reporter, info1.fOriginXform.isIdentity());
             REPORTER_ASSERT(reporter, 0 == info1.fOffset.fX && 0 == info1.fOffset.fY);
             REPORTER_ASSERT(reporter, NULL == info1.fPaint);
-            REPORTER_ASSERT(reporter, !info1.fIsNested && 
+            REPORTER_ASSERT(reporter, !info1.fIsNested &&
                                       info1.fHasNestedLayers); // has a nested SL
 
             REPORTER_ASSERT(reporter, info2.fValid);
@@ -1013,13 +1013,13 @@
                                       kHeight/2 == info2.fSize.fHeight); // bound reduces size
             REPORTER_ASSERT(reporter, info2.fOriginXform.isIdentity());
             REPORTER_ASSERT(reporter, kWidth/2 == info2.fOffset.fX &&   // translated
-                                      kHeight/2 == info2.fOffset.fY); 
+                                      kHeight/2 == info2.fOffset.fY);
             REPORTER_ASSERT(reporter, NULL == info1.fPaint);
             REPORTER_ASSERT(reporter, info2.fIsNested && !info2.fHasNestedLayers); // is nested
 
             REPORTER_ASSERT(reporter, info3.fValid);
             REPORTER_ASSERT(reporter, pict->uniqueID() == info3.fPictureID);
-            REPORTER_ASSERT(reporter, kWidth == info3.fSize.fWidth && 
+            REPORTER_ASSERT(reporter, kWidth == info3.fSize.fWidth &&
                                       kHeight == info3.fSize.fHeight);
             REPORTER_ASSERT(reporter, info3.fOriginXform.isIdentity());
             REPORTER_ASSERT(reporter, 0 == info3.fOffset.fX && 0 == info3.fOffset.fY);
@@ -1028,17 +1028,17 @@
 
             REPORTER_ASSERT(reporter, info4.fValid);
             REPORTER_ASSERT(reporter, pict->uniqueID() == info4.fPictureID);
-            REPORTER_ASSERT(reporter, kWidth == info4.fSize.fWidth && 
+            REPORTER_ASSERT(reporter, kWidth == info4.fSize.fWidth &&
                                       kHeight == info4.fSize.fHeight);
             REPORTER_ASSERT(reporter, 0 == info4.fOffset.fX && 0 == info4.fOffset.fY);
             REPORTER_ASSERT(reporter, info4.fOriginXform.isIdentity());
             REPORTER_ASSERT(reporter, NULL == info4.fPaint);
-            REPORTER_ASSERT(reporter, !info4.fIsNested && 
+            REPORTER_ASSERT(reporter, !info4.fIsNested &&
                                       info4.fHasNestedLayers); // has a nested SL
 
             REPORTER_ASSERT(reporter, info5.fValid);
             REPORTER_ASSERT(reporter, child->uniqueID() == info5.fPictureID); // in a child picture
-            REPORTER_ASSERT(reporter, kWidth == info5.fSize.fWidth && 
+            REPORTER_ASSERT(reporter, kWidth == info5.fSize.fWidth &&
                                       kHeight == info5.fSize.fHeight);
             REPORTER_ASSERT(reporter, 0 == info5.fOffset.fX && 0 == info5.fOffset.fY);
             REPORTER_ASSERT(reporter, info5.fOriginXform.isIdentity());
@@ -1047,17 +1047,17 @@
 
             REPORTER_ASSERT(reporter, info6.fValid);
             REPORTER_ASSERT(reporter, pict->uniqueID() == info6.fPictureID);
-            REPORTER_ASSERT(reporter, kWidth == info6.fSize.fWidth && 
+            REPORTER_ASSERT(reporter, kWidth == info6.fSize.fWidth &&
                                       kHeight == info6.fSize.fHeight);
             REPORTER_ASSERT(reporter, 0 == info6.fOffset.fX && 0 == info6.fOffset.fY);
             REPORTER_ASSERT(reporter, info6.fOriginXform.isIdentity());
             REPORTER_ASSERT(reporter, NULL == info6.fPaint);
-            REPORTER_ASSERT(reporter, !info6.fIsNested && 
+            REPORTER_ASSERT(reporter, !info6.fIsNested &&
                                       info6.fHasNestedLayers); // has a nested SL
 
             REPORTER_ASSERT(reporter, info7.fValid);
             REPORTER_ASSERT(reporter, child->uniqueID() == info7.fPictureID); // in a child picture
-            REPORTER_ASSERT(reporter, kWidth == info7.fSize.fWidth && 
+            REPORTER_ASSERT(reporter, kWidth == info7.fSize.fWidth &&
                                       kHeight == info7.fSize.fHeight);
             REPORTER_ASSERT(reporter, 0 == info7.fOffset.fX && 0 == info7.fOffset.fY);
             REPORTER_ASSERT(reporter, info7.fOriginXform.isIdentity());
@@ -1188,14 +1188,16 @@
 void check_save_state(skiatest::Reporter* reporter, SkPicture* picture,
                       unsigned int numSaves, unsigned int numSaveLayers,
                       unsigned int numRestores) {
-    SaveCountingCanvas canvas(SkScalarCeilToInt(picture->cullRect().width()), 
+    SaveCountingCanvas canvas(SkScalarCeilToInt(picture->cullRect().width()),
                               SkScalarCeilToInt(picture->cullRect().height()));
 
     picture->playback(&canvas);
 
-    REPORTER_ASSERT(reporter, numSaves == canvas.getSaveCount());
-    REPORTER_ASSERT(reporter, numSaveLayers == canvas.getSaveLayerCount());
-    REPORTER_ASSERT(reporter, numRestores == canvas.getRestoreCount());
+    // Optimizations may have removed these,
+    // so expect to have seen no more than num{Saves,SaveLayers,Restores}.
+    REPORTER_ASSERT(reporter, numSaves >= canvas.getSaveCount());
+    REPORTER_ASSERT(reporter, numSaveLayers >= canvas.getSaveLayerCount());
+    REPORTER_ASSERT(reporter, numRestores >= canvas.getRestoreCount());
 }
 
 // This class exists so SkPicture can friend it and give it access to
@@ -1445,7 +1447,7 @@
 
 static SkData* serialized_picture_from_bitmap(const SkBitmap& bitmap) {
     SkPictureRecorder recorder;
-    SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(bitmap.width()), 
+    SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(bitmap.width()),
                                                SkIntToScalar(bitmap.height()));
     canvas->drawBitmap(bitmap, 0, 0);
     SkAutoTUnref<SkPicture> picture(recorder.endRecording());