Adding bracketing save/restore calls to SkPicture at record time and
preparing tests for enforcing save/restore balancing constraints on SkPicture

Review URL: http://codereview.appspot.com/6354105/



git-svn-id: http://skia.googlecode.com/svn/trunk@4618 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 630a1bb..ed528f2 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -12,6 +12,10 @@
 #define MIN_WRITER_SIZE 16384
 #define HEAP_BLOCK_SIZE 4096
 
+enum {
+    kNoInitialSave = -1,
+};
+
 SkPictureRecord::SkPictureRecord(uint32_t flags) :
         fHeap(HEAP_BLOCK_SIZE),
         fBitmaps(&fHeap),
@@ -26,7 +30,7 @@
 #endif
 
     fRestoreOffsetStack.setReserve(32);
-    fRestoreOffsetStack.push(0);
+    fInitialSaveCount = kNoInitialSave;
 
     fPathHeap = NULL;   // lazy allocate
     fFirstSavedLayerIndex = kNoSavedLayerIndex;
@@ -38,6 +42,16 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+SkDevice* SkPictureRecord::setDevice(SkDevice* device) {
+    SkASSERT(kNoInitialSave == fInitialSaveCount);
+    this->INHERITED::setDevice(device);
+
+    // The bracketting save() call needs to be recorded after setting the
+    // device otherwise the clip stack will get messed-up
+    fInitialSaveCount = this->save(SkCanvas::kMatrixClip_SaveFlag);
+    return device;
+}
+
 int SkPictureRecord::save(SaveFlags flags) {
     addDraw(SAVE);
     addInt(flags);
@@ -78,6 +92,13 @@
 }
 
 void SkPictureRecord::restore() {
+    // FIXME: SkDeferredCanvas needs to be refactored to respect
+    // save/restore balancing so that the following test can be
+    // turned on permanently.
+#if 0
+    SkASSERT(fRestoreOffsetStack.count() > 1);
+#endif
+
     // check for underflow
     if (fRestoreOffsetStack.count() == 0) {
         return;
@@ -171,11 +192,8 @@
 }
 
 void SkPictureRecord::endRecording() {
-    // clear any remaining unhandled restore offset placeholders
-    while (fRestoreOffsetStack.count()) {
-        this->fillRestoreOffsetPlaceholdersForCurrentStackLevel(0);
-        fRestoreOffsetStack.pop();
-    }
+    SkASSERT(kNoInitialSave != fInitialSaveCount);
+    this->restoreToCount(fInitialSaveCount);
 }
 
 void SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) {