Update bench pictures to time image decode & upload costs

https://codereview.chromium.org/117583002/



git-svn-id: http://skia.googlecode.com/svn/trunk@12742 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tools/PictureBenchmark.cpp b/tools/PictureBenchmark.cpp
index f441c37..65f3660 100644
--- a/tools/PictureBenchmark.cpp
+++ b/tools/PictureBenchmark.cpp
@@ -22,6 +22,7 @@
 , fTimerResult(TimerData::kAvg_Result)
 , fTimerTypes(0)
 , fTimeIndividualTiles(false)
+, fPurgeDecodedTex(false)
 {}
 
 PictureBenchmark::~PictureBenchmark() {
@@ -79,6 +80,10 @@
     fRenderer->render(NULL);
     fRenderer->resetState(true);
 
+    if (fPurgeDecodedTex) {
+        fRenderer->purgeTextures();
+    }
+
     bool usingGpu = false;
 #if SK_SUPPORT_GPU
     usingGpu = fRenderer->isUsingGpuDevice();
@@ -140,6 +145,10 @@
                 tiledRenderer->resetState(false);
                 perTileTimer->end();
                 SkAssertResult(perTileTimerData.appendTimes(perTileTimer.get()));
+
+                if (fPurgeDecodedTex) {
+                    fRenderer->purgeTextures();
+                }
             }
             longRunningTimer->truncatedEnd();
             tiledRenderer->resetState(true);
@@ -160,7 +169,9 @@
 #if 0
             this->logProgress(result.c_str());
 #endif
-
+            if (fPurgeDecodedTex) {
+                configName.append(" <withPurging>");
+            }
             configName.append(" <averaged>");
             SkString longRunningResult = longRunningTimerData.getResult(
                 tiledRenderer->getNormalTimeFormat().c_str(),
@@ -186,6 +197,10 @@
             perRunTimer->end();
 
             SkAssertResult(perRunTimerData.appendTimes(perRunTimer.get()));
+
+            if (fPurgeDecodedTex) {
+                fRenderer->purgeTextures();
+            }
         }
         longRunningTimer->truncatedEnd();
         fRenderer->resetState(true);
@@ -193,6 +208,9 @@
         SkAssertResult(longRunningTimerData.appendTimes(longRunningTimer.get()));
 
         SkString configName = fRenderer->getConfigName();
+        if (fPurgeDecodedTex) {
+            configName.append(" <withPurging>");
+        }
 
         // Beware - since the per-run-timer doesn't ever include a glFinish it can
         // report a lower time then the long-running-timer
diff --git a/tools/PictureBenchmark.h b/tools/PictureBenchmark.h
index 1f01ce5..e9d9f65 100644
--- a/tools/PictureBenchmark.h
+++ b/tools/PictureBenchmark.h
@@ -41,8 +41,10 @@
      * TiledPictureRenderer.
      */
     void setTimeIndividualTiles(bool indiv) { fTimeIndividualTiles = indiv; }
+    bool timeIndividualTiles() const { return fTimeIndividualTiles; }
 
-    bool timeIndividualTiles() { return fTimeIndividualTiles; }
+    void setPurgeDecodedTex(bool purgeDecodedTex) { fPurgeDecodedTex = purgeDecodedTex; }
+    bool purgeDecodedText() const { return fPurgeDecodedTex; }
 
     PictureRenderer* setRenderer(PictureRenderer*);
 
@@ -59,6 +61,7 @@
     TimerData::Result fTimerResult;
     uint32_t          fTimerTypes; // bitfield of TimerData::TimerFlags values
     bool              fTimeIndividualTiles;
+    bool              fPurgeDecodedTex;
 
     void logProgress(const char msg[]);
 
diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp
index 54d4633..4856dd2 100644
--- a/tools/PictureRenderer.cpp
+++ b/tools/PictureRenderer.cpp
@@ -12,6 +12,7 @@
 #include "SkCanvas.h"
 #include "SkData.h"
 #include "SkDevice.h"
+#include "SkDiscardableMemoryPool.h"
 #include "SkGPipe.h"
 #if SK_SUPPORT_GPU
 #include "gl/GrGLDefines.h"
@@ -246,6 +247,25 @@
 #endif
 }
 
+void PictureRenderer::purgeTextures() {
+    SkDiscardableMemoryPool* pool = SkGetGlobalDiscardableMemoryPool();
+
+    pool->dumpPool();
+
+#if SK_SUPPORT_GPU
+    SkGLContextHelper* glContext = this->getGLContext();
+    if (NULL == glContext) {
+        SkASSERT(kBitmap_DeviceType == fDeviceType);
+        return;
+    }
+
+    // resetState should've already done this
+    fGrContext->flush();
+
+    fGrContext->purgeAllUnlockedResources();
+#endif
+}
+
 uint32_t PictureRenderer::recordFlags() {
     return ((kNone_BBoxHierarchyType == fBBoxHierarchyType) ? 0 :
         SkPicture::kOptimizeForClippedPlayback_RecordingFlag) |
diff --git a/tools/PictureRenderer.h b/tools/PictureRenderer.h
index 6d886ab..a22e0b7 100644
--- a/tools/PictureRenderer.h
+++ b/tools/PictureRenderer.h
@@ -148,6 +148,12 @@
     void resetState(bool callFinish);
 
     /**
+     * Remove all decoded textures from the CPU caches and all uploaded textures
+     * from the GPU.
+     */
+    void purgeTextures();
+
+    /**
      * Set the backend type. Returns true on success and false on failure.
      */
     bool setDeviceType(SkDeviceTypes deviceType) {
diff --git a/tools/bench_pictures_main.cpp b/tools/bench_pictures_main.cpp
index 1f3b0c0..5829e18 100644
--- a/tools/bench_pictures_main.cpp
+++ b/tools/bench_pictures_main.cpp
@@ -41,6 +41,8 @@
 DEFINE_int32(repeat, 1, "Set the number of times to repeat each test.");
 DEFINE_bool(timeIndividualTiles, false, "Report times for drawing individual tiles, rather than "
             "times for drawing the whole page. Requires tiled rendering.");
+DEFINE_bool(purgeDecodedTex, false, "Purge decoded and GPU-uploaded textures "
+            "after each iteration.");
 DEFINE_string(timers, "c", "[wcgWC]*: Display wall, cpu, gpu, truncated wall or truncated cpu time"
               " for each picture.");
 DEFINE_bool(trackDeferredCaching, false, "Only meaningful with --deferImageDecoding and "
@@ -338,6 +340,8 @@
         benchmark->setTimeIndividualTiles(true);
     }
 
+    benchmark->setPurgeDecodedTex(FLAGS_purgeDecodedTex);
+
     if (FLAGS_readPath.count() < 1) {
         gLogger.logError(".skp files or directories are required.\n");
         exit(-1);