Add MSAA configs to bench.
Review URL: https://codereview.chromium.org/12607013

git-svn-id: http://skia.googlecode.com/svn/trunk@8217 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp
index 1d31cdb..4bc56c4 100644
--- a/bench/benchmain.cpp
+++ b/bench/benchmain.cpp
@@ -193,7 +193,7 @@
 };
 
 static SkDevice* make_device(SkBitmap::Config config, const SkIPoint& size,
-                             Backend backend, GrContext* context) {
+                             Backend backend, int sampleCount, GrContext* context) {
     SkDevice* device = NULL;
     SkBitmap bitmap;
     bitmap.setConfig(config, size.fX, size.fY);
@@ -211,6 +211,7 @@
             desc.fFlags = kRenderTarget_GrTextureFlagBit;
             desc.fWidth = size.fX;
             desc.fHeight = size.fY;
+            desc.fSampleCnt = sampleCount;
             SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0));
             if (!texture) {
                 return NULL;
@@ -238,21 +239,25 @@
 static const struct {
     SkBitmap::Config    fConfig;
     const char*         fName;
+    int                 fSampleCnt;
     Backend             fBackend;
     GLContextType       fContextType;
+    bool                fRunByDefault;
 } gConfigs[] = {
-    { SkBitmap::kNo_Config,         "NONRENDERING",    kNonRendering_Backend, kDontCareGLCtxType },
-    { SkBitmap::kARGB_8888_Config,  "8888",            kRaster_Backend, kDontCareGLCtxType },
-    { SkBitmap::kRGB_565_Config,    "565",             kRaster_Backend, kDontCareGLCtxType },
+    { SkBitmap::kNo_Config,         "NONRENDERING", 0, kNonRendering_Backend, kDontCareGLCtxType,                      true     },
+    { SkBitmap::kARGB_8888_Config,  "8888",         0, kRaster_Backend,       kDontCareGLCtxType,                      true     },
+    { SkBitmap::kRGB_565_Config,    "565",          0, kRaster_Backend,       kDontCareGLCtxType,                      true     },
 #if SK_SUPPORT_GPU
-    { SkBitmap::kARGB_8888_Config,  "GPU",             kGPU_Backend, GrContextFactory::kNative_GLContextType },
+    { SkBitmap::kARGB_8888_Config,  "GPU",          0, kGPU_Backend,          GrContextFactory::kNative_GLContextType, true     },
+    { SkBitmap::kARGB_8888_Config,  "MSAA4",        4, kGPU_Backend,          GrContextFactory::kNative_GLContextType, false    },
+    { SkBitmap::kARGB_8888_Config,  "MSAA16",      16, kGPU_Backend,          GrContextFactory::kNative_GLContextType, false    },
 #if SK_ANGLE
-    { SkBitmap::kARGB_8888_Config,  "ANGLE",           kGPU_Backend, GrContextFactory::kANGLE_GLContextType },
+    { SkBitmap::kARGB_8888_Config,  "ANGLE",        0, kGPU_Backend,          GrContextFactory::kANGLE_GLContextType,  true     },
 #endif // SK_ANGLE
 #ifdef SK_DEBUG
-    { SkBitmap::kARGB_8888_Config,  "Debug",           kGPU_Backend, GrContextFactory::kDebug_GLContextType },
+    { SkBitmap::kARGB_8888_Config,  "Debug",        0, kGPU_Backend,          GrContextFactory::kDebug_GLContextType,  GR_DEBUG },
 #endif // SK_DEBUG
-    { SkBitmap::kARGB_8888_Config,  "NULLGPU",         kGPU_Backend, GrContextFactory::kNull_GLContextType },
+    { SkBitmap::kARGB_8888_Config,  "NULLGPU",      0, kGPU_Backend,          GrContextFactory::kNull_GLContextType,   true     },
 #endif // SK_SUPPORT_GPU
 };
 
@@ -280,6 +285,12 @@
 }
 
 static void help() {
+    SkString configsStr;
+    static const size_t kConfigCount = SK_ARRAY_COUNT(gConfigs);
+    for (size_t i = 0; i < kConfigCount; ++i) {
+        configsStr.appendf("%s%s", gConfigs[i].fName, ((i == kConfigCount - 1) ? "" : "|"));
+    }
+
     SkDebugf("Usage: bench [-o outDir] [--repeat nr] [--logPerIter] "
                           "[--timers [wcgWC]*] [--rotate]\n"
              "    [--scale] [--clip] [--min] [--forceAA 1|0] [--forceFilter 1|0]\n"
@@ -290,8 +301,9 @@
              "\n"
              "    [--strokeWidth width] [--match name]\n"
              "    [--mode normal|deferred|deferredSilent|record|picturerecord]\n"
-             "    [--config 8888|565|GPU|ANGLE|NULLGPU] [-Dfoo bar] [--logFile filename]\n"
-             "    [-h|--help]");
+             "    [--config ");
+    SkDebugf("%s]\n", configsStr.c_str());
+    SkDebugf("    [-Dfoo bar] [--logFile filename] [-h|--help]");
     SkDebugf("\n\n");
     SkDebugf("    -o outDir : Image of each bench will be put in outDir.\n");
     SkDebugf("    --repeat nr : Each bench repeats for nr times.\n");
@@ -327,12 +339,8 @@
              "                 picturerecord, Benchmark the time to do record from a \n"
              "                                SkPicture to a SkPicture.\n");
     SkDebugf("    --logFile filename : destination for writing log output, in addition to stdout.\n");
-    SkDebugf("    --config ");
-    static const size_t kConfigCount = SK_ARRAY_COUNT(gConfigs);
-    for (size_t i = 0; i < kConfigCount; ++i) {
-        SkDebugf("%s%s", gConfigs[i].fName, ((i == kConfigCount - 1) ? "" : "|"));
-    }
-    SkDebugf(" :  Run bench in corresponding config mode.\n");
+    SkDebugf("    --config %s:\n", configsStr.c_str());
+    SkDebugf("             Run bench in corresponding config mode.\n");
     SkDebugf("    -Dfoo bar : Add extra definition to bench.\n");
     SkDebugf("    -h|--help : Show this help message.\n");
 }
@@ -379,6 +387,7 @@
     SkBitmap::Config outConfig = SkBitmap::kNo_Config;
     const char* configName = "";
     Backend backend = kRaster_Backend;  // for warning
+    int sampleCount = 0;
     SkTDArray<int> configs;
     bool userConfig = false;
 
@@ -588,9 +597,11 @@
         normalTimeFormat.set("%6.4f");
     }
     if (!userConfig) {
-        // if no config is specified by user, we add them all.
+        // if no config is specified by user, add the default configs
         for (unsigned int i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
-            *configs.append() = i;
+            if (gConfigs[i].fRunByDefault) {
+                *configs.append() = i;
+            }
         }
     }
     if (kNormal_benchModes != benchMode) {
@@ -604,6 +615,35 @@
         }
     }
 
+#if SK_SUPPORT_GPU
+    for (int i = 0; i < configs.count(); ++i) {
+        int configIdx = configs[i];
+
+        if (kGPU_Backend == gConfigs[configIdx].fBackend && gConfigs[configIdx].fSampleCnt > 0) {
+            GrContext* context = gContextFactory.get(gConfigs[configIdx].fContextType);
+            if (NULL == context) {
+                SkString error;
+                error.printf("Error creating GrContext for config %s. Config will be skipped.\n",
+                             gConfigs[configIdx].fName);
+                logger.logError(error.c_str());
+                configs.remove(i);
+                --i;
+                continue;
+            }
+            if (gConfigs[configIdx].fSampleCnt > context->getMaxSampleCount()){
+                SkString error;
+                error.printf("Sample count (%d) for config %s is unsupported. "
+                             "Config will be skipped.\n",
+                             gConfigs[configIdx].fSampleCnt, gConfigs[configIdx].fName);
+                logger.logError(error.c_str());
+                configs.remove(i);
+                --i;
+                continue;
+            }
+        }
+    }
+#endif
+
     // report our current settings
     {
         SkString str;
@@ -728,6 +768,7 @@
             outConfig = gConfigs[configIndex].fConfig;
             configName = gConfigs[configIndex].fName;
             backend = gConfigs[configIndex].fBackend;
+            sampleCount = gConfigs[configIndex].fSampleCnt;
             GrContext* context = NULL;
             BenchTimer* timer = timers[configIndex];
 
@@ -747,7 +788,7 @@
             SkPicture pictureRecordTo;
 
             if (kNonRendering_Backend != backend) {
-                device = make_device(outConfig, dim, backend, context);
+                device = make_device(outConfig, dim, backend, sampleCount, context);
 
                 switch(benchMode) {
                     case kDeferredSilent_benchModes:
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index ac61ea8..c5572ac 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -251,12 +251,6 @@
      */
     int getMaxTextureSize() const;
 
-    /**
-     * Return the max width or height of a render target supported by the
-     * current GPU.
-     */
-    int getMaxRenderTargetSize() const;
-
     ///////////////////////////////////////////////////////////////////////////
     // Render targets
 
@@ -280,6 +274,18 @@
      */
     bool isConfigRenderable(GrPixelConfig config) const;
 
+    /**
+     * Return the max width or height of a render target supported by the
+     * current GPU.
+     */
+    int getMaxRenderTargetSize() const;
+
+    /**
+     * Returns the max sample count for a render target. It will be 0 if MSAA
+     * is not supported.
+     */
+    int getMaxSampleCount() const;
+
     ///////////////////////////////////////////////////////////////////////////
     // Backend Surfaces
 
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 271923a..b719ec5 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -549,6 +549,10 @@
     return fGpu->getCaps().maxRenderTargetSize();
 }
 
+int GrContext::getMaxSampleCount() const {
+    return fGpu->getCaps().maxSampleCount();
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 GrTexture* GrContext::wrapBackendTexture(const GrBackendTextureDesc& desc) {
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 965b1b6..a011aae 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -45,8 +45,10 @@
         bool fDualSourceBlendingSupport : 1;
         bool fBufferLockSupport         : 1;
         bool fPathStencilingSupport     : 1;
+
         int fMaxRenderTargetSize;
         int fMaxTextureSize;
+        int fMaxSampleCount;
     };
 
     class DrawInfo;
@@ -81,6 +83,8 @@
 
         int maxRenderTargetSize() const { return fInternals.fMaxRenderTargetSize; }
         int maxTextureSize() const { return fInternals.fMaxTextureSize; }
+        // Will be 0 if MSAA is not supported
+        int maxSampleCount() const { return fInternals.fMaxSampleCount; }
     private:
         CapsInternals fInternals;
         friend class GrDrawTarget; // to set values of fInternals
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 82b042f..04c2c3c 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -19,7 +19,6 @@
     fStencilFormats.reset();
     fStencilVerifiedColorConfigs.reset();
     fMSFBOType = kNone_MSFBOType;
-    fMaxSampleCount = 0;
     fCoverageAAType = kNone_CoverageAAType;
     fMaxFragmentUniformVectors = 0;
     fMaxVertexAttributes = 0;
@@ -53,7 +52,6 @@
     fMaxFragmentUniformVectors = caps.fMaxFragmentUniformVectors;
     fMaxVertexAttributes = caps.fMaxVertexAttributes;
     fMSFBOType = caps.fMSFBOType;
-    fMaxSampleCount = caps.fMaxSampleCount;
     fCoverageAAType = caps.fCoverageAAType;
     fMSAACoverageModes = caps.fMSAACoverageModes;
     fRGBA8RenderbufferSupport = caps.fRGBA8RenderbufferSupport;
@@ -284,13 +282,9 @@
                     SkCastForQSort(coverage_mode_compare));
         }
     }
-    if (kNone_MSFBOType != fMSFBOType) {
-        GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxSampleCount);
-    }
 }
 
-const GrGLCaps::MSAACoverageMode& GrGLCaps::getMSAACoverageMode(
-                                            int desiredSampleCount) const {
+const GrGLCaps::MSAACoverageMode& GrGLCaps::getMSAACoverageMode(int desiredSampleCount) const {
     static const MSAACoverageMode kNoneMode = {0, 0};
     if (0 == fMSAACoverageModes.count()) {
         return kNoneMode;
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 9168956..2ecfb85 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -138,11 +138,6 @@
     MSFBOType msFBOType() const { return fMSFBOType; }
 
     /**
-     * Reports the maximum number of samples supported.
-     */
-    int maxSampleCount() const { return fMaxSampleCount; }
-
-    /**
      * Reports the type of coverage sample AA support.
      */
     CoverageAAType coverageAAType() const { return fCoverageAAType; }
@@ -289,7 +284,6 @@
     int fMaxVertexAttributes;
 
     MSFBOType fMSFBOType;
-    int fMaxSampleCount;
     CoverageAAType fCoverageAAType;
     SkTDArray<MSAACoverageMode> fMSAACoverageModes;
 
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 343cae3..33e3d61 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -278,18 +278,20 @@
 
     // Enable supported shader-related caps
     if (kDesktop_GrGLBinding == this->glBinding()) {
-        caps->fDualSourceBlendingSupport =
-                            this->glVersion() >= GR_GL_VER(3,3) ||
-                            this->hasExtension("GL_ARB_blend_func_extended");
+        caps->fDualSourceBlendingSupport = this->glVersion() >= GR_GL_VER(3,3) ||
+                                           this->hasExtension("GL_ARB_blend_func_extended");
         caps->fShaderDerivativeSupport = true;
         // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
-        caps->fGeometryShaderSupport =
-                                this->glVersion() >= GR_GL_VER(3,2) &&
-                                this->glslGeneration() >= k150_GrGLSLGeneration;
+        caps->fGeometryShaderSupport = this->glVersion() >= GR_GL_VER(3,2) &&
+                                       this->glslGeneration() >= k150_GrGLSLGeneration;
     } else {
         caps->fShaderDerivativeSupport =
                             this->hasExtension("GL_OES_standard_derivatives");
     }
+
+    if (GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType()) {
+        GR_GL_GetIntegerv(this->glInterface(), GR_GL_MAX_SAMPLES, &caps->fMaxSampleCount);
+    }
 }
 
 void GrGpuGL::fillInConfigRenderableTable() {
@@ -316,8 +318,7 @@
     //  color renderable: RGBA4, RGB5_A1, RGB565
     //  GL_EXT_texture_rg adds support for R8 as a color render target
     //  GL_OES_rgb8_rgba8 and/or GL_ARM_rgba8 adds support for RGBA8
-    //  GL_EXT_texture_format_BGRA8888 and/or GL_APPLE_texture_format_BGRA8888
-    //          added BGRA support
+    //  GL_EXT_texture_format_BGRA8888 and/or GL_APPLE_texture_format_BGRA8888 added BGRA support
 
     if (kDesktop_GrGLBinding == this->glBinding()) {
         // Post 3.0 we will get R8
@@ -849,8 +850,6 @@
         created = (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctx.interface()));
     }
     if (!created) {
-        // glRBMS will fail if requested samples is > max samples.
-        sampleCount = GrMin(sampleCount, ctx.info().caps().maxSampleCount());
         GL_ALLOC_CALL(ctx.interface(),
                       RenderbufferStorageMultisample(GR_GL_RENDERBUFFER,
                                                      sampleCount,
@@ -976,12 +975,18 @@
 
     // Attempt to catch un- or wrongly initialized sample counts;
     GrAssert(desc.fSampleCnt >= 0 && desc.fSampleCnt <= 64);
+    // We fail if the MSAA was requested and is not available.
+    if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleCnt) {
+        //GrPrintf("MSAA RT requested but not supported on this platform.");
+        return return_null_texture();
+    }
+    // If the sample count exceeds the max then we clamp it.
+    glTexDesc.fSampleCnt = GrMin(desc.fSampleCnt, this->getCaps().maxSampleCount());
 
     glTexDesc.fFlags  = desc.fFlags;
     glTexDesc.fWidth  = desc.fWidth;
     glTexDesc.fHeight = desc.fHeight;
     glTexDesc.fConfig = desc.fConfig;
-    glTexDesc.fSampleCnt = desc.fSampleCnt;
     glTexDesc.fIsWrapped = false;
 
     glRTDesc.fMSColorRenderbufferID = 0;
@@ -997,7 +1002,7 @@
     glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget);
     glRTDesc.fOrigin = glTexDesc.fOrigin;
 
-    glRTDesc.fSampleCnt = desc.fSampleCnt;
+    glRTDesc.fSampleCnt = glTexDesc.fSampleCnt;
     if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() &&
         desc.fSampleCnt) {
         //GrPrintf("MSAA RT requested but not supported on this platform.");