Add counting of some GL calls
authorrobertphillips <robertphillips@google.com>
Thu, 18 Sep 2014 20:52:08 +0000 (13:52 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 18 Sep 2014 20:52:08 +0000 (13:52 -0700)
I would like this facility for tracking FBO switch improvements.

R=bsalomon@google.com

Author: robertphillips@google.com

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

14 files changed:
include/gpu/GrConfig.h
include/gpu/GrContext.h
src/gpu/GrContext.cpp
src/gpu/GrGpu.h
src/gpu/gl/GrGpuGL.cpp
src/gpu/gl/GrGpuGL.h
src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp
src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
src/gpu/gl/builders/GrGLShaderStringBuilder.h
src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
tools/PictureBenchmark.h
tools/bench_pictures_main.cpp
tools/render_pictures_main.cpp

index 80897a07bd17c4af4e85edf7d2be3c6a9ee4dc96..86ad63ad6e82fb0947525683a694aa972a2d468a 100644 (file)
     #define GR_CACHE_STATS      0
 #endif
 
+#if !defined(GR_GPU_STATS)
+#define GR_GPU_STATS      0
+#endif
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
index dd15767534500474809bf1fc6ab5d21f6fa1496b..f9c78ffbe3c32cd41c4ed890b839954e7c3263a8 100644 (file)
@@ -960,6 +960,30 @@ public:
     void printCacheStats() const;
 #endif
 
+    class GPUStats {
+    public:
+#if GR_GPU_STATS
+        GPUStats() { this->reset(); }
+
+        void reset() { fRenderTargetBinds = 0; fShaderCompilations = 0; }
+
+        int renderTargetBinds() const { return fRenderTargetBinds; }
+        void incRenderTargetBinds() { fRenderTargetBinds++; }
+        int shaderCompilations() const { return fShaderCompilations; }
+        void incShaderCompilations() { fShaderCompilations++; }
+    private:
+        int fRenderTargetBinds;
+        int fShaderCompilations;
+#else
+        void incRenderTargetBinds() {}
+        void incShaderCompilations() {}
+#endif
+    };
+
+#if GR_GPU_STATS
+    const GPUStats* gpuStats() const;
+#endif
+
 private:
     // Used to indicate whether a draw should be performed immediately or queued in fDrawBuffer.
     enum BufferedDraw {
index e208cddec4c89a83f4291c000223b8b1de718541..eb8455adbbae89355d4521fbbbeb140ede4643f7 100755 (executable)
@@ -1941,3 +1941,10 @@ void GrContext::printCacheStats() const {
     fResourceCache->printStats();
 }
 #endif
+
+#if GR_GPU_STATS
+const GrContext::GPUStats* GrContext::gpuStats() const {
+    return fGpu->gpuStats();
+}
+#endif
+
index 9ceb706db876bb0f743a894dd56a519d444a2faa..54fe471c88c2fceccbed9013337333277d8a4e72 100644 (file)
@@ -327,6 +327,8 @@ public:
         return kDrawPath_DrawType == type || kDrawPaths_DrawType == type;
     }
 
+    GrContext::GPUStats* gpuStats() { return &fGPUStats; }
+
 protected:
     DrawType PrimTypeToDrawType(GrPrimitiveType type) {
         switch (type) {
@@ -364,6 +366,8 @@ protected:
 
     GrClipMaskManager           fClipMaskManager;
 
+    GrContext::GPUStats         fGPUStats;
+
     struct GeometryPoolState {
         const GrVertexBuffer* fPoolVertexBuffer;
         int                   fPoolStartVertex;
index 5d4bd8b7b74f308aa5fbc1e56670884972e622dc..ebc34572fed1f1660e43246f7601edfd47afdc4c 100644 (file)
@@ -870,6 +870,7 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
                                        width, height)) {
             goto FAILED;
         }
+        fGPUStats.incRenderTargetBinds();
         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fRTFBOID));
         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
                                       GR_GL_COLOR_ATTACHMENT0,
@@ -884,6 +885,7 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
             fGLContext.caps()->markConfigAsValidColorAttachment(desc->fConfig);
         }
     }
+    fGPUStats.incRenderTargetBinds();
     GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fTexFBOID));
 
     if (this->glCaps().usesImplicitMSAAResolve() && desc->fSampleCnt > 0) {
@@ -1245,6 +1247,7 @@ bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTar
         GrGLuint rb = glsb->renderbufferID();
 
         fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
+        fGPUStats.incRenderTargetBinds();
         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo));
         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
                                         GR_GL_STENCIL_ATTACHMENT,
@@ -1438,6 +1441,7 @@ void GrGpuGL::discard(GrRenderTarget* renderTarget) {
     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
     if (renderTarget->getUniqueID() != fHWBoundRenderTargetUniqueID) {
         fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
+        fGPUStats.incRenderTargetBinds();
         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, glRT->renderFBOID()));
     }
     switch (this->glCaps().invalidateFBType()) {
@@ -1601,6 +1605,7 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
         case GrGLRenderTarget::kCanResolve_ResolveType:
             this->onResolveRenderTarget(tgt);
             // we don't track the state of the READ FBO ID.
+            fGPUStats.incRenderTargetBinds();
             GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
                                     tgt->textureFBOID()));
             break;
@@ -1698,6 +1703,7 @@ void GrGpuGL::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound)
 
     uint32_t rtID = target->getUniqueID();
     if (fHWBoundRenderTargetUniqueID != rtID) {
+        fGPUStats.incRenderTargetBinds();
         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID()));
 #ifdef SK_DEBUG
         // don't do this check in Chromium -- this is causing
@@ -1800,6 +1806,8 @@ void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
         // Some extensions automatically resolves the texture when it is read.
         if (this->glCaps().usesMSAARenderBuffers()) {
             SkASSERT(rt->textureFBOID() != rt->renderFBOID());
+            fGPUStats.incRenderTargetBinds();
+            fGPUStats.incRenderTargetBinds();
             GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID()));
             GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()));
             // make sure we go through flushRenderTarget() since we've modified
@@ -2363,38 +2371,37 @@ inline bool can_copy_texsubimage(const GrSurface* dst,
     }
 }
 
+}
+
 // If a temporary FBO was created, its non-zero ID is returned. The viewport that the copy rect is
 // relative to is output.
-inline GrGLuint bind_surface_as_fbo(const GrGLInterface* gl,
-                                    GrSurface* surface,
-                                    GrGLenum fboTarget,
-                                    GrGLIRect* viewport) {
+GrGLuint GrGpuGL::bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport) {
     GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarget());
     GrGLuint tempFBOID;
     if (NULL == rt) {
         SkASSERT(surface->asTexture());
         GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textureID();
-        GR_GL_CALL(gl, GenFramebuffers(1, &tempFBOID));
-        GR_GL_CALL(gl, BindFramebuffer(fboTarget, tempFBOID));
-        GR_GL_CALL(gl, FramebufferTexture2D(fboTarget,
-                                            GR_GL_COLOR_ATTACHMENT0,
-                                            GR_GL_TEXTURE_2D,
-                                            texID,
-                                            0));
+        GR_GL_CALL(this->glInterface(), GenFramebuffers(1, &tempFBOID));
+        fGPUStats.incRenderTargetBinds();
+        GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, tempFBOID));
+        GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
+                                                             GR_GL_COLOR_ATTACHMENT0,
+                                                             GR_GL_TEXTURE_2D,
+                                                             texID,
+                                                             0));
         viewport->fLeft = 0;
         viewport->fBottom = 0;
         viewport->fWidth = surface->width();
         viewport->fHeight = surface->height();
     } else {
         tempFBOID = 0;
-        GR_GL_CALL(gl, BindFramebuffer(fboTarget, rt->renderFBOID()));
+        fGPUStats.incRenderTargetBinds();
+        GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBOID()));
         *viewport = rt->getViewport();
     }
     return tempFBOID;
 }
 
-}
-
 void GrGpuGL::initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) {
     // Check for format issues with glCopyTexSubImage2D
     if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInternalFormat() &&
@@ -2432,7 +2439,7 @@ bool GrGpuGL::onCopySurface(GrSurface* dst,
         (!wouldNeedTempFBO || !inheritedCouldCopy)) {
         GrGLuint srcFBO;
         GrGLIRect srcVP;
-        srcFBO = bind_surface_as_fbo(this->glInterface(), src, GR_GL_FRAMEBUFFER, &srcVP);
+        srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP);
         GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture());
         SkASSERT(dstTex);
         // We modified the bound FBO
@@ -2475,8 +2482,8 @@ bool GrGpuGL::onCopySurface(GrSurface* dst,
             GrGLuint srcFBO;
             GrGLIRect dstVP;
             GrGLIRect srcVP;
-            dstFBO = bind_surface_as_fbo(this->glInterface(), dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP);
-            srcFBO = bind_surface_as_fbo(this->glInterface(), src, GR_GL_READ_FRAMEBUFFER, &srcVP);
+            dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP);
+            srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP);
             // We modified the bound FBO
             fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
             GrGLIRect srcGLRect;
index a8130d8099d63b00c72ab7c2b51e173851ff2f6c..06a0e3bf2e0037d45a1fbb7e9c39bd099882ad15 100644 (file)
@@ -150,7 +150,7 @@ private:
                                   bool insideClip) SK_OVERRIDE;
     virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
 
-    // GrDrawTarget ovverides
+    // GrDrawTarget overrides
     virtual void didAddGpuTraceMarker() SK_OVERRIDE;
     virtual void didRemoveGpuTraceMarker() SK_OVERRIDE;
 
@@ -267,6 +267,8 @@ private:
                                    GrGLuint texID,
                                    GrGLRenderTarget::Desc* desc);
 
+    GrGLuint bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport);
+
     GrGLContext fGLContext;
 
     // GL program-related state
index 182ebfb70fa92133851cb93f13f54c9986143b24..730ce04b3e1a7c543b5ee750d2465cb417f9f3d5 100644 (file)
@@ -231,8 +231,9 @@ bool GrGLFragmentShaderBuilder::compileAndAttachShaders(GrGLuint programId,
     fragShaderSrc.append(fCode);
     fragShaderSrc.append("}\n");
 
-    GrGLuint fragShaderId = GrGLCompileAndAttachShader(gpu->glContext(),
-            programId, GR_GL_FRAGMENT_SHADER, fragShaderSrc);
+    GrGLuint fragShaderId = GrGLCompileAndAttachShader(gpu->glContext(), programId,
+                                                       GR_GL_FRAGMENT_SHADER, fragShaderSrc,
+                                                       gpu->gpuStats());
     if (!fragShaderId) {
         return false;
     }
index 6cdf2f93e075f3966259b950af5aafcfc8b99d1d..117497b9ee9f3ebd6cc63b9bb37dd256cbe888bb 100644 (file)
@@ -61,7 +61,9 @@ bool GrGLGeometryShaderBuilder::compileAndAttachShaders(GrGLuint programId,
                          "\tEndPrimitive();\n");
     geomShaderSrc.append("}\n");
     GrGLuint geomShaderId =
-            GrGLCompileAndAttachShader(glCtx, programId, GR_GL_GEOMETRY_SHADER, geomShaderSrc);
+        GrGLCompileAndAttachShader(glCtx, programId,
+                                   GR_GL_GEOMETRY_SHADER, geomShaderSrc,
+                                   fProgramBuilder->gpu()->gpuStats());
     if (!geomShaderId) {
         return false;
     }
index dff8c7e684a919c2c74cb86b09daa3ad2ad48a2a..6406451014fc729f5116a9a113d1e7df92929823 100644 (file)
@@ -20,66 +20,68 @@ SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false,
 GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx,
                                     GrGLuint programId,
                                     GrGLenum type,
-                                    const SkString& shaderSrc) {
+                                    const SkString& shaderSrc,
+                                    GrContext::GPUStats* gpuStats) {
     const GrGLInterface* gli = glCtx.interface();
 
-     GrGLuint shaderId;
-     GR_GL_CALL_RET(gli, shaderId, CreateShader(type));
-     if (0 == shaderId) {
-         return 0;
-     }
+    GrGLuint shaderId;
+    GR_GL_CALL_RET(gli, shaderId, CreateShader(type));
+    if (0 == shaderId) {
+        return 0;
+    }
 
- #ifdef SK_DEBUG
-     SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, false);
-     const GrGLchar* sourceStr = prettySource.c_str();
-     GrGLint sourceLength = static_cast<GrGLint>(prettySource.size());
- #else
-     GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size());
-     const GrGLchar* sourceStr = shaderSrc.c_str();
- #endif
-     GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength));
-     GR_GL_CALL(gli, CompileShader(shaderId));
+#ifdef SK_DEBUG
+    SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, false);
+    const GrGLchar* sourceStr = prettySource.c_str();
+    GrGLint sourceLength = static_cast<GrGLint>(prettySource.size());
+#else
+    GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size());
+    const GrGLchar* sourceStr = shaderSrc.c_str();
+#endif
+    GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength));
+    gpuStats->incShaderCompilations();
+    GR_GL_CALL(gli, CompileShader(shaderId));
 
-     // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds.
-     bool checkCompiled = !glCtx.isChromium();
- #ifdef SK_DEBUG
-     checkCompiled = true;
- #endif
-     if (checkCompiled) {
-         GrGLint compiled = GR_GL_INIT_ZERO;
-         GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled));
+    // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds.
+    bool checkCompiled = !glCtx.isChromium();
+#ifdef SK_DEBUG
+    checkCompiled = true;
+#endif
+    if (checkCompiled) {
+        GrGLint compiled = GR_GL_INIT_ZERO;
+        GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled));
 
-         if (!compiled) {
-             GrGLint infoLen = GR_GL_INIT_ZERO;
-             GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen));
-             SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
-             if (infoLen > 0) {
-                 // retrieve length even though we don't need it to workaround bug in Chromium cmd
-                 // buffer param validation.
-                 GrGLsizei length = GR_GL_INIT_ZERO;
-                 GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1,
-                                                  &length, (char*)log.get()));
-                 GrPrintf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str());
-                 GrPrintf("\n%s", log.get());
-             }
-             SkDEBUGFAIL("Shader compilation failed!");
-             GR_GL_CALL(gli, DeleteShader(shaderId));
-             return 0;
-         }
-     }
+        if (!compiled) {
+            GrGLint infoLen = GR_GL_INIT_ZERO;
+            GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen));
+            SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
+            if (infoLen > 0) {
+                // retrieve length even though we don't need it to workaround bug in Chromium cmd
+                // buffer param validation.
+                GrGLsizei length = GR_GL_INIT_ZERO;
+                GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1,
+                                                 &length, (char*)log.get()));
+                GrPrintf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str());
+                GrPrintf("\n%s", log.get());
+            }
+            SkDEBUGFAIL("Shader compilation failed!");
+            GR_GL_CALL(gli, DeleteShader(shaderId));
+            return 0;
+        }
+    }
 
-     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "skia_gpu::GLShader",
-                          TRACE_EVENT_SCOPE_THREAD, "shader", TRACE_STR_COPY(shaderSrc.c_str()));
-     if (c_PrintShaders) {
-         GrPrintf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str());
-         GrPrintf("\n");
-     }
+    TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "skia_gpu::GLShader",
+                         TRACE_EVENT_SCOPE_THREAD, "shader", TRACE_STR_COPY(shaderSrc.c_str()));
+    if (c_PrintShaders) {
+        GrPrintf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str());
+        GrPrintf("\n");
+    }
 
-     // Attach the shader, but defer deletion until after we have linked the program.
-     // This works around a bug in the Android emulator's GLES2 wrapper which
-     // will immediately delete the shader object and free its memory even though it's
-     // attached to a program, which then causes glLinkProgram to fail.
-     GR_GL_CALL(gli, AttachShader(programId, shaderId));
+    // Attach the shader, but defer deletion until after we have linked the program.
+    // This works around a bug in the Android emulator's GLES2 wrapper which
+    // will immediately delete the shader object and free its memory even though it's
+    // attached to a program, which then causes glLinkProgram to fail.
+    GR_GL_CALL(gli, AttachShader(programId, shaderId));
 
-     return shaderId;
+    return shaderId;
 }
index 8c18fa570a78761e32b69700566d481859a6d468..ab8734f7c6bc5ccebf0a4e92165abc9995fe766b 100644 (file)
@@ -9,12 +9,14 @@
 #define GrGLShaderStringBuilder_DEFINED
 
 #include "GrAllocator.h"
+#include "GrContext.h"
 #include "gl/GrGLContext.h"
 #include "SkTypes.h"
 
 GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx,
                                     GrGLuint programId,
                                     GrGLenum type,
-                                    const SkString& shaderSrc);
+                                    const SkString& shaderSrc,
+                                    GrContext::GPUStats* gpuStats);
 
 #endif
index 9e666ad3da21389483155b20deb3e31c886dfe87..ad614659416dd3fd197f608615b80d6fd75a31b9 100644 (file)
@@ -120,9 +120,10 @@ bool GrGLVertexShaderBuilder::compileAndAttachShaders(GrGLuint programId,
     fProgramBuilder->appendDecls(fOutputs, &vertShaderSrc);
     vertShaderSrc.append("void main() {");
     vertShaderSrc.append(fCode);
-    vertShaderSrc.append("}");
+    vertShaderSrc.append("}\n");
     GrGLuint vertShaderId = GrGLCompileAndAttachShader(glCtx, programId,
-            GR_GL_VERTEX_SHADER, vertShaderSrc);
+                                                       GR_GL_VERTEX_SHADER, vertShaderSrc,
+                                                       gpu->gpuStats());
     if (!vertShaderId) {
         return false;
     }
index 1ddd18ea16358634a19c31fd625983402d976082..2b1ccb5383daf7104e82790468a2e7ceb25bd628 100644 (file)
@@ -49,6 +49,7 @@ public:
     bool preprocess() const { return fPreprocess; }
 
     PictureRenderer* setRenderer(PictureRenderer*);
+    PictureRenderer* renderer() { return fRenderer; }
 
     void setTimerResultType(TimerData::Result resultType) { fTimerResult = resultType; }
 
index 2eda73c40fa245a2197b00ef689d75f72267add4..ade93fc3e6f05108df5aa8695818d41b929269cf 100644 (file)
@@ -54,6 +54,11 @@ DEFINE_bool(trackDeferredCaching, false, "Only meaningful with --deferImageDecod
             "SK_LAZY_CACHE_STATS set to true. Report percentage of cache hits when using "
             "deferred image decoding.");
 
+#if GR_GPU_STATS
+DEFINE_bool(gpuStats, false, "Only meaningful with gpu configurations. "
+            "Report some GPU call statistics.");
+#endif
+
 DEFINE_bool(preprocess, false, "If true, perform device specific preprocessing before timing.");
 
 // Buildbot-specific parameters
@@ -476,6 +481,15 @@ int tool_main(int argc, char** argv) {
                  (double) gTotalCacheHits / (gTotalCacheHits + gTotalCacheMisses));
     }
 #endif
+
+#if GR_GPU_STATS
+    if (FLAGS_gpuStats && benchmark.renderer()->isUsingGpuDevice()) {
+        GrContext* ctx = benchmark.renderer()->getGrContext();
+        SkDebugf("RenderTarget Binds: %d\n", ctx->gpuStats()->renderTargetBinds());
+        SkDebugf("Shader Compilations: %d\n", ctx->gpuStats()->shaderCompilations());
+    }
+#endif
+
     gWriter.end();
     return 0;
 }
index 4fb83521c8c3e05e6661463aaf2d9172430dcf78..d7a213cb47e74650db2885c7c75b96b3c04205a9 100644 (file)
@@ -36,6 +36,10 @@ DEFINE_int32(maxComponentDiff, 256, "Maximum diff on a component, 0 - 256. Compo
              "Requires --validate.");
 DEFINE_string(mismatchPath, "", "Write images for tests that failed due to "
               "pixel mismatches into this directory.");
+#if GR_GPU_STATS
+DEFINE_bool(gpuStats, false, "Only meaningful with gpu configurations. "
+            "Report some GPU call statistics.");
+#endif
 DEFINE_bool(preprocess, false, "If true, perform device specific preprocessing before rendering.");
 DEFINE_string(readJsonSummaryPath, "", "JSON file to read image expectations from.");
 DECLARE_string(readPath);
@@ -496,6 +500,13 @@ int tool_main(int argc, char** argv) {
 #endif
     }
 #endif
+#if GR_GPU_STATS
+    if (FLAGS_gpuStats && renderer->isUsingGpuDevice()) {
+        GrContext* ctx = renderer->getGrContext();
+        SkDebugf("RenderTarget Binds: %d\n", ctx->gpuStats()->renderTargetBinds());
+        SkDebugf("Shader Compilations: %d\n", ctx->gpuStats()->shaderCompilations());
+    }
+#endif
 #endif
     if (FLAGS_writeJsonSummaryPath.count() == 1) {
         // If there were any descriptions on the command line, insert them now.