Adding a silent playback option to SkGPipeRead
authorjunov@chromium.org <junov@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 20 Sep 2012 19:35:43 +0000 (19:35 +0000)
committerjunov@chromium.org <junov@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 20 Sep 2012 19:35:43 +0000 (19:35 +0000)
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

bench/benchmain.cpp
experimental/Debugger/DebuggerContentView.cpp
include/pipe/SkGPipe.h
include/utils/SkDeferredCanvas.h
src/pipe/SkGPipeRead.cpp
src/utils/SkDeferredCanvas.cpp
tests/CanvasTest.cpp

index 692b0bdc706cc3c3942ed520679decb403cfacc6..19ff176031fc0bee42f198d30d800528f2a5616b 100644 (file)
@@ -37,6 +37,7 @@
 enum benchModes {
     kNormal_benchModes,
     kDeferred_benchModes,
+    kDeferredSilent_benchModes,
     kRecord_benchModes,
     kPictureRecord_benchModes
 };
@@ -352,7 +353,7 @@ static void help() {
                           "[--timers [wcgWC]*] [--rotate]\n"
              "    [--scale] [--clip] [--min] [--forceAA 1|0] [--forceFilter 1|0]\n"
              "    [--forceDither 1|0] [--forceBlend 1|0] [--strokeWidth width]\n"
-             "    [--match name] [--mode normal|deferred|record|picturerecord]\n"
+             "    [--match name] [--mode normal|deferred|deferredSilent|record|picturerecord]\n"
              "    [--config 8888|565|GPU|ANGLE|NULLGPU] [-Dfoo bar] [--logFile filename]\n"
              "    [-h|--help]");
     SkDebugf("\n\n");
@@ -376,9 +377,11 @@ static void help() {
              "Enable/disable dithering, default is disabled.\n");
     SkDebugf("    --strokeWidth width : The width for path stroke.\n");
     SkDebugf("    --match name : Only run bench whose name is matched.\n");
-    SkDebugf("    --mode normal|deferred|record|picturerecord : Run in the corresponding mode\n"
+    SkDebugf("    --mode normal|deferred|deferredSilent|record|picturerecord :\n"
+             "             Run in the corresponding mode\n"
              "                 normal, Use a normal canvas to draw to;\n"
              "                 deferred, Use a deferrred canvas when drawing;\n"
+             "                 deferredSilent, deferred with silent playback;\n"
              "                 record, Benchmark the time to record to an SkPicture;\n"
              "                 picturerecord, Benchmark the time to do record from a \n"
              "                                SkPicture to a SkPicture.\n");
@@ -526,6 +529,8 @@ int main (int argc, char * const argv[]) {
                     benchMode = kNormal_benchModes;
                 } else if (strcmp(*argv, "deferred") == 0) {
                     benchMode = kDeferred_benchModes;
+                } else if (strcmp(*argv, "deferredSilent") == 0) {
+                    benchMode = kDeferredSilent_benchModes;
                 } else if (strcmp(*argv, "record") == 0) {
                     benchMode = kRecord_benchModes;
                 } else if (strcmp(*argv, "picturerecord") == 0) {
@@ -637,9 +642,11 @@ int main (int argc, char * const argv[]) {
     // report our current settings
     {
         SkString str;
+        const char* deferredMode = benchMode == kDeferred_benchModes ? "yes" :
+            (benchMode == kDeferredSilent_benchModes ? "silent" : "no");
         str.printf("skia bench: alpha=0x%02X antialias=%d filter=%d "
-                   "deferred=%d logperiter=%d",
-                   forceAlpha, forceAA, forceFilter, benchMode == kDeferred_benchModes,
+                   "deferred=%s logperiter=%d",
+                   forceAlpha, forceAA, forceFilter, deferredMode,
                    logPerIter);
         str.appendf(" rotate=%d scale=%d clip=%d min=%d",
                    doRotate, doScale, doClip, printMin);
@@ -763,6 +770,7 @@ int main (int argc, char * const argv[]) {
             SkPicture pictureRecordFrom;
             SkPicture pictureRecordTo;
             switch(benchMode) {
+                case kDeferredSilent_benchModes: 
                 case kDeferred_benchModes:
                     canvas = new SkDeferredCanvas(device);
                     break;
@@ -816,7 +824,12 @@ int main (int argc, char * const argv[]) {
                 } else {
                     bench->draw(canvas);
                 }
-                canvas->flush();
+
+                if (kDeferredSilent_benchModes == benchMode) {
+                    static_cast<SkDeferredCanvas*>(canvas)->silentFlush();
+                } else {
+                    canvas->flush();
+                }
 #if SK_SUPPORT_GPU
                 if (glHelper) {
                     glHelper->grContext()->flush();
@@ -842,7 +855,12 @@ int main (int argc, char * const argv[]) {
                 } else {
                     bench->draw(canvas);
                 }
-                canvas->flush();
+
+                if (kDeferredSilent_benchModes == benchMode) {
+                    static_cast<SkDeferredCanvas*>(canvas)->silentFlush();
+                } else {
+                    canvas->flush();
+                }
 
                 // stop the truncated timer after the last canvas call but
                 // don't wait for all the GL calls to complete
index 8039e57faa5653ce4931aeb794590854c13a5069..f079508643dfac35e5ed1ab8f8cdeae9317d8895 100644 (file)
@@ -40,10 +40,9 @@ public:
             int frameBound = 0;
             size_t bytesRead;
             while (static_cast<unsigned>(offset) < size) {
-                SkGPipeReader::Status s = dumpReader->playback(data + offset,
-                                                               size - offset,
-                                                               &bytesRead,
-                                                               true);
+                SkGPipeReader::Status s =
+                    dumpReader->playback(data + offset, size - offset,
+                                         SkGPipeReader::kReadAtom_PlaybackFlag, &bytesRead);
                 SkASSERT(SkGPipeReader::kError_Status != s);
                 offset += bytesRead;
 
@@ -138,9 +137,9 @@ protected:
             SkGPipeReader::Status s;
             //Read the first chunk
             if (offset < firstChunk && firstChunk < toBeRead) {
-                s = dumpReader->playback(fData.begin() + offset, firstChunk - offset, NULL, false);
+                s = dumpReader->playback(fData.begin() + offset, firstChunk - offset);
                 SkASSERT(SkGPipeReader::kError_Status != s);
-                s = reader->playback(fData.begin() + offset, firstChunk - offset, &bytesRead, false);
+                s = reader->playback(fData.begin() + offset, firstChunk - offset, 0, &bytesRead);
                 SkASSERT(SkGPipeReader::kError_Status != s);
                 if (SkGPipeReader::kDone_Status == s){
                     delete dumpReader;
@@ -155,9 +154,11 @@ protected:
             SkASSERT(offset == firstChunk);
             //Then read the current atom
             fDumper->enable();
-            s = dumpReader->playback(fData.begin() + offset, toBeRead - offset, NULL, true);
+            s = dumpReader->playback(fData.begin() + offset, toBeRead - offset,
+                                     SkGPipeReader::kReadAtom_PlaybackFlag);
             SkASSERT(SkGPipeReader::kError_Status != s);
-            s = reader->playback(fData.begin() + offset, toBeRead - offset, &bytesRead, true);
+            s = reader->playback(fData.begin() + offset, toBeRead - offset,
+                                 SkGPipeReader::kReadAtom_PlaybackFlag, &bytesRead);
             SkASSERT(SkGPipeReader::kError_Status != s);
 
             delete reader;
index f1fc4b0edea807581583c3ee9caa9a724e3b1291..27af16db8c134fdacd97fb03102eb33f5d868b1b 100644 (file)
@@ -34,11 +34,16 @@ public:
         kReadAtom_Status//!< finished reading an atom
     };
 
+    enum PlaybackFlags {
+        kReadAtom_PlaybackFlag = 0x1, //!< playback a single command from the stream
+        kSilent_PlaybackFlag   = 0x2, //!< playback without drawing
+    };
+
     void setCanvas(SkCanvas*);
     // data must be 4-byte aligned
     // length must be a multiple of 4
-    Status playback(const void* data, size_t length, size_t* bytesRead = NULL,
-                    bool readAtom = false);
+    Status playback(const void* data, size_t length, uint32_t playbackFlags = 0,
+                    size_t* bytesRead = NULL);
 private:
     SkCanvas*           fCanvas;
     class SkGPipeState* fState;
index 5e8920024a87b0bd0fb3593272069ae3430c0655..f3005b322bed6d614292145365a822e5f2c3981f 100644 (file)
@@ -109,6 +109,11 @@ public:
      */
     size_t freeMemoryIfPossible(size_t bytesToFree);
 
+    /**
+     * Executes all pending commands without drawing
+     */
+    void silentFlush();
+
     // Overrides of the SkCanvas interface
     virtual int save(SaveFlags flags) SK_OVERRIDE;
     virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
index 137ecb706251b3d31fc9e0077d4b33dc88857fdd..1f13dafa7daa7444b58dbbae192998d2ff9e8cc9 100644 (file)
@@ -67,6 +67,14 @@ public:
     SkGPipeState();
     ~SkGPipeState();
 
+    void setSilent(bool silent) {
+        fSilent = silent;
+    }
+
+    bool shouldDraw() {
+        return !fSilent;
+    }
+
     void setFlags(unsigned flags) {
         if (fFlags != flags) {
             fFlags = flags;
@@ -183,6 +191,7 @@ private:
     SkTDArray<SkTypeface*>    fTypefaces;
     SkTDArray<SkFlattenable::Factory> fFactoryArray;
     SkTDArray<SkBitmap*>      fBitmaps;
+    bool                      fSilent;
     // Only used when sharing bitmaps with the writer.
     SkBitmapHeap*             fSharedHeap;
     unsigned                  fFlags;
@@ -308,7 +317,9 @@ static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
 
 static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
                          SkGPipeState* state) {
-    canvas->drawPaint(state->paint());
+    if (state->shouldDraw()) {
+        canvas->drawPaint(state->paint());
+    }
 }
 
 static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
@@ -316,19 +327,26 @@ static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
     SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32);
     size_t count = reader->readU32();
     const SkPoint* pts = skip<SkPoint>(reader, count);
-    canvas->drawPoints(mode, count, pts, state->paint());
+    if (state->shouldDraw()) {
+        canvas->drawPoints(mode, count, pts, state->paint());
+    }
 }
 
 static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
                         SkGPipeState* state) {
-    canvas->drawRect(*skip<SkRect>(reader), state->paint());
+    const SkRect* rect = skip<SkRect>(reader);
+    if (state->shouldDraw()) {
+        canvas->drawRect(*rect, state->paint());
+    }
 }
 
 static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
                         SkGPipeState* state) {
     SkPath path;
     reader->readPath(&path);
-    canvas->drawPath(path, state->paint());
+    if (state->shouldDraw()) {
+        canvas->drawPath(path, state->paint());
+    }
 }
 
 static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
@@ -358,9 +376,10 @@ static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
         indexCount = reader->readU32();
         indices = skipAlign<uint16_t>(reader, indexCount);
     }
-
-    canvas->drawVertices(mode, vertexCount, verts, texs, colors, xfer,
-                         indices, indexCount, state->paint());
+    if (state->shouldDraw()) {
+        canvas->drawVertices(mode, vertexCount, verts, texs, colors, xfer,
+                             indices, indexCount, state->paint());
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -370,7 +389,9 @@ static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
     size_t len = reader->readU32();
     const void* text = reader->skip(SkAlign4(len));
     const SkScalar* xy = skip<SkScalar>(reader, 2);
-    canvas->drawText(text, len, xy[0], xy[1], state->paint());
+    if (state->shouldDraw()) {
+        canvas->drawText(text, len, xy[0], xy[1], state->paint());
+    }
 }
 
 static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
@@ -379,7 +400,9 @@ static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
     const void* text = reader->skip(SkAlign4(len));
     size_t posCount = reader->readU32();    // compute by our writer
     const SkPoint* pos = skip<SkPoint>(reader, posCount);
-    canvas->drawPosText(text, len, pos, state->paint());
+    if (state->shouldDraw()) {
+        canvas->drawPosText(text, len, pos, state->paint());
+    }
 }
 
 static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
@@ -389,7 +412,9 @@ static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
     size_t posCount = reader->readU32();    // compute by our writer
     const SkScalar* xpos = skip<SkScalar>(reader, posCount);
     SkScalar constY = reader->readScalar();
-    canvas->drawPosTextH(text, len, xpos, constY, state->paint());
+    if (state->shouldDraw()) {
+        canvas->drawPosTextH(text, len, xpos, constY, state->paint());
+    }
 }
 
 static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
@@ -406,8 +431,9 @@ static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op3
         reader->readMatrix(&matrixStorage);
         matrix = &matrixStorage;
     }
-
-    canvas->drawTextOnPath(text, len, path, matrix, state->paint());
+    if (state->shouldDraw()) {
+        canvas->drawTextOnPath(text, len, path, matrix, state->paint());
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -461,7 +487,10 @@ static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
     bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
     SkScalar left = reader->readScalar();
     SkScalar top = reader->readScalar();
-    canvas->drawBitmap(*holder.getBitmap(), left, top, hasPaint ? &state->paint() : NULL);
+    const SkBitmap* bitmap = holder.getBitmap();
+    if (state->shouldDraw()) {
+        canvas->drawBitmap(*bitmap, left, top, hasPaint ? &state->paint() : NULL);
+    }
 }
 
 static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
@@ -470,8 +499,11 @@ static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t o
     bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
     SkMatrix matrix;
     reader->readMatrix(&matrix);
-    canvas->drawBitmapMatrix(*holder.getBitmap(), matrix,
-                             hasPaint ? &state->paint() : NULL);
+    const SkBitmap* bitmap = holder.getBitmap();
+    if (state->shouldDraw()) {
+        canvas->drawBitmapMatrix(*bitmap, matrix,
+                                 hasPaint ? &state->paint() : NULL);
+    }
 }
 
 static void drawBitmapNine_rp(SkCanvas* canvas, SkReader32* reader,
@@ -480,8 +512,11 @@ static void drawBitmapNine_rp(SkCanvas* canvas, SkReader32* reader,
     bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
     const SkIRect* center = skip<SkIRect>(reader);
     const SkRect* dst = skip<SkRect>(reader);
-    canvas->drawBitmapNine(*holder.getBitmap(), *center, *dst,
-                           hasPaint ? &state->paint() : NULL);
+    const SkBitmap* bitmap = holder.getBitmap();
+    if (state->shouldDraw()) {
+        canvas->drawBitmapNine(*bitmap, *center, *dst,
+                               hasPaint ? &state->paint() : NULL);
+    }
 }
 
 static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader,
@@ -497,7 +532,10 @@ static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader,
         src = NULL;
     }
     const SkRect* dst = skip<SkRect>(reader);
-    canvas->drawBitmapRectToRect(*holder.getBitmap(), src, *dst, hasPaint ? &state->paint() : NULL);
+    const SkBitmap* bitmap = holder.getBitmap();
+    if (state->shouldDraw()) {
+        canvas->drawBitmapRectToRect(*bitmap, src, *dst, hasPaint ? &state->paint() : NULL);
+    }
 }
 
 static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
@@ -505,7 +543,10 @@ static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
     BitmapHolder holder(reader, op32, state);
     bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
     const SkIPoint* point = skip<SkIPoint>(reader);
-    canvas->drawSprite(*holder.getBitmap(), point->fX, point->fY, hasPaint ? &state->paint() : NULL);
+    const SkBitmap* bitmap = holder.getBitmap();
+    if (state->shouldDraw()) {
+        canvas->drawSprite(*bitmap, point->fX, point->fY, hasPaint ? &state->paint() : NULL);
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -518,7 +559,9 @@ static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
         size = reader->readU32();
     }
     const void* data = reader->skip(SkAlign4(size));
-    canvas->drawData(data, size);
+    if (state->shouldDraw()) {
+        canvas->drawData(data, size);
+    }
 }
 
 static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
@@ -677,6 +720,7 @@ static const ReadProc gReadTable[] = {
 
 SkGPipeState::SkGPipeState()
     : fReader(0)
+    , fSilent(false)
     , fSharedHeap(NULL)
     , fFlags(0) {
 
@@ -714,7 +758,7 @@ SkGPipeReader::~SkGPipeReader() {
 }
 
 SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
-                                              size_t* bytesRead, bool readAtom) {
+                                              uint32_t playbackFlags, size_t* bytesRead) {
     if (NULL == fCanvas) {
         return kError_Status;
     }
@@ -723,6 +767,8 @@ SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
         fState = new SkGPipeState;
     }
 
+    fState->setSilent(playbackFlags & kSilent_PlaybackFlag);
+
     SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1));
 
     const ReadProc* table = gReadTable;
@@ -746,7 +792,7 @@ SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
             break;
         }
         table[op](canvas, reader.getReader32(), op32, fState);
-        if (readAtom &&
+        if ((playbackFlags & kReadAtom_PlaybackFlag) &&
             (table[op] != paintOp_rp &&
              table[op] != def_Typeface_rp &&
              table[op] != def_PaintFlat_rp &&
index ef93c9cd715fc2ac1ccbc2ac7ab22114995b7075..a3306c52a3f3f9fc33aa254d402e6c25f3452d57 100644 (file)
@@ -151,7 +151,7 @@ public:
     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 @@ void DeferredPipeController::notifyWritten(size_t bytes) {
     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 @@ public:
     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(
 }
 
 DeferredDevice::~DeferredDevice() {
-    this->flushPendingCommands();
+    this->flushPendingCommands(true);
     SkSafeUnref(fImmediateCanvas);
 }
 
@@ -428,7 +429,7 @@ bool DeferredDevice::isFreshFrame() {
     return ret;
 }
 
-void DeferredDevice::flushPendingCommands() {
+void DeferredDevice::flushPendingCommands(bool silent) {
     if (!fPipeController.hasRecorded()) {
         return;
     }
@@ -436,7 +437,7 @@ void DeferredDevice::flushPendingCommands() {
         fNotificationClient->prepareForDraw();
     }
     fPipeWriter.flushRecording(true);
-    fPipeController.playback();
+    fPipeController.playback(silent);
     if (fNotificationClient) {
         fNotificationClient->flushedDrawCommands();
     }
@@ -444,7 +445,7 @@ void DeferredDevice::flushPendingCommands() {
 }
 
 void DeferredDevice::flush() {
-    this->flushPendingCommands();
+    this->flushPendingCommands(false);
     fImmediateCanvas->flush();
 }
 
@@ -467,7 +468,7 @@ void DeferredDevice::recordedDrawCommand() {
         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 @@ int DeferredDevice::height() const {
 }
 
 SkGpuRenderTarget* DeferredDevice::accessRenderTarget() {
-    this->flushPendingCommands();
+    this->flushPendingCommands(false);
     return fImmediateDevice->accessRenderTarget();
 }
 
@@ -515,7 +516,7 @@ void DeferredDevice::writePixels(const SkBitmap& bitmap,
         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 @@ void DeferredDevice::writePixels(const SkBitmap& bitmap,
     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 @@ void DeferredDevice::writePixels(const SkBitmap& bitmap,
 }
 
 const SkBitmap& DeferredDevice::onAccessBitmap(SkBitmap*) {
-    this->flushPendingCommands();
+    this->flushPendingCommands(false);
     return fImmediateDevice->accessBitmap(false);
 }
 
@@ -552,7 +553,7 @@ SkDevice* DeferredDevice::onCreateCompatibleDevice(
 
 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 @@ void SkDeferredCanvas::setDeferredDrawing(bool val) {
     if (val != fDeferredDrawing) {
         if (fDeferredDrawing) {
             // Going live.
-            this->getDeferredDevice()->flushPendingCommands();
+            this->getDeferredDevice()->flushPendingCommands(false);
         }
         fDeferredDrawing = val;
     }
@@ -628,6 +629,12 @@ bool SkDeferredCanvas::isFreshFrame() const {
     return this->getDeferredDevice()->isFreshFrame();
 }
 
+void SkDeferredCanvas::silentFlush() {
+    if (fDeferredDrawing) {
+        this->getDeferredDevice()->flushPendingCommands(true);
+    }
+}
+
 SkDeferredCanvas::~SkDeferredCanvas() {
 }
 
index 9449bfe61e5723be5d710eac50eb4582a4d4c47c..fd62893392616359f465046cd6f6e445b4b75bba 100644 (file)
@@ -125,6 +125,8 @@ static const char* const kDeferredPreFlushAssertMessageFormat =
     "test step %s, SkDeferredCanvas state consistency before flush";
 static const char* const kDeferredPostFlushPlaybackAssertMessageFormat =
     "test step %s, SkDeferredCanvas playback canvas state consistency after flush";
+static const char* const kDeferredPostSilentFlushPlaybackAssertMessageFormat =
+    "test step %s, SkDeferredCanvas playback canvas state consistency after silent flush";
 static const char* const kDeferredPostFlushAssertMessageFormat =
     "test step %s, SkDeferredCanvas state consistency after flush";
 static const char* const kPictureResourceReuseMessageFormat =
@@ -738,7 +740,7 @@ public:
     static void TestDeferredCanvasStateConsistency(
         skiatest::Reporter* reporter,
         CanvasTestStep* testStep,
-        const SkCanvas& referenceCanvas) {
+        const SkCanvas& referenceCanvas, bool silent) {
 
         SkBitmap deferredStore;
         createBitmap(&deferredStore, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
@@ -750,8 +752,14 @@ public:
         AssertCanvasStatesEqual(reporter, &deferredCanvas, &referenceCanvas,
             testStep);
 
-        deferredCanvas.flush();
-        testStep->setAssertMessageFormat(
+        if (silent) {
+            deferredCanvas.silentFlush();
+        } else {
+            deferredCanvas.flush();
+        }
+
+        testStep->setAssertMessageFormat( 
+            silent ? kDeferredPostSilentFlushPlaybackAssertMessageFormat :
             kDeferredPostFlushPlaybackAssertMessageFormat);
         AssertCanvasStatesEqual(reporter,
             deferredCanvas.immediateCanvas(),
@@ -844,7 +852,9 @@ static void TestOverrideStateConsistency(skiatest::Reporter* reporter,
     testStep->setAssertMessageFormat(kCanvasDrawAssertMessageFormat);
     testStep->draw(&referenceCanvas, reporter);
 
-    SkDeferredCanvasTester::TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas);
+    SkDeferredCanvasTester::TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas, false);
+
+    SkDeferredCanvasTester::TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas, true);
 
     // The following test code is disabled because SkProxyCanvas is
     // missing a lot of virtual overrides on get* methods, which are used