Cache the results of get_pixel_formats_to_try

Choosing pixel formats is quite slow (depending on driver?). We were
doing this once per context, and it added up. On my desktop windows
machine, this saves another 7 seconds in `dm --config gl --src gm`.

Actual times:
  37s -> 30s (not writing PNGs)
  47s -> 39.5s (writing PNGs)

We always called this with MSAA sample count set to zero, so I cleaned
up the code to make that clearer. Also included a comment about the
theoretical risk, although I think that outside of a multi-GPU system,
we're fine.

Bug: skia:
Change-Id: I50927ebfaf6fe8d88a63674427fbf9e06e4ab059
Reviewed-on: https://skia-review.googlesource.com/35763
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/utils/win/SkWGL.h b/src/utils/win/SkWGL.h
index 315be24..c6c9479 100644
--- a/src/utils/win/SkWGL.h
+++ b/src/utils/win/SkWGL.h
@@ -143,8 +143,8 @@
  */
 class SkWGLPbufferContext : public SkRefCnt {
 public:
-    static SkWGLPbufferContext* Create(HDC parentDC, int msaaSampleCount,
-                                       SkWGLContextRequest contextType, HGLRC shareContext);
+    static SkWGLPbufferContext* Create(HDC parentDC, SkWGLContextRequest contextType,
+                                       HGLRC shareContext);
 
     virtual ~SkWGLPbufferContext();
 
diff --git a/src/utils/win/SkWGL_win.cpp b/src/utils/win/SkWGL_win.cpp
index cc95f49..016b61b 100644
--- a/src/utils/win/SkWGL_win.cpp
+++ b/src/utils/win/SkWGL_win.cpp
@@ -438,8 +438,7 @@
     return create_gl_context(dc, extensions, contextType, shareContext);
 }
 
-SkWGLPbufferContext* SkWGLPbufferContext::Create(HDC parentDC, int msaaSampleCount,
-                                                 SkWGLContextRequest contextType,
+SkWGLPbufferContext* SkWGLPbufferContext::Create(HDC parentDC, SkWGLContextRequest contextType,
                                                  HGLRC shareContext) {
     SkWGLExtensions extensions;
     if (!extensions.hasExtension(parentDC, "WGL_ARB_pixel_format") ||
@@ -447,24 +446,45 @@
         return nullptr;
     }
 
+    // We cache the pixel formats once, and then reuse them. That's possibly incorrect if
+    // there are multiple GPUs, but this function is always called with a freshly made,
+    // identically constructed HDC (see WinGLTestContext).
+    //
+    // We only store two potential pixel formats, one for single buffer, one for double buffer.
+    // We never ask for MSAA, so we don't need the second pixel format for each buffering state.
+    static int gPixelFormats[2] = { -1, -1 };
+    static SkOnce once;
+    once([=] {
+        {
+            // Single buffer
+            int pixelFormatsToTry[2] = { -1, -1 };
+            get_pixel_formats_to_try(parentDC, extensions, false, 0, false, pixelFormatsToTry);
+            gPixelFormats[0] = pixelFormatsToTry[0];
+        }
+        {
+            // Double buffer
+            int pixelFormatsToTry[2] = { -1, -1 };
+            get_pixel_formats_to_try(parentDC, extensions, true, 0, false, pixelFormatsToTry);
+            gPixelFormats[1] = pixelFormatsToTry[0];
+        }
+    });
+
     // try for single buffer first
-    for (int dblBuffer = 0; dblBuffer < 2; ++dblBuffer) {
-        int pixelFormatsToTry[] = { -1, -1 };
-        get_pixel_formats_to_try(parentDC, extensions, (0 != dblBuffer), msaaSampleCount,
-                                 false, pixelFormatsToTry);
-        for (int f = 0; -1 != pixelFormatsToTry[f] && f < SK_ARRAY_COUNT(pixelFormatsToTry); ++f) {
-            HPBUFFER pbuf = extensions.createPbuffer(parentDC, pixelFormatsToTry[f], 1, 1, nullptr);
-            if (0 != pbuf) {
-                HDC dc = extensions.getPbufferDC(pbuf);
-                if (dc) {
-                    HGLRC glrc = create_gl_context(dc, extensions, contextType, shareContext);
-                    if (glrc) {
-                        return new SkWGLPbufferContext(pbuf, dc, glrc);
-                    }
-                    extensions.releasePbufferDC(pbuf, dc);
+    for (int pixelFormat : gPixelFormats) {
+        if (-1 == pixelFormat) {
+            continue;
+        }
+        HPBUFFER pbuf = extensions.createPbuffer(parentDC, pixelFormat, 1, 1, nullptr);
+        if (0 != pbuf) {
+            HDC dc = extensions.getPbufferDC(pbuf);
+            if (dc) {
+                HGLRC glrc = create_gl_context(dc, extensions, contextType, shareContext);
+                if (glrc) {
+                    return new SkWGLPbufferContext(pbuf, dc, glrc);
                 }
-                extensions.destroyPbuffer(pbuf);
+                extensions.releasePbufferDC(pbuf, dc);
             }
+            extensions.destroyPbuffer(pbuf);
         }
     }
     return nullptr;
diff --git a/tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp b/tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp
index 49d7743..0e97153 100644
--- a/tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp
+++ b/tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp
@@ -90,7 +90,7 @@
         winShareContext = shareContext->fPbufferContext ? shareContext->fPbufferContext->getGLRC()
                                                         : shareContext->fGlRenderContext;
     }
-    fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, 0, contextType, winShareContext);
+    fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, contextType, winShareContext);
 
     HDC dc;
     HGLRC glrc;