Reuse one canvas for every tile in bench_pictures (in single threaded mode).

Turn off multi threaded option for now.

In bench_pictures, do not create a large canvas, since we never use it.

Remove unused functions on TiledPictureRenderer.

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

git-svn-id: http://skia.googlecode.com/svn/trunk@5583 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp
index cc9babb..cea7b5b 100644
--- a/tools/PictureRenderer.cpp
+++ b/tools/PictureRenderer.cpp
@@ -115,6 +115,8 @@
     return SkImageEncoder::EncodeFile(path.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100);
 }
 
+///////////////////////////////////////////////////////////////////////////////////////////////
+
 void RecordPictureRenderer::render(bool doExtraWorkToDrawToBaseCanvas) {
     SkPicture replayer;
     SkCanvas* recorder = replayer.beginRecording(fPicture->width(), fPicture->height());
@@ -122,6 +124,8 @@
     replayer.endRecording();
 }
 
+///////////////////////////////////////////////////////////////////////////////////////////////
+
 void PipePictureRenderer::render(bool doExtraWorkToDrawToBaseCanvas) {
     SkASSERT(fCanvas.get() != NULL);
     SkASSERT(fPicture != NULL);
@@ -137,6 +141,8 @@
     fCanvas->flush();
 }
 
+///////////////////////////////////////////////////////////////////////////////////////////////
+
 void SimplePictureRenderer::render(bool doExtraWorkToDrawToBaseCanvas) {
     SkASSERT(fCanvas.get() != NULL);
     SkASSERT(fPicture != NULL);
@@ -148,6 +154,8 @@
     fCanvas->flush();
 }
 
+///////////////////////////////////////////////////////////////////////////////////////////////
+
 TiledPictureRenderer::TiledPictureRenderer()
     : fMultiThreaded(false)
     , fUsePipe(false)
@@ -159,12 +167,14 @@
 
 void TiledPictureRenderer::init(SkPicture* pict) {
     SkASSERT(pict != NULL);
-    SkASSERT(0 == fTiles.count());
-    if (NULL == pict || fTiles.count() != 0) {
+    SkASSERT(0 == fTileRects.count());
+    if (NULL == pict || fTileRects.count() != 0) {
         return;
     }
 
-    this->INHERITED::init(pict);
+    // Do not call INHERITED::init(), which would create a (potentially large) canvas which is not
+    // used by bench_pictures.
+    fPicture = pict;
 
     if (fTileWidthPercentage > 0) {
         fTileWidth = sk_float_ceil2int(float(fTileWidthPercentage * fPicture->width() / 100));
@@ -180,19 +190,6 @@
     }
 }
 
-void TiledPictureRenderer::render(bool doExtraWorkToDrawToBaseCanvas) {
-    SkASSERT(fCanvas.get() != NULL);
-    SkASSERT(fPicture != NULL);
-    if (NULL == fCanvas.get() || NULL == fPicture) {
-        return;
-    }
-
-    this->drawTiles();
-    if (doExtraWorkToDrawToBaseCanvas) {
-        this->copyTilesToCanvas();
-    }
-}
-
 void TiledPictureRenderer::end() {
     this->deleteTiles();
     this->INHERITED::end();
@@ -202,27 +199,13 @@
     this->deleteTiles();
 }
 
-void TiledPictureRenderer::clipTile(SkCanvas* tile) {
-    SkRect clip = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
-                                 SkIntToScalar(fPicture->height()));
-    tile->clipRect(clip);
-}
-
-void TiledPictureRenderer::addTile(int tile_x_start, int tile_y_start, int width, int height) {
-    SkCanvas* tile = this->setupCanvas(width, height);
-
-    tile->translate(SkIntToScalar(-tile_x_start), SkIntToScalar(-tile_y_start));
-    this->clipTile(tile);
-
-    fTiles.push(tile);
-}
-
 void TiledPictureRenderer::setupTiles() {
-    for (int tile_y_start = 0; tile_y_start < fPicture->height();
-         tile_y_start += fTileHeight) {
-        for (int tile_x_start = 0; tile_x_start < fPicture->width();
-             tile_x_start += fTileWidth) {
-            this->addTile(tile_x_start, tile_y_start, fTileWidth, fTileHeight);
+    for (int tile_y_start = 0; tile_y_start < fPicture->height(); tile_y_start += fTileHeight) {
+        for (int tile_x_start = 0; tile_x_start < fPicture->width(); tile_x_start += fTileWidth) {
+            *fTileRects.append() = SkRect::MakeXYWH(SkIntToScalar(tile_x_start),
+                                                    SkIntToScalar(tile_y_start),
+                                                    SkIntToScalar(fTileWidth),
+                                                    SkIntToScalar(fTileHeight));
         }
     }
 }
@@ -250,11 +233,17 @@
     for (int tile_y_start = 0; tile_y_start < fPicture->height(); tile_y_start += fTileHeight) {
         int tile_x_start = 0;
         int current_width = largest_possible_tile_size;
+        // Set fTileWidth to be the width of the widest tile, so that each canvas is large enough
+        // to draw each tile.
+        fTileWidth = current_width;
 
         while (current_width >= fTileMinPowerOf2Width) {
             // It is very important this is a bitwise AND.
             if (current_width & rounded_value) {
-                this->addTile(tile_x_start, tile_y_start, current_width, fTileHeight);
+                *fTileRects.append() = SkRect::MakeXYWH(SkIntToScalar(tile_x_start),
+                                                        SkIntToScalar(tile_y_start),
+                                                        SkIntToScalar(current_width),
+                                                        SkIntToScalar(fTileHeight));
                 tile_x_start += current_width;
             }
 
@@ -264,11 +253,7 @@
 }
 
 void TiledPictureRenderer::deleteTiles() {
-    for (int i = 0; i < fTiles.count(); ++i) {
-        SkDELETE(fTiles[i]);
-    }
-
-    fTiles.reset();
+    fTileRects.reset();
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
@@ -317,8 +302,21 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
-void TiledPictureRenderer::drawTiles() {
+void TiledPictureRenderer::render(bool doExtraWorkToDrawToBaseCanvas) {
+    SkASSERT(fPicture != NULL);
+    if (NULL == fPicture) {
+        return;
+    }
+
+    if (doExtraWorkToDrawToBaseCanvas) {
+        if (NULL == fCanvas.get()) {
+            fCanvas.reset(this->setupCanvas());
+        }
+    }
+
     if (fMultiThreaded) {
+        // FIXME: Turning off multi threading while we transition to using a pool of tiles
+/*
         if (fUsePipe) {
             // First, draw into a pipe controller
             SkGPipeWriter writer;
@@ -358,29 +356,36 @@
                 SkDELETE(cloneData[i]);
             }
         }
+ */
     } else {
-        for (int i = 0; i < fTiles.count(); ++i) {
-            fTiles[i]->drawPicture(*(fPicture));
-            fTiles[i]->flush();
+        // For single thread, we really only need one canvas total
+        SkCanvas* canvas = this->setupCanvas(fTileWidth, fTileHeight);
+        SkAutoUnref aur(canvas);
+
+        // Clip the tile to an area that is completely in what the SkPicture says is the
+        // drawn-to area. This is mostly important for tiles on the right and bottom edges
+        // as they may go over this area and the picture may have some commands that
+        // draw outside of this area and so should not actually be written.
+        SkRect clip = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
+                                     SkIntToScalar(fPicture->height()));
+        for (int i = 0; i < fTileRects.count(); ++i) {
+            canvas->resetMatrix();
+            canvas->clipRect(clip);
+            // Translate so that we draw the correct portion of the picture
+            canvas->translate(-fTileRects[i].fLeft, -fTileRects[i].fTop);
+            canvas->drawPicture(*(fPicture));
+            canvas->flush();
+            if (doExtraWorkToDrawToBaseCanvas) {
+                SkASSERT(fCanvas.get() != NULL);
+                SkBitmap source = canvas->getDevice()->accessBitmap(false);
+                fCanvas->drawBitmap(source, fTileRects[i].fLeft, fTileRects[i].fTop);
+                fCanvas->flush();
+            }
         }
     }
 }
 
-void TiledPictureRenderer::copyTilesToCanvas() {
-    for (int i = 0; i < fTiles.count(); ++i) {
-        // Since SkPicture performs a save and restore when being drawn to a
-        // canvas, we can be confident that the transform matrix of the canvas
-        // is what we set when creating the tiles.
-        SkMatrix matrix = fTiles[i]->getTotalMatrix();
-        SkScalar tile_x_start = matrix.getTranslateX();
-        SkScalar tile_y_start = matrix.getTranslateY();
-
-        SkBitmap source = fTiles[i]->getDevice()->accessBitmap(false);
-
-        fCanvas->drawBitmap(source, -tile_x_start, -tile_y_start);
-    }
-    fCanvas->flush();
-}
+///////////////////////////////////////////////////////////////////////////////////////////////
 
 void PlaybackCreationRenderer::setup() {
     SkCanvas* recorder = fReplayer.beginRecording(fPicture->width(), fPicture->height());