Ensure that Pipe does not crash when attempting to draw after endRecording.
authorscroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 14 Aug 2012 20:38:28 +0000 (20:38 +0000)
committerscroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 14 Aug 2012 20:38:28 +0000 (20:38 +0000)
Add a test for drawing a bitmap and a bitmapshader after endRecording.

BUG=https://code.google.com/p/skia/issues/detail?id=774&can=3
Test=PipeTest

Review URL: https://codereview.appspot.com/6459088

git-svn-id: http://skia.googlecode.com/svn/trunk@5099 2bbb7eff-a529-9590-31e7-b0007b416f81

src/pipe/SkGPipeWrite.cpp
tests/PipeTest.cpp

index e1eaabd..4f408fd 100644 (file)
@@ -192,7 +192,7 @@ public:
     size_t freeMemoryIfPossible(size_t bytesToFree);
 
     size_t storageAllocatedForRecording() {
-        return fBitmapHeap->bytesAllocated();
+        return (NULL == fBitmapHeap) ? 0 : fBitmapHeap->bytesAllocated();
     }
 
     // overrides from SkCanvas
@@ -348,11 +348,11 @@ bool SkGPipeCanvas::shuttleBitmap(const SkBitmap& bm, int32_t slot) {
 // return 0 for NULL (or unflattenable obj), or index-base-1
 // return ~(index-base-1) if an old flattenable was replaced
 int SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) {
+    SkASSERT(!fDone && fBitmapHeap != NULL);
     if (NULL == obj) {
         return 0;
     }
 
-
     fBitmapHeap->deferAddingOwners();
     bool added, replaced;
     const SkFlatData* flat = fFlatDictionary.findAndReplace(*obj, fFlattenableHeap.flatToReplace(),
@@ -703,15 +703,16 @@ bool SkGPipeCanvas::commonDrawBitmap(const SkBitmap& bm, DrawOps op,
                                      unsigned flags,
                                      size_t opBytesNeeded,
                                      const SkPaint* paint) {
-    int32_t bitmapIndex = fBitmapHeap->insert(bm);
-    if (SkBitmapHeap::INVALID_SLOT == bitmapIndex) {
-        return false;
-    }
     if (paint != NULL) {
         flags |= kDrawBitmap_HasPaint_DrawOpsFlag;
         this->writePaint(*paint);
     }
     if (this->needOpBytes(opBytesNeeded)) {
+        SkASSERT(fBitmapHeap != NULL);
+        int32_t bitmapIndex = fBitmapHeap->insert(bm);
+        if (SkBitmapHeap::INVALID_SLOT == bitmapIndex) {
+            return false;
+        }
         this->writeOp(op, flags, bitmapIndex);
         return true;
     }
@@ -941,7 +942,7 @@ void SkGPipeCanvas::flushRecording(bool detachCurrentBlock) {
 }
 
 size_t SkGPipeCanvas::freeMemoryIfPossible(size_t bytesToFree) {
-    return fBitmapHeap->freeMemoryIfPossible(bytesToFree);
+    return (NULL == fBitmapHeap) ? 0 : fBitmapHeap->freeMemoryIfPossible(bytesToFree);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -956,6 +957,9 @@ template <typename T> uint32_t castToU32(T value) {
 }
 
 void SkGPipeCanvas::writePaint(const SkPaint& paint) {
+    if (fDone) {
+        return;
+    }
     SkPaint& base = fPaint;
     uint32_t storage[32];
     uint32_t* ptr = storage;
index 3724223..7790c16 100644 (file)
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkGPipe.h"
+#include "SkPaint.h"
+#include "SkShader.h"
 #include "Test.h"
 
 // Ensures that the pipe gracefully handles drawing an invalid bitmap.
-static void testDrawingBadBitmap(skiatest::Reporter* reporter, SkCanvas* pipeCanvas) {
+static void testDrawingBadBitmap(SkCanvas* pipeCanvas) {
     SkBitmap badBitmap;
     badBitmap.setConfig(SkBitmap::kNo_Config, 5, 5);
     pipeCanvas->drawBitmap(badBitmap, 0, 0);
 }
 
-static void test_pipeTests(skiatest::Reporter* reporter) {
+// Ensure that pipe gracefully handles attempting to draw after endRecording is called on the
+// SkGPipeWriter.
+static void testDrawingAfterEndRecording(SkCanvas* canvas) {
+    PipeController pc(canvas);
+    SkGPipeWriter writer;
+    SkCanvas* pipeCanvas = writer.startRecording(&pc, SkGPipeWriter::kCrossProcess_Flag);
+    writer.endRecording();
+
+    SkBitmap bm;
+    bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
+    bm.allocPixels();
+    bm.eraseColor(0);
+
+    SkShader* shader = SkShader::CreateBitmapShader(bm, SkShader::kClamp_TileMode,
+                                                    SkShader::kClamp_TileMode);
+    SkPaint paint;
+    paint.setShader(shader)->unref();
+    pipeCanvas->drawPaint(paint);
+
+    pipeCanvas->drawBitmap(bm, 0, 0);
+}
+
+static void test_pipeTests(skiatest::Reporter*) {
     SkBitmap bitmap;
     bitmap.setConfig(SkBitmap::kARGB_8888_Config, 64, 64);
     SkCanvas canvas(bitmap);
@@ -27,8 +51,10 @@ static void test_pipeTests(skiatest::Reporter* reporter) {
     PipeController pipeController(&canvas);
     SkGPipeWriter writer;
     SkCanvas* pipeCanvas = writer.startRecording(&pipeController);
-    testDrawingBadBitmap(reporter, pipeCanvas);
+    testDrawingBadBitmap(pipeCanvas);
     writer.endRecording();
+
+    testDrawingAfterEndRecording(&canvas);
 }
 
 #include "TestClassDef.h"