Reland bug fixes from "4x allocation in PipeController is probably overkill."

BUG=372671
R=mtklein@google.com

Author: mtklein@chromium.org

Review URL: https://codereview.chromium.org/283093002

git-svn-id: http://skia.googlecode.com/svn/trunk@14727 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp
index 82848f8..b78c291 100644
--- a/src/pipe/SkGPipeWrite.cpp
+++ b/src/pipe/SkGPipeWrite.cpp
@@ -366,7 +366,7 @@
     const char* name;
     while ((name = fFactorySet->getNextAddedFactoryName()) != NULL) {
         size_t len = strlen(name);
-        if (this->needOpBytes(len)) {
+        if (this->needOpBytes(SkWriter32::WriteStringSize(name, len))) {
             this->writeOp(kDef_Factory_DrawOp);
             fWriter.writeString(name, len);
         }
@@ -474,12 +474,13 @@
     }
 
     needed += 4;  // size of DrawOp atom
+    needed = SkTMax<size_t>(MIN_BLOCK_SIZE, needed);
+    needed = SkAlign4(needed);
     if (fWriter.bytesWritten() + needed > fBlockSize) {
         // Before we wipe out any data that has already been written, read it
         // out.
         this->doNotify();
-        size_t blockSize = SkTMax<size_t>(MIN_BLOCK_SIZE, needed);
-        void* block = fController->requestBlock(blockSize, &fBlockSize);
+        void* block = fController->requestBlock(needed, &fBlockSize);
         if (NULL == block) {
             // Do not notify the readers, which would call this function again.
             this->finish(false);
@@ -936,9 +937,15 @@
     }
 
     NOTIFY_SETUP(this);
-    size_t size = 4 + vertexCount * sizeof(SkPoint);
     this->writePaint(paint);
-    unsigned flags = 0;
+
+    unsigned flags = 0;  // packs with the op, so needs no extra space
+
+    size_t size = 0;
+    size += 4;                              // vmode
+    size += 4;                              // vertex count
+    size += vertexCount * sizeof(SkPoint);  // vertices
+
     if (texs) {
         flags |= kDrawVertices_HasTexs_DrawOpFlag;
         size += vertexCount * sizeof(SkPoint);
@@ -947,13 +954,14 @@
         flags |= kDrawVertices_HasColors_DrawOpFlag;
         size += vertexCount * sizeof(SkColor);
     }
-    if (indices && indexCount > 0) {
-        flags |= kDrawVertices_HasIndices_DrawOpFlag;
-        size += 4 + SkAlign4(indexCount * sizeof(uint16_t));
-    }
     if (xfer && !SkXfermode::IsMode(xfer, SkXfermode::kModulate_Mode)) {
         flags |= kDrawVertices_HasXfermode_DrawOpFlag;
-        size += sizeof(int32_t);    // mode enum
+        size += sizeof(int32_t);    // SkXfermode::Mode
+    }
+    if (indices && indexCount > 0) {
+        flags |= kDrawVertices_HasIndices_DrawOpFlag;
+        size += 4;                                        // index count
+        size += SkAlign4(indexCount * sizeof(uint16_t));  // indices
     }
 
     if (this->needOpBytes(size)) {
@@ -961,18 +969,18 @@
         fWriter.write32(vmode);
         fWriter.write32(vertexCount);
         fWriter.write(vertices, vertexCount * sizeof(SkPoint));
-        if (texs) {
+        if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
             fWriter.write(texs, vertexCount * sizeof(SkPoint));
         }
-        if (colors) {
+        if (flags & kDrawVertices_HasColors_DrawOpFlag) {
             fWriter.write(colors, vertexCount * sizeof(SkColor));
         }
         if (flags & kDrawVertices_HasXfermode_DrawOpFlag) {
             SkXfermode::Mode mode = SkXfermode::kModulate_Mode;
-            (void)xfer->asMode(&mode);
+            SkAssertResult(xfer->asMode(&mode));
             fWriter.write32(mode);
         }
-        if (indices && indexCount > 0) {
+        if (flags & kDrawVertices_HasIndices_DrawOpFlag) {
             fWriter.write32(indexCount);
             fWriter.writePad(indices, indexCount * sizeof(uint16_t));
         }
@@ -1009,7 +1017,7 @@
 }
 
 void SkGPipeCanvas::flushRecording(bool detachCurrentBlock) {
-    doNotify();
+    this->doNotify();
     if (detachCurrentBlock) {
         // force a new block to be requested for the next recorded command
         fBlockSize = 0;
diff --git a/tests/DeferredCanvasTest.cpp b/tests/DeferredCanvasTest.cpp
index b61ae2e..a5a763a 100644
--- a/tests/DeferredCanvasTest.cpp
+++ b/tests/DeferredCanvasTest.cpp
@@ -547,7 +547,7 @@
     canvas->drawBitmap(sourceImages[0], 0, 0, NULL);
     REPORTER_ASSERT(reporter, 2 == notificationCounter.fStorageAllocatedChangedCount);
     canvas->drawBitmap(sourceImages[0], 0, 0, NULL);
-    REPORTER_ASSERT(reporter, 2 == notificationCounter.fStorageAllocatedChangedCount);
+    REPORTER_ASSERT(reporter, 3 == notificationCounter.fStorageAllocatedChangedCount);
     REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount);
     REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() < 2 * bitmapSize);