Adding a silent playback option to SkGPipeRead
Testing state consistency after silent playback in CanvasTest indirectly
through SkDeferredCanvas.

BUG=http://code.google.com/p/chromium/issues/detail?id=146178
TEST=CanvasTest unit test, and bench with --mode deferredSilent
Review URL: https://codereview.appspot.com/6542047

git-svn-id: http://skia.googlecode.com/svn/trunk@5619 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp
index ef93c9c..a3306c5 100644
--- a/src/utils/SkDeferredCanvas.cpp
+++ b/src/utils/SkDeferredCanvas.cpp
@@ -151,7 +151,7 @@
     virtual ~DeferredPipeController();
     virtual void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE;
     virtual void notifyWritten(size_t bytes) SK_OVERRIDE;
-    void playback();
+    void playback(bool silent);
     void reset();
     bool hasRecorded() const { return fAllocator.blockCount() != 0; }
     size_t storageAllocatedForRecording() const { return fAllocator.totalCapacity(); }
@@ -202,15 +202,16 @@
     fBytesWritten += bytes;
 }
 
-void DeferredPipeController::playback() {
-
+void DeferredPipeController::playback(bool silent) {
+    uint32_t flags = silent ? SkGPipeReader::kSilent_PlaybackFlag : 0;
     for (int currentBlock = 0; currentBlock < fBlockList.count(); currentBlock++ ) {
-        fReader.playback(fBlockList[currentBlock].fBlock, fBlockList[currentBlock].fSize);
+        fReader.playback(fBlockList[currentBlock].fBlock, fBlockList[currentBlock].fSize,
+                         flags);
     }
     fBlockList.reset();
 
     if (fBlock) {
-        fReader.playback(fBlock, fBytesWritten);
+        fReader.playback(fBlock, fBytesWritten, flags);
         fBlock = NULL;
     }
 
@@ -241,7 +242,7 @@
     bool isFreshFrame();
     size_t storageAllocatedForRecording() const;
     size_t freeMemoryIfPossible(size_t bytesToFree);
-    void flushPendingCommands();
+    void flushPendingCommands(bool silent);
     void skipPendingCommands();
     void setMaxRecordingStorage(size_t);
     void recordedDrawCommand();
@@ -359,7 +360,7 @@
 }
 
 DeferredDevice::~DeferredDevice() {
-    this->flushPendingCommands();
+    this->flushPendingCommands(true);
     SkSafeUnref(fImmediateCanvas);
 }
 
@@ -428,7 +429,7 @@
     return ret;
 }
 
-void DeferredDevice::flushPendingCommands() {
+void DeferredDevice::flushPendingCommands(bool silent) {
     if (!fPipeController.hasRecorded()) {
         return;
     }
@@ -436,7 +437,7 @@
         fNotificationClient->prepareForDraw();
     }
     fPipeWriter.flushRecording(true);
-    fPipeController.playback();
+    fPipeController.playback(silent);
     if (fNotificationClient) {
         fNotificationClient->flushedDrawCommands();
     }
@@ -444,7 +445,7 @@
 }
 
 void DeferredDevice::flush() {
-    this->flushPendingCommands();
+    this->flushPendingCommands(false);
     fImmediateCanvas->flush();
 }
 
@@ -467,7 +468,7 @@
         size_t tryFree = storageAllocated - fMaxRecordingStorageBytes;
         if (this->freeMemoryIfPossible(tryFree) < tryFree) {
             // Flush is necessary to free more space.
-            this->flushPendingCommands();
+            this->flushPendingCommands(false);
             // Free as much as possible to avoid oscillating around fMaxRecordingStorageBytes
             // which could cause a high flushing frequency.
             this->freeMemoryIfPossible(~0U);
@@ -499,7 +500,7 @@
 }
 
 SkGpuRenderTarget* DeferredDevice::accessRenderTarget() {
-    this->flushPendingCommands();
+    this->flushPendingCommands(false);
     return fImmediateDevice->accessRenderTarget();
 }
 
@@ -515,7 +516,7 @@
         SkCanvas::kNative_Premul_Config8888 != config8888 &&
         kPMColorAlias != config8888) {
         //Special case config: no deferral
-        this->flushPendingCommands();
+        this->flushPendingCommands(false);
         fImmediateDevice->writePixels(bitmap, x, y, config8888);
         return;
     }
@@ -523,7 +524,7 @@
     SkPaint paint;
     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     if (shouldDrawImmediately(&bitmap, NULL)) {
-        this->flushPendingCommands();
+        this->flushPendingCommands(false);
         fImmediateCanvas->drawSprite(bitmap, x, y, &paint);
     } else {
         this->recordingCanvas()->drawSprite(bitmap, x, y, &paint);
@@ -533,7 +534,7 @@
 }
 
 const SkBitmap& DeferredDevice::onAccessBitmap(SkBitmap*) {
-    this->flushPendingCommands();
+    this->flushPendingCommands(false);
     return fImmediateDevice->accessBitmap(false);
 }
 
@@ -552,7 +553,7 @@
 
 bool DeferredDevice::onReadPixels(
     const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) {
-    this->flushPendingCommands();
+    this->flushPendingCommands(false);
     return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap),
                                                    x, y, config8888);
 }
@@ -614,7 +615,7 @@
     if (val != fDeferredDrawing) {
         if (fDeferredDrawing) {
             // Going live.
-            this->getDeferredDevice()->flushPendingCommands();
+            this->getDeferredDevice()->flushPendingCommands(false);
         }
         fDeferredDrawing = val;
     }
@@ -628,6 +629,12 @@
     return this->getDeferredDevice()->isFreshFrame();
 }
 
+void SkDeferredCanvas::silentFlush() {
+    if (fDeferredDrawing) {
+        this->getDeferredDevice()->flushPendingCommands(true);
+    }
+}
+
 SkDeferredCanvas::~SkDeferredCanvas() {
 }