When performing offscreen rendering on windows, attempt to use a pbuffer context.

A pbuffer context is less likely to have a blocking SwapBuffers (due to vsync).

R=robertphillips@google.com

Author: bsalomon@google.com

Review URL: https://codereview.chromium.org/336863009
diff --git a/src/gpu/gl/win/SkNativeGLContext_win.cpp b/src/gpu/gl/win/SkNativeGLContext_win.cpp
index f085fdc..ab66ba4 100644
--- a/src/gpu/gl/win/SkNativeGLContext_win.cpp
+++ b/src/gpu/gl/win/SkNativeGLContext_win.cpp
@@ -7,7 +7,6 @@
  */
 
 #include "gl/SkNativeGLContext.h"
-#include "SkWGL.h"
 
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -28,7 +27,8 @@
 SkNativeGLContext::SkNativeGLContext()
     : fWindow(NULL)
     , fDeviceContext(NULL)
-    , fGlRenderContext(0) {
+    , fGlRenderContext(0)
+    , fPbufferContext(NULL) {
 }
 
 SkNativeGLContext::~SkNativeGLContext() {
@@ -36,14 +36,18 @@
 }
 
 void SkNativeGLContext::destroyGLContext() {
+    SkSafeSetNull(fPbufferContext);
     if (fGlRenderContext) {
         wglDeleteContext(fGlRenderContext);
+        fGlRenderContext = 0;
     }
     if (fWindow && fDeviceContext) {
         ReleaseDC(fWindow, fDeviceContext);
+        fDeviceContext = 0;
     }
     if (fWindow) {
         DestroyWindow(fWindow);
+        fWindow = 0;
     }
 }
 
@@ -91,17 +95,35 @@
         kGLES_GrGLStandard == forcedGpuAPI ?
         kGLES_SkWGLContextRequest : kGLPreferCompatibilityProfile_SkWGLContextRequest;
 
-    if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, contextType))) {
-        SkDebugf("Could not create rendering context.\n");
-        this->destroyGLContext();
-        return NULL;
+    fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, 0, contextType);
+
+    HDC dc;
+    HGLRC glrc;
+
+    if (NULL == fPbufferContext) {
+        if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, contextType))) {
+            SkDebugf("Could not create rendering context.\n");
+            this->destroyGLContext();
+            return NULL;
+        }
+        dc = fDeviceContext;
+        glrc = fGlRenderContext;
+    } else {
+        ReleaseDC(fWindow, fDeviceContext);
+        fDeviceContext = 0;
+        DestroyWindow(fWindow);
+        fWindow = 0;
+
+        dc = fPbufferContext->getDC();
+        glrc = fPbufferContext->getGLRC();
     }
 
-    if (!(wglMakeCurrent(fDeviceContext, fGlRenderContext))) {
+    if (!(wglMakeCurrent(dc, glrc))) {
         SkDebugf("Could not set the context.\n");
         this->destroyGLContext();
         return NULL;
     }
+
     const GrGLInterface* interface = GrGLCreateNativeInterface();
     if (NULL == interface) {
         SkDebugf("Could not create GL interface.\n");
@@ -113,13 +135,31 @@
 }
 
 void SkNativeGLContext::makeCurrent() const {
-    if (!wglMakeCurrent(fDeviceContext, fGlRenderContext)) {
+    HDC dc;
+    HGLRC glrc;
+
+    if (NULL == fPbufferContext) {
+        dc = fDeviceContext;
+        glrc = fGlRenderContext;
+    } else {
+        dc = fPbufferContext->getDC();
+        glrc = fPbufferContext->getGLRC();
+    }
+
+    if (!wglMakeCurrent(dc, glrc)) {
         SkDebugf("Could not create rendering context.\n");
     }
 }
 
 void SkNativeGLContext::swapBuffers() const {
-    if (!SwapBuffers(fDeviceContext)) {
+    HDC dc;
+
+    if (NULL == fPbufferContext) {
+        dc = fDeviceContext;
+    } else {
+        dc = fPbufferContext->getDC();
+    }
+    if (!SwapBuffers(dc)) {
         SkDebugf("Could not complete SwapBuffers.\n");
     }
 }