Virtualize SkGLContext with subclasses SkNativeGLContext and SkMesaGLContext, allow both in gm
Review URL: http://codereview.appspot.com/5307045/



git-svn-id: http://skia.googlecode.com/svn/trunk@2499 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrGLCreateNativeInterface_none.cpp b/src/gpu/GrGLCreateNativeInterface_none.cpp
new file mode 100644
index 0000000..7de5912
--- /dev/null
+++ b/src/gpu/GrGLCreateNativeInterface_none.cpp
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLInterface.h"
+
+const GrGLInterface* GrGLCreateNativeInterface() {
+    return NULL;
+}
diff --git a/src/gpu/GrGLDefaultInterface_native.cpp b/src/gpu/GrGLDefaultInterface_native.cpp
new file mode 100644
index 0000000..7b8b84a
--- /dev/null
+++ b/src/gpu/GrGLDefaultInterface_native.cpp
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLInterface.h"
+
+const GrGLInterface* GrGLDefaultInterface() {
+    return GrGLCreateNativeInterface();
+}
diff --git a/src/gpu/GrGLInterface.cpp b/src/gpu/GrGLInterface.cpp
index 70dd019..db57947 100644
--- a/src/gpu/GrGLInterface.cpp
+++ b/src/gpu/GrGLInterface.cpp
@@ -345,6 +345,8 @@
         NULL == fCheckFramebufferStatus ||
         NULL == fDeleteFramebuffers ||
         NULL == fDeleteRenderbuffers ||
+        NULL == fFinish ||
+        NULL == fFlush ||
         NULL == fFramebufferRenderbuffer ||
         NULL == fFramebufferTexture2D ||
         NULL == fGetFramebufferAttachmentParameteriv ||
@@ -417,6 +419,32 @@
                 return false;
             }
         }
+        if (glVer >= GR_GL_VER(1,5) ||
+            GrGLHasExtensionFromString("GL_ARB_occlusion_query", ext)) {
+            if (NULL == fGenQueries ||
+                NULL == fDeleteQueries ||
+                NULL == fBeginQuery ||
+                NULL == fEndQuery ||
+                NULL == fGetQueryiv ||
+                NULL == fGetQueryObjectiv ||
+                NULL == fGetQueryObjectuiv) {
+                return false;
+            }
+        }
+        if (glVer >= GR_GL_VER(3,3) ||
+            GrGLHasExtensionFromString("GL_ARB_timer_query", ext) ||
+            GrGLHasExtensionFromString("GL_EXT_timer_query", ext)) {
+            if (NULL == fGetQueryObjecti64v ||
+                NULL == fGetQueryObjectui64v) {
+                return false;
+            }
+        }
+        if (glVer >= GR_GL_VER(3,3) ||
+            GrGLHasExtensionFromString("GL_ARB_timer_query", ext)) {
+            if (NULL == fQueryCounter) {
+                return false;
+            }
+        }
     }
 
     // optional function on desktop before 1.3
diff --git a/src/gpu/GrGLProgram.cpp b/src/gpu/GrGLProgram.cpp
index e05b6c3..26ada9c 100644
--- a/src/gpu/GrGLProgram.cpp
+++ b/src/gpu/GrGLProgram.cpp
@@ -363,13 +363,13 @@
 const char* glsl_version_string(const GrGLInterface* gl,
                                 GrGLProgram::GLSLVersion v) {
     switch (v) {
-        case GrGLProgram::k120_GLSLVersion:
+        case GrGLProgram::k110_GLSLVersion:
             if (gl->supportsES()) {
                 // ES2s shader language is based on version 1.20 but is version
                 // 1.00 of the ES language.
                 return "#version 100\n";
             } else {
-                return "#version 120\n";
+                return "#version 110\n";
             }
         case GrGLProgram::k130_GLSLVersion:
             GrAssert(!gl->supportsES());
@@ -524,7 +524,7 @@
                                   VarArray* fsOutputs,
                                   const char** name) {
     switch (v) {
-        case GrGLProgram::k120_GLSLVersion:
+        case GrGLProgram::k110_GLSLVersion:
             *name = "gl_FragColor";
             return false;
             break;
@@ -977,10 +977,10 @@
 
     static const char* gVaryingPrefixes[2][2] = {{"varying", "varying"},
                                                  {"out", "in"}};
-    const char** varyingPrefixes = k120_GLSLVersion == glslVersion ?
+    const char** varyingPrefixes = k110_GLSLVersion == glslVersion ?
                                                     gVaryingPrefixes[0] :
                                                     gVaryingPrefixes[1];
-    const char* attributePrefix = k120_GLSLVersion == glslVersion ?
+    const char* attributePrefix = k110_GLSLVersion == glslVersion ?
                                                     "attribute" :
                                                     "in";
 
@@ -1031,8 +1031,8 @@
     append_string(precisionStr, &strs, &lengths);
     append_decls(segments.fFSUnis, gl, "uniform", &strs, &lengths, &temps);
     append_decls(segments.fFSInputs, gl, varyingPrefixes[1], &strs, &lengths, &temps);
-    // We shouldn't have declared outputs on 1.2
-    GrAssert(k120_GLSLVersion != glslVersion || segments.fFSOutputs.empty());
+    // We shouldn't have declared outputs on 1.10
+    GrAssert(k110_GLSLVersion != glslVersion || segments.fFSOutputs.empty());
     append_decls(segments.fFSOutputs, gl, "out", &strs, &lengths, &temps);
     append_string(segments.fFSFunctions, &strs, &lengths);
     append_string(segments.fFSCode, &strs, &lengths);
diff --git a/src/gpu/GrGLProgram.h b/src/gpu/GrGLProgram.h
index 678a56d..e0ae4eb 100644
--- a/src/gpu/GrGLProgram.h
+++ b/src/gpu/GrGLProgram.h
@@ -35,10 +35,21 @@
  */
 class GrGLProgram {
 public:
+    // Limited set of GLSL versions we build shaders for. Caller should round
+    // down the GLSL version to one of these enums.
     enum GLSLVersion {
-        k120_GLSLVersion, // Desktop GLSL 1.20 and ES2 shading lang
-        k130_GLSLVersion, // Desktop GLSL 1.30
-        k150_GLSLVersion  // Dekstop GLSL 1.50
+        /**
+         * Desktop GLSL 1.10 and ES2 shading lang (based on desktop GLSL 1.20)
+         */
+        k110_GLSLVersion,
+        /**
+         * Desktop GLSL 1.30
+         */
+        k130_GLSLVersion,
+        /**
+         * Dekstop GLSL 1.50
+         */
+        k150_GLSLVersion,
     };
 
     class CachedData;
diff --git a/src/gpu/GrGpuGLShaders.cpp b/src/gpu/GrGpuGLShaders.cpp
index 71444da..0742c3b 100644
--- a/src/gpu/GrGpuGLShaders.cpp
+++ b/src/gpu/GrGpuGLShaders.cpp
@@ -149,22 +149,22 @@
     GrGLSLVersion ver = GrGLGetGLSLVersion(gl);
     switch (binding) {
         case kDesktop_GrGLBinding:
-            GrAssert(ver >= GR_GLSL_VER(1,20));
+            GrAssert(ver >= GR_GLSL_VER(1,10));
             if (ver >= GR_GLSL_VER(1,50)) {
                 return GrGLProgram::k150_GLSLVersion;
             } else if (ver >= GR_GLSL_VER(1,30)) {
                 return GrGLProgram::k130_GLSLVersion;
             } else {
-                return GrGLProgram::k120_GLSLVersion;
+                return GrGLProgram::k110_GLSLVersion;
             }
         case kES2_GrGLBinding:
             // version 1.00 of ES GLSL based on ver 1.20 of desktop GLSL
             GrAssert(ver >= GR_GL_VER(1,00));
-            return GrGLProgram::k120_GLSLVersion;
+            return GrGLProgram::k110_GLSLVersion;
         default:
             GrCrash("Attempting to get GLSL version in unknown or fixed-"
                      "function GL binding.");
-            return GrGLProgram::k120_GLSLVersion; // suppress warning
+            return GrGLProgram::k110_GLSLVersion; // suppress warning
     }
 }
 
diff --git a/src/gpu/SkGLContext.cpp b/src/gpu/SkGLContext.cpp
new file mode 100644
index 0000000..c50ee6e
--- /dev/null
+++ b/src/gpu/SkGLContext.cpp
@@ -0,0 +1,70 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkGLContext.h"
+
+SkGLContext::SkGLContext()
+    : fFBO(0)
+    , fGL(NULL) {
+}
+
+SkGLContext::~SkGLContext() {
+    SkSafeUnref(fGL);
+}
+
+bool SkGLContext::init(int width, int height) {
+    if (fGL) {
+        fGL->unref();
+        this->destroyGLContext();
+    }
+
+    fGL = this->createGLContext();
+    if (fGL) {
+        GrGLuint cbID;
+        GrGLuint dsID;
+        SK_GL(*this, GenFramebuffers(1, &fFBO));
+        SK_GL(*this, BindFramebuffer(GR_GL_FRAMEBUFFER, fFBO));
+        SK_GL(*this, GenRenderbuffers(1, &cbID));
+        SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, cbID));
+        SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
+                                         GR_GL_RGBA,
+                                         width, height));
+        SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
+                                             GR_GL_COLOR_ATTACHMENT0,
+                                             GR_GL_RENDERBUFFER, 
+                                             cbID));
+        SK_GL(*this, GenRenderbuffers(1, &dsID));
+        SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, dsID));
+        SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
+                                         GR_GL_DEPTH_STENCIL,
+                                         width, height));
+        SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
+                                             GR_GL_DEPTH_ATTACHMENT,
+                                             GR_GL_RENDERBUFFER,
+                                             dsID));
+        SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
+                                             GR_GL_STENCIL_ATTACHMENT,
+                                             GR_GL_RENDERBUFFER,
+                                             dsID));
+        SK_GL(*this, Viewport(0, 0, width, height));
+        SK_GL(*this, ClearStencil(0));
+        SK_GL(*this, Clear(GR_GL_STENCIL_BUFFER_BIT));
+
+        GrGLenum status =
+            SK_GL(*this, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
+        if (GR_GL_FRAMEBUFFER_COMPLETE != status) {
+            fFBO = 0;
+            fGL->unref();
+            fGL = NULL;
+            this->destroyGLContext();
+            return false;
+        } else {
+            return true;
+        }
+    }
+    return false;
+}
diff --git a/src/gpu/SkGLContext_none.cpp b/src/gpu/SkGLContext_none.cpp
deleted file mode 100644
index 921f583..0000000
--- a/src/gpu/SkGLContext_none.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "SkGLContext.h"
-
-SkGLContext::SkGLContext()
-    : fFBO(0) {
-}
-
-SkGLContext::~SkGLContext() {
-}
-
-bool SkGLContext::init(int width, int height) {
-    return false;
-}
diff --git a/src/gpu/mac/GrGLDefaultInterface_mac.cpp b/src/gpu/mac/GrGLCreateNativeInterface_mac.cpp
similarity index 83%
rename from src/gpu/mac/GrGLDefaultInterface_mac.cpp
rename to src/gpu/mac/GrGLCreateNativeInterface_mac.cpp
index ba43975..c0e93d7 100644
--- a/src/gpu/mac/GrGLDefaultInterface_mac.cpp
+++ b/src/gpu/mac/GrGLCreateNativeInterface_mac.cpp
@@ -12,7 +12,9 @@
 #include <OpenGL/gl.h>
 #include <OpenGL/glext.h>
 
-const GrGLInterface* GrGLDefaultInterface() {
+const GrGLInterface* GrGLCreateNativeInterface() {
+    // The gl functions are not context-specific so we create one global 
+    // interface
     static SkAutoTUnref<GrGLInterface> glInterface;
     if (!glInterface.get()) {
         GrGLInterface* interface = new GrGLInterface;
@@ -20,6 +22,7 @@
         interface->fBindingsExported = kDesktop_GrGLBinding;
         interface->fActiveTexture = glActiveTexture;
         interface->fAttachShader = glAttachShader;
+        interface->fBeginQuery = glBeginQuery;
         interface->fBindAttribLocation = glBindAttribLocation;
         interface->fBindBuffer = glBindBuffer;
 #if GL_VERSION_3_0
@@ -44,12 +47,13 @@
         interface->fCullFace = glCullFace;
         interface->fDeleteBuffers = glDeleteBuffers;
         interface->fDeleteProgram = glDeleteProgram;
+        interface->fDeleteQueries = glDeleteQueries;
         interface->fDeleteShader = glDeleteShader;
         interface->fDeleteTextures = glDeleteTextures;
         interface->fDepthMask = glDepthMask;
         interface->fDisable = glDisable;
         interface->fDisableClientState = glDisableClientState;
-        interface->fDisableVertexAttribArray = 
+        interface->fDisableVertexAttribArray =
                                             glDisableVertexAttribArray;
         interface->fDrawArrays = glDrawArrays;
         interface->fDrawBuffer = glDrawBuffer;
@@ -58,13 +62,20 @@
         interface->fEnable = glEnable;
         interface->fEnableClientState = glEnableClientState;
         interface->fEnableVertexAttribArray = glEnableVertexAttribArray;
+        interface->fEndQuery = glEndQuery;
+        interface->fFinish = glFinish;
+        interface->fFlush = glFlush;
         interface->fFrontFace = glFrontFace;
         interface->fGenBuffers = glGenBuffers;
+        interface->fGenQueries = glGenQueries;
         interface->fGetBufferParameteriv = glGetBufferParameteriv;
         interface->fGetError = glGetError;
         interface->fGetIntegerv = glGetIntegerv;
         interface->fGetProgramInfoLog = glGetProgramInfoLog;
         interface->fGetProgramiv = glGetProgramiv;
+        interface->fGetQueryiv = glGetQueryiv;
+        interface->fGetQueryObjectiv = glGetQueryObjectiv;
+        interface->fGetQueryObjectuiv = glGetQueryObjectuiv;
         interface->fGetShaderInfoLog = glGetShaderInfoLog;
         interface->fGetShaderiv = glGetShaderiv;
         interface->fGetString = glGetString;
@@ -123,9 +134,19 @@
         interface->fVertexPointer = glVertexPointer;
         interface->fViewport = glViewport;
 
+    #if GL_ARB_timer_query || GL_VERSION_3_3
+        interface->fQueryCounter = glQueryCounter;
+        interface->fGetQueryObjecti64v = glGetQueryObjecti64v;
+        interface->fGetQueryObjectui64v = glGetQueryObjectui64v;
+    #elif GL_EXT_timer_query
+        interface->fGetQueryObjecti64v = glGetQueryObjecti64vEXT;
+        interface->fGetQueryObjectui64v = glGetQueryObjectui64vEXT;
+    #endif
+        
     #if GL_ARB_framebuffer_object
         interface->fGenFramebuffers = glGenFramebuffers;
-        interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;
+        interface->fGetFramebufferAttachmentParameteriv =
+                                        glGetFramebufferAttachmentParameteriv;
         interface->fGetRenderbufferParameteriv = glGetRenderbufferParameteriv;
         interface->fBindFramebuffer = glBindFramebuffer;
         interface->fFramebufferTexture2D = glFramebufferTexture2D;
@@ -141,8 +162,10 @@
         interface->fBlitFramebuffer = glBlitFramebuffer;
     #elif GL_EXT_framebuffer_object
         interface->fGenFramebuffers = glGenFramebuffersEXT;
-        interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameterivEXT;
-        interface->fGetRenderbufferParameteriv = glGetRenderbufferParameterivEXT;
+        interface->fGetFramebufferAttachmentParameteriv = 
+                                    glGetFramebufferAttachmentParameterivEXT;
+        interface->fGetRenderbufferParameteriv =
+                                                glGetRenderbufferParameterivEXT;
         interface->fBindFramebuffer = glBindFramebufferEXT;
         interface->fFramebufferTexture2D = glFramebufferTexture2DEXT;
         interface->fCheckFramebufferStatus = glCheckFramebufferStatusEXT;
@@ -150,8 +173,7 @@
         interface->fRenderbufferStorage = glRenderbufferStorageEXT;
         interface->fGenRenderbuffers = glGenRenderbuffersEXT;
         interface->fDeleteRenderbuffers = glDeleteRenderbuffersEXT;
-        interface->fFramebufferRenderbuffer = 
-                                                glFramebufferRenderbufferEXT;
+        interface->fFramebufferRenderbuffer = glFramebufferRenderbufferEXT;
         interface->fBindRenderbuffer = glBindRenderbufferEXT;
     #if GL_EXT_framebuffer_multisample
         interface->fRenderbufferStorageMultisample = 
diff --git a/src/gpu/mac/SkGLContext_mac.cpp b/src/gpu/mac/SkGLContext_mac.cpp
deleted file mode 100644
index 0992be8..0000000
--- a/src/gpu/mac/SkGLContext_mac.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "SkGLContext.h"
-//#include "SkTypes.h"
-#include <AGL/agl.h>
-
-SkGLContext::SkGLContext() 
-    : fFBO(0)
-    , context(NULL) {
-}
-
-SkGLContext::~SkGLContext() {
-    if (this->context) {
-        aglDestroyContext(this->context);
-    }
-}
-
-bool SkGLContext::init(int width, int height) {
-    GLint major, minor;
-    AGLContext ctx;
-
-    aglGetVersion(&major, &minor);
-    //SkDebugf("---- agl version %d %d\n", major, minor);
-
-    const GLint pixelAttrs[] = {
-        AGL_RGBA,
-        AGL_STENCIL_SIZE, 8,
-/*
-        AGL_SAMPLE_BUFFERS_ARB, 1,
-        AGL_MULTISAMPLE,
-        AGL_SAMPLES_ARB, 2,
-*/
-        AGL_ACCELERATED,
-        AGL_NONE
-    };
-    AGLPixelFormat format = aglChoosePixelFormat(NULL, 0, pixelAttrs);
-    //AGLPixelFormat format = aglCreatePixelFormat(pixelAttrs);
-    //SkDebugf("----- agl format %p\n", format);
-    ctx = aglCreateContext(format, NULL);
-    //SkDebugf("----- agl context %p\n", ctx);
-    aglDestroyPixelFormat(format);
-
-/*
-    static const GLint interval = 1;
-    aglSetInteger(ctx, AGL_SWAP_INTERVAL, &interval);
-*/
-
-    aglSetCurrentContext(ctx);
-    this->context = ctx;
-
-    // Now create our FBO render target
-
-    GLuint cbID;
-    GLuint dsID;
-    glGenFramebuffersEXT(1, &fFBO);
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fFBO);
-    glGenRenderbuffersEXT(1, &cbID);
-    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, cbID);
-    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, width, height);
-    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, cbID);
-    glGenRenderbuffersEXT(1, &dsID);
-    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, dsID);
-    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, width, height);
-    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, dsID);
-    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, dsID);
-    glViewport(0, 0, width, height);
-    glClearStencil(0);
-    glClear(GL_STENCIL_BUFFER_BIT);
-
-    GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
-    return GL_FRAMEBUFFER_COMPLETE_EXT == status;
-}
diff --git a/src/gpu/mac/SkNativeGLContext_mac.cpp b/src/gpu/mac/SkNativeGLContext_mac.cpp
new file mode 100644
index 0000000..3f864c2
--- /dev/null
+++ b/src/gpu/mac/SkNativeGLContext_mac.cpp
@@ -0,0 +1,64 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkNativeGLContext.h"
+
+SkNativeGLContext::SkNativeGLContext() 
+    : fContext(NULL) {
+}
+
+SkNativeGLContext::~SkNativeGLContext() {
+    this->destroyGLContext();
+}
+
+void SkNativeGLContext::destroyGLContext() {
+    if (fContext) {
+        aglDestroyContext(fContext);
+    }
+}
+
+const GrGLInterface* SkNativeGLContext::createGLContext() {
+    GLint major, minor;
+    AGLContext ctx;
+
+    aglGetVersion(&major, &minor);
+    //SkDebugf("---- agl version %d %d\n", major, minor);
+
+    const GLint pixelAttrs[] = {
+        AGL_RGBA,
+        AGL_ACCELERATED,
+        AGL_NONE
+    };
+    AGLPixelFormat format = aglChoosePixelFormat(NULL, 0, pixelAttrs);
+    if (NULL == format) {
+        SkDebugf("Format could not be found.\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+    fContext = aglCreateContext(format, NULL);
+    if (NULL == fContext) {
+        SkDebugf("Context could not be created.\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+    aglDestroyPixelFormat(format);
+
+    aglSetCurrentContext(fContext);
+    
+    const GrGLInterface* interface = GrGLCreateNativeInterface();
+    if (NULL == interface) {
+        SkDebugf("Context could not create GL interface.\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+    
+    return interface;
+}
+
+void SkNativeGLContext::makeCurrent() const {
+    aglSetCurrentContext(fContext);
+}
diff --git a/src/gpu/mesa/GrGLDefaultInterface_mesa.cpp b/src/gpu/mesa/GrGLCreateMesaInterface.cpp
similarity index 64%
rename from src/gpu/mesa/GrGLDefaultInterface_mesa.cpp
rename to src/gpu/mesa/GrGLCreateMesaInterface.cpp
index 793e65c..f7d1626 100644
--- a/src/gpu/mesa/GrGLDefaultInterface_mesa.cpp
+++ b/src/gpu/mesa/GrGLCreateMesaInterface.cpp
@@ -9,19 +9,22 @@
 
 #include "GrGLInterface.h"
 
-#include "GL/osmesa.h"
-#include <GL/glext.h>
-#include <GL/glu.h>
+#define GL_GLEXT_PROTOTYPES
+#include <GL/osmesa.h>
 
 #define GR_GL_GET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) \
         OSMesaGetProcAddress("gl" #F);
 #define GR_GL_GET_PROC_SUFFIX(F, S) interface->f ## F = (GrGL ## F ## Proc) \
         OSMesaGetProcAddress("gl" #F #S);
 
-const GrGLInterface* GrGLDefaultInterface() {
+// We use OSMesaGetProcAddress for every gl function to avoid accidentally using
+// non-Mesa gl functions.
+
+const GrGLInterface* GrGLCreateMesaInterface() {
     if (NULL != OSMesaGetCurrentContext()) {
-        const char* versionString = (const char*) glGetString(GL_VERSION);
-        const char* extString = (const char*) glGetString(GL_EXTENSIONS);
+        GrGLGetStringProc getString = (GrGLGetStringProc) OSMesaGetProcAddress("glGetString");
+        const char* versionString = (const char*) getString(GL_VERSION);
+        const char* extString = (const char*) getString(GL_EXTENSIONS);
         GrGLVersion glVer = GrGLGetVersionFromString(versionString);
 
         if (glVer < GR_GL_VER(1,5)) {
@@ -33,80 +36,97 @@
         interface->fMinRenderTargetHeight = kProbe_GrGLCapability;
         interface->fMinRenderTargetWidth = kProbe_GrGLCapability;
 
-        interface->fActiveTexture = glActiveTexture;GrGLIn
+        GR_GL_GET_PROC(ActiveTexture);
+        GR_GL_GET_PROC(BeginQuery);
         GR_GL_GET_PROC(AttachShader);
         GR_GL_GET_PROC(BindAttribLocation);
         GR_GL_GET_PROC(BindBuffer);
         GR_GL_GET_PROC(BindFragDataLocation);
-        interface->fBindTexture = glBindTexture;
-        interface->fBlendColor = glBlendColor;
-        interface->fBlendFunc = glBlendFunc;
+        GR_GL_GET_PROC(BindTexture);
+        GR_GL_GET_PROC(BlendColor);
+        GR_GL_GET_PROC(BlendFunc);
         GR_GL_GET_PROC(BufferData);
         GR_GL_GET_PROC(BufferSubData);
-        interface->fClear = glClear;
-        interface->fClearColor = glClearColor;
-        interface->fClearStencil = glClearStencil;
-        interface->fClientActiveTexture = glClientActiveTexture;
-        interface->fColorMask = glColorMask;
-        interface->fColorPointer = glColorPointer;
-        interface->fColor4ub = glColor4ub;
+        GR_GL_GET_PROC(Clear);
+        GR_GL_GET_PROC(ClearColor);
+        GR_GL_GET_PROC(ClearStencil);
+        GR_GL_GET_PROC(ClientActiveTexture);
+        GR_GL_GET_PROC(ColorMask);
+        GR_GL_GET_PROC(ColorPointer);
+        GR_GL_GET_PROC(Color4ub);
         GR_GL_GET_PROC(CompileShader);
-        interface->fCompressedTexImage2D = glCompressedTexImage2D;
+        GR_GL_GET_PROC(CompressedTexImage2D);
         GR_GL_GET_PROC(CreateProgram);
         GR_GL_GET_PROC(CreateShader);
-        interface->fCullFace = glCullFace;
+        GR_GL_GET_PROC(CullFace);
         GR_GL_GET_PROC(DeleteBuffers);
         GR_GL_GET_PROC(DeleteProgram);
+        GR_GL_GET_PROC(DeleteQueries);
         GR_GL_GET_PROC(DeleteShader);
-        interface->fDeleteTextures = glDeleteTextures;
-        interface->fDepthMask = glDepthMask;
-        interface->fDisable = glDisable;
-        interface->fDisableClientState = glDisableClientState;
+        GR_GL_GET_PROC(DeleteTextures);
+        GR_GL_GET_PROC(DepthMask);
+        GR_GL_GET_PROC(Disable);
+        GR_GL_GET_PROC(DisableClientState);
         GR_GL_GET_PROC(DisableVertexAttribArray);
-        interface->fDrawArrays = glDrawArrays;
-        interface->fDrawBuffer = glDrawBuffer;
+        GR_GL_GET_PROC(DrawArrays);
+        GR_GL_GET_PROC(DrawBuffer);
         GR_GL_GET_PROC(DrawBuffers);
-        interface->fDrawElements = glDrawElements;
-        interface->fEnable = glEnable;
-        interface->fEnableClientState = glEnableClientState;
+        GR_GL_GET_PROC(DrawElements);
+        GR_GL_GET_PROC(Enable);
+        GR_GL_GET_PROC(EnableClientState);
         GR_GL_GET_PROC(EnableVertexAttribArray);
-        interface->fFrontFace = glFrontFace;
+        GR_GL_GET_PROC(EndQuery);
+        GR_GL_GET_PROC(Finish);
+        GR_GL_GET_PROC(Flush);
+        GR_GL_GET_PROC(FrontFace);
         GR_GL_GET_PROC(GenBuffers);
+        GR_GL_GET_PROC(GenQueries);
         GR_GL_GET_PROC(GetBufferParameteriv);
-        interface->fGetError = glGetError;
-        interface->fGetIntegerv = glGetIntegerv;
+        GR_GL_GET_PROC(GetError);
+        GR_GL_GET_PROC(GetIntegerv);
         GR_GL_GET_PROC(GetProgramInfoLog);
         GR_GL_GET_PROC(GetProgramiv);
+        if (glVer >= GR_GL_VER(3,3) ||
+            GrGLHasExtensionFromString("GL_ARB_timer_query", extString)) {
+            GR_GL_GET_PROC(GetQueryObjecti64v);
+            GR_GL_GET_PROC(GetQueryObjectui64v)
+            GR_GL_GET_PROC(QueryCounter);
+        } else if (GrGLHasExtensionFromString("GL_EXT_timer_query", extString)) {
+            GR_GL_GET_PROC_SUFFIX(GetQueryObjecti64v, "EXT");
+            GR_GL_GET_PROC_SUFFIX(GetQueryObjectui64v, "EXT");
+        }
+        GR_GL_GET_PROC(GetQueryObjectiv);
+        GR_GL_GET_PROC(GetQueryObjectuiv);
+        GR_GL_GET_PROC(GetQueryiv);
         GR_GL_GET_PROC(GetShaderInfoLog);
         GR_GL_GET_PROC(GetShaderiv);
-        interface->fGetString = glGetString;
-        interface->fGetTexLevelParameteriv = glGetTexLevelParameteriv;
-        interface->fGenTextures = glGenTextures;
+        GR_GL_GET_PROC(GetString);
+        GR_GL_GET_PROC(GetTexLevelParameteriv);
+        GR_GL_GET_PROC(GenTextures);
         GR_GL_GET_PROC(GetUniformLocation);
-        interface->fLineWidth = glLineWidth;
+        GR_GL_GET_PROC(LineWidth);
         GR_GL_GET_PROC(LinkProgram);
-        interface->fLoadMatrixf = glLoadMatrixf;
+        GR_GL_GET_PROC(LoadMatrixf);
         GR_GL_GET_PROC(MapBuffer);
-        interface->fMatrixMode = glMatrixMode;
-        interface->fPointSize = glPointSize;
-        interface->fPixelStorei = glPixelStorei;
-        interface->fReadBuffer = glReadBuffer;
-        interface->fReadPixels = glReadPixels;
-        interface->fScissor = glScissor;
-        interface->fShadeModel = glShadeModel;
+        GR_GL_GET_PROC(MatrixMode);
+        GR_GL_GET_PROC(PointSize);
+        GR_GL_GET_PROC(PixelStorei);
+        GR_GL_GET_PROC(ReadBuffer);
+        GR_GL_GET_PROC(ReadPixels);
+        GR_GL_GET_PROC(Scissor);
+        GR_GL_GET_PROC(ShadeModel);
         GR_GL_GET_PROC(ShaderSource);
-        interface->fStencilFunc = glStencilFunc;
+        GR_GL_GET_PROC(StencilFunc);
         GR_GL_GET_PROC(StencilFuncSeparate);
-        interface->fStencilMask = glStencilMask;
+        GR_GL_GET_PROC(StencilMask);
         GR_GL_GET_PROC(StencilMaskSeparate);
-        interface->fStencilOp = glStencilOp;
+        GR_GL_GET_PROC(StencilOp);
         GR_GL_GET_PROC(StencilOpSeparate);
-        interface->fTexCoordPointer = glTexCoordPointer;
-        interface->fTexEnvi = glTexEnvi;
-        //OSMesa on Mac's glTexImage2D takes a GLenum for internalFormat rather than a GLint.
-        interface->fTexImage2D = reinterpret_cast<GrGLTexImage2DProc>(glTexImage2D);
-        interface->fTexParameteri = glTexParameteri;
-        interface->fTexSubImage2D = glTexSubImage2D;
+        GR_GL_GET_PROC(TexCoordPointer);
+        GR_GL_GET_PROC(TexEnvi);
+        GR_GL_GET_PROC(TexImage2D)
+        GR_GL_GET_PROC(TexParameteri);
+        GR_GL_GET_PROC(TexSubImage2D);
         GR_GL_GET_PROC(Uniform1f);
         GR_GL_GET_PROC(Uniform1i);
         GR_GL_GET_PROC(Uniform1fv);
@@ -130,8 +150,8 @@
         GR_GL_GET_PROC(UseProgram);
         GR_GL_GET_PROC(VertexAttrib4fv);
         GR_GL_GET_PROC(VertexAttribPointer);
-        interface->fVertexPointer = glVertexPointer;
-        interface->fViewport = glViewport;
+        GR_GL_GET_PROC(VertexPointer);
+        GR_GL_GET_PROC(Viewport);
 
         // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since
         // GL_ARB_framebuffer_object doesn't use ARB suffix.)
diff --git a/src/gpu/mesa/SkGLContext_mesa.cpp b/src/gpu/mesa/SkGLContext_mesa.cpp
deleted file mode 100644
index 6ba42e7..0000000
--- a/src/gpu/mesa/SkGLContext_mesa.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "SkGLContext.h"
-#include "SkTypes.h"
-
-#include "GL/osmesa.h"
-#include "GL/glu.h"
-
-#define SK_GL_DECL_PROC(T, F) T F ## _func = NULL;
-#define SK_GL_GET_PROC(T, F) F ## _func = (T)OSMesaGetProcAddress(#F);
-#define SK_GL_GET_EXT_PROC(T, F) F ## _func = (T)OSMesaGetProcAddress(#F "EXT");
-
-SkGLContext::SkGLContext()
-    : fFBO(0)
-    , context(NULL)
-    , image(NULL) {
-}
-
-SkGLContext::~SkGLContext() {
-    if (this->image)
-        free(this->image);
-    
-    if (this->context)
-        OSMesaDestroyContext(this->context);
-}
-
-#if SK_B32_SHIFT < SK_G32_SHIFT &&\
-                   SK_G32_SHIFT < SK_R32_SHIFT &&\
-                                  SK_R32_SHIFT < SK_A32_SHIFT
-    #define SK_OSMESA_COLOR_ORDER OSMESA_BGRA
-#elif SK_R32_SHIFT < SK_G32_SHIFT &&\
-                     SK_G32_SHIFT < SK_B32_SHIFT &&\
-                                    SK_B32_SHIFT < SK_A32_SHIFT
-    #define SK_OSMESA_COLOR_ORDER OSMESA_RGBA
-#elif SK_A32_SHIFT < SK_R32_SHIFT && \
-                     SK_R32_SHIFT < SK_G32_SHIFT && \
-                                    SK_G32_SHIFT < SK_B32_SHIFT
-    #define SK_OSMESA_COLOR_ORDER OSMESA_ARGB
-#else
-    //Color order (rgba) SK_R32_SHIFT SK_G32_SHIFT SK_B32_SHIFT SK_A32_SHIFT
-    #define SK_OSMESA_COLOR_ORDER OSMESA_RGBA
-#endif
-
-bool SkGLContext::init(const int width, const int height) {
-    /* Create an RGBA-mode context */
-#if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
-    /* specify Z, stencil, accum sizes */
-    OSMesaContext ctx = OSMesaCreateContextExt(SK_OSMESA_COLOR_ORDER, 16, 0, 0, NULL);
-#else
-    OSMesaContext ctx = OSMesaCreateContext(SK_OSMESA_COLOR_ORDER, NULL);
-#endif
-    if (!ctx) {
-        SkDebugf("OSMesaCreateContext failed!\n");
-        return false;
-    }
-    this->context = ctx;
-    
-    // Allocate the image buffer
-    GLfloat *buffer = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
-    if (!buffer) {
-        SkDebugf("Alloc image buffer failed!\n");
-        return false;
-    }
-    this->image = buffer;
-    
-    // Bind the buffer to the context and make it current
-    if (!OSMesaMakeCurrent(ctx, buffer, GL_FLOAT, width, height)) {
-        SkDebugf("OSMesaMakeCurrent failed!\n");
-        return false;
-    }
-    
-    //Setup the framebuffers
-    SK_GL_DECL_PROC(PFNGLGENFRAMEBUFFERSEXTPROC, glGenFramebuffers)
-    SK_GL_DECL_PROC(PFNGLBINDFRAMEBUFFEREXTPROC, glBindFramebuffer)
-    SK_GL_DECL_PROC(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers)
-    SK_GL_DECL_PROC(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer)
-    SK_GL_DECL_PROC(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage)
-    SK_GL_DECL_PROC(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer)
-    SK_GL_DECL_PROC(PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC, glCheckFramebufferStatus)
-    
-    const GLubyte* glExts = glGetString(GL_EXTENSIONS);
-    if (gluCheckExtension(
-          reinterpret_cast<const GLubyte*>("GL_ARB_framebuffer_object")
-          , glExts))
-    {
-        SK_GL_GET_PROC(PFNGLGENFRAMEBUFFERSEXTPROC, glGenFramebuffers)
-        SK_GL_GET_PROC(PFNGLBINDFRAMEBUFFEREXTPROC, glBindFramebuffer)
-        SK_GL_GET_PROC(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers)
-        SK_GL_GET_PROC(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer)
-        SK_GL_GET_PROC(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage)
-        SK_GL_GET_PROC(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer)
-        SK_GL_GET_PROC(PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC, glCheckFramebufferStatus)
-        
-    //osmesa on mac currently only supports EXT
-    } else if (gluCheckExtension(
-          reinterpret_cast<const GLubyte*>("GL_EXT_framebuffer_object")
-          , glExts))
-    {
-        SK_GL_GET_EXT_PROC(PFNGLGENFRAMEBUFFERSEXTPROC, glGenFramebuffers)
-        SK_GL_GET_EXT_PROC(PFNGLBINDFRAMEBUFFEREXTPROC, glBindFramebuffer)
-        SK_GL_GET_EXT_PROC(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers)
-        SK_GL_GET_EXT_PROC(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer)
-        SK_GL_GET_EXT_PROC(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage)
-        SK_GL_GET_EXT_PROC(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer)
-        SK_GL_GET_EXT_PROC(PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC, glCheckFramebufferStatus)
-    } else {
-      SkDebugf("GL_ARB_framebuffer_object not found.\n");
-      return false;
-    }
-    
-    GLuint cbID;
-    GLuint dsID;
-    glGenFramebuffers_func(1, &fFBO);
-    glBindFramebuffer_func(GL_FRAMEBUFFER, fFBO);
-    
-    glGenRenderbuffers_func(1, &cbID);
-    glBindRenderbuffer_func(GL_RENDERBUFFER, cbID);
-    glRenderbufferStorage_func(GL_RENDERBUFFER, OSMESA_RGBA, width, height);
-    glFramebufferRenderbuffer_func(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, cbID);
-    
-    glGenRenderbuffers_func(1, &dsID);
-    glBindRenderbuffer_func(GL_RENDERBUFFER_EXT, dsID);
-    glRenderbufferStorage_func(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
-    glFramebufferRenderbuffer_func(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, dsID);
-    
-    glViewport(0, 0, width, height);
-    glClearStencil(0);
-    glClear(GL_STENCIL_BUFFER_BIT);
-
-    GLenum status = glCheckFramebufferStatus_func(GL_FRAMEBUFFER);
-    return GL_FRAMEBUFFER_COMPLETE == status;
-}
diff --git a/src/gpu/mesa/SkMesaGLContext.cpp b/src/gpu/mesa/SkMesaGLContext.cpp
new file mode 100644
index 0000000..23ccc95
--- /dev/null
+++ b/src/gpu/mesa/SkMesaGLContext.cpp
@@ -0,0 +1,86 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <GL/osmesa.h>
+
+#include "SkMesaGLContext.h"
+
+
+SkMesaGLContext::SkMesaGLContext()
+    : fContext(NULL)
+    , fImage(NULL) {
+    GR_STATIC_ASSERT(sizeof(Context) == sizeof(OSMesaContext));
+}
+
+SkMesaGLContext::~SkMesaGLContext() {
+    this->destroyGLContext();
+}
+
+void SkMesaGLContext::destroyGLContext() {
+    if (fImage) {
+        sk_free(fImage);
+    }
+    
+    if (fContext) {
+        OSMesaDestroyContext((OSMesaContext)fContext);
+    }
+}
+
+static const GrGLint gBOGUS_SIZE = 16;
+
+const GrGLInterface* SkMesaGLContext::createGLContext() {
+    /* Create an RGBA-mode context */
+#if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
+    /* specify Z, stencil, accum sizes */
+    fContext = (Context)OSMesaCreateContextExt(OSMESA_BGRA, 0, 0, 0, NULL);
+#else
+    fContext = (Context)OSMesaCreateContext(OSMESA_BGRA, NULL);
+#endif
+    if (!fContext) {
+        SkDebugf("OSMesaCreateContext failed!\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+    // Allocate the image buffer
+    fImage = (GrGLubyte *) sk_malloc_throw(gBOGUS_SIZE * gBOGUS_SIZE *
+                                           4 * sizeof(GrGLubyte));
+    if (!fImage) {
+        SkDebugf("Alloc image buffer failed!\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+    
+    // Bind the buffer to the context and make it current
+    if (!OSMesaMakeCurrent((OSMesaContext)fContext, 
+                           fImage, 
+                           GR_GL_UNSIGNED_BYTE, 
+                           gBOGUS_SIZE, 
+                           gBOGUS_SIZE)) {
+        SkDebugf("OSMesaMakeCurrent failed!\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+    
+    const GrGLInterface* interface = GrGLCreateMesaInterface();
+    if (!interface) {
+        SkDebugf("Could not create GL interface!\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+    return interface;
+    
+}
+
+void SkMesaGLContext::makeCurrent() const {
+    if (fContext) {
+        if (!OSMesaMakeCurrent((OSMesaContext)fContext, fImage, 
+                               GR_GL_UNSIGNED_BYTE, gBOGUS_SIZE, gBOGUS_SIZE)) {
+            SkDebugf("Could not make MESA context current.");
+        }
+    }
+}
diff --git a/src/gpu/unix/GrGLDefaultInterface_unix.cpp b/src/gpu/unix/GrGLCreateNativeInterface_unix.cpp
similarity index 90%
rename from src/gpu/unix/GrGLDefaultInterface_unix.cpp
rename to src/gpu/unix/GrGLCreateNativeInterface_unix.cpp
index 041caec..90338a5 100644
--- a/src/gpu/unix/GrGLDefaultInterface_unix.cpp
+++ b/src/gpu/unix/GrGLCreateNativeInterface_unix.cpp
@@ -19,7 +19,7 @@
 #define GR_GL_GET_PROC_SUFFIX(F, S) interface->f ## F = (GrGL ## F ## Proc) \
         glXGetProcAddress(reinterpret_cast<const GLubyte*>("gl" #F #S));
 
-const GrGLInterface* GrGLDefaultInterface() {
+const GrGLInterface* GrGLCreateNativeInterface() {
     if (NULL != glXGetCurrentContext()) {
         const char* versionString = (const char*) glGetString(GL_VERSION);
         const char* extString = (const char*) glGetString(GL_EXTENSIONS);
@@ -41,6 +41,7 @@
         GR_GL_GET_PROC(BindAttribLocation);
         GR_GL_GET_PROC(BindBuffer);
         GR_GL_GET_PROC(BindFragDataLocation);
+        GR_GL_GET_PROC(BeginQuery);
         interface->fBindTexture = glBindTexture;
         interface->fBlendColor = glBlendColor;
         interface->fBlendFunc = glBlendFunc;
@@ -60,6 +61,7 @@
         interface->fCullFace = glCullFace;
         GR_GL_GET_PROC(DeleteBuffers);
         GR_GL_GET_PROC(DeleteProgram);
+        GR_GL_GET_PROC(DeleteQueries);
         GR_GL_GET_PROC(DeleteShader);
         interface->fDeleteTextures = glDeleteTextures;
         interface->fDepthMask = glDepthMask;
@@ -73,17 +75,33 @@
         interface->fEnable = glEnable;
         interface->fEnableClientState = glEnableClientState;
         GR_GL_GET_PROC(EnableVertexAttribArray);
+        GR_GL_GET_PROC(EndQuery);
+        interface->fFinish = glFinish;
+        interface->fFlush = glFlush;
         interface->fFrontFace = glFrontFace;
         GR_GL_GET_PROC(GenBuffers);
         GR_GL_GET_PROC(GetBufferParameteriv);
         interface->fGetError = glGetError;
         interface->fGetIntegerv = glGetIntegerv;
+        GR_GL_GET_PROC(GetQueryObjectiv);
+        GR_GL_GET_PROC(GetQueryObjectuiv);
+        if (glVer >= GR_GL_VER(3,3) ||
+            GrGLHasExtensionFromString("GL_ARB_timer_query", extString)) {
+            GR_GL_GET_PROC(GetQueryObjecti64v);
+            GR_GL_GET_PROC(GetQueryObjectui64v);
+            GR_GL_GET_PROC(QueryCounter);
+        } else if (GrGLHasExtensionFromString("GL_EXT_timer_query", extString)) {
+            GR_GL_GET_PROC_SUFFIX(GetQueryObjecti64v, "EXT");
+            GR_GL_GET_PROC_SUFFIX(GetQueryObjectui64v, "EXT");
+        }
+        GR_GL_GET_PROC(GetQueryiv);
         GR_GL_GET_PROC(GetProgramInfoLog);
         GR_GL_GET_PROC(GetProgramiv);
         GR_GL_GET_PROC(GetShaderInfoLog);
         GR_GL_GET_PROC(GetShaderiv);
         interface->fGetString = glGetString;
         interface->fGetTexLevelParameteriv = glGetTexLevelParameteriv;
+        GR_GL_GET_PROC(GenQueries);
         interface->fGenTextures = glGenTextures;
         GR_GL_GET_PROC(GetUniformLocation);
         interface->fLineWidth = glLineWidth;
@@ -93,6 +111,7 @@
         interface->fMatrixMode = glMatrixMode;
         interface->fPointSize = glPointSize;
         interface->fPixelStorei = glPixelStorei;
+
         interface->fReadBuffer = glReadBuffer;
         interface->fReadPixels = glReadPixels;
         interface->fScissor = glScissor;
diff --git a/src/gpu/unix/SkGLContext_unix.cpp b/src/gpu/unix/SkGLContext_unix.cpp
deleted file mode 100644
index ea15a4b..0000000
--- a/src/gpu/unix/SkGLContext_unix.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "SkGLContext.h"
-#include "SkTypes.h"
-
-#include <GL/gl.h>
-#include <GL/glext.h>
-#include <GL/glu.h>
-#include <GL/glx.h>
-#include <X11/Xlib.h>
-
-#define SK_GL_GET_PROC(T, F) T F = NULL; \
-        F = (T) glXGetProcAddressARB(reinterpret_cast<const GLubyte*>(#F));
-
-static bool ctxErrorOccurred = false;
-static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) {
-    ctxErrorOccurred = true;
-    return 0;
-}
-
-SkGLContext::SkGLContext() 
-    : fFBO(0)
-    , context(NULL)
-    , display(NULL)
-    , pixmap(0)
-    , glxPixmap(0) {
-}
-
-SkGLContext::~SkGLContext() {
-    if (this->display) {
-        glXMakeCurrent(this->display, 0, 0);
-
-        if (this->context)
-            glXDestroyContext(this->display, this->context);
-
-        if (this->glxPixmap)
-            glXDestroyGLXPixmap(this->display, this->glxPixmap);
-
-        if (this->pixmap)
-            XFreePixmap(this->display, this->pixmap);
-
-        XCloseDisplay(this->display);
-    }
-}
-
-bool SkGLContext::init(const int width, const int height) {
-    Display *display = XOpenDisplay(0);
-    this->display = display;
-
-    if (!display) {
-        SkDebugf("Failed to open X display.\n");
-        return false;
-    }
-
-    // Get a matching FB config
-    static int visual_attribs[] = {
-        GLX_X_RENDERABLE    , True,
-        GLX_DRAWABLE_TYPE   , GLX_PIXMAP_BIT,
-        GLX_RENDER_TYPE     , GLX_RGBA_BIT,
-        GLX_X_VISUAL_TYPE   , GLX_TRUE_COLOR,
-        GLX_RED_SIZE        , 8,
-        GLX_GREEN_SIZE      , 8,
-        GLX_BLUE_SIZE       , 8,
-        GLX_ALPHA_SIZE      , 8,
-        GLX_DEPTH_SIZE      , 24,
-        GLX_STENCIL_SIZE    , 8,
-        GLX_DOUBLEBUFFER    , True,
-        //GLX_SAMPLE_BUFFERS  , 1,
-        //GLX_SAMPLES         , 4,
-        None
-    };
-
-    int glx_major, glx_minor;
-
-    // FBConfigs were added in GLX version 1.3.
-    if (!glXQueryVersion( display, &glx_major, &glx_minor) ||
-            ( (glx_major == 1) && (glx_minor < 3) ) || (glx_major < 1))
-    {
-        SkDebugf("Invalid GLX version.");
-        return false;
-    }
-
-    //SkDebugf("Getting matching framebuffer configs.\n");
-    int fbcount;
-    GLXFBConfig *fbc = glXChooseFBConfig(display, DefaultScreen(display),
-                                          visual_attribs, &fbcount);
-    if (!fbc) {
-        SkDebugf("Failed to retrieve a framebuffer config.\n");
-        return false;
-    }
-    //SkDebugf("Found %d matching FB configs.\n", fbcount);
-
-    // Pick the FB config/visual with the most samples per pixel
-    //SkDebugf("Getting XVisualInfos.\n");
-    int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;
-
-    int i;
-    for (i = 0; i < fbcount; ++i) {
-        XVisualInfo *vi = glXGetVisualFromFBConfig(display, fbc[i]);
-        if (vi) {
-            int samp_buf, samples;
-            glXGetFBConfigAttrib(display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
-            glXGetFBConfigAttrib(display, fbc[i], GLX_SAMPLES, &samples);
-
-            //SkDebugf("  Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
-            //       " SAMPLES = %d\n",
-            //        i, (unsigned int)vi->visualid, samp_buf, samples);
-
-            if (best_fbc < 0 || (samp_buf && samples > best_num_samp))
-                best_fbc = i, best_num_samp = samples;
-            if (worst_fbc < 0 || !samp_buf || samples < worst_num_samp)
-                worst_fbc = i, worst_num_samp = samples;
-        }
-        XFree(vi);
-    }
-
-    GLXFBConfig bestFbc = fbc[best_fbc];
-
-    // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
-    XFree(fbc);
-
-    // Get a visual
-    XVisualInfo *vi = glXGetVisualFromFBConfig(display, bestFbc);
-    //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid);
-
-    Pixmap pixmap = XCreatePixmap(
-        display, RootWindow(display, vi->screen), width, height, vi->depth
-    );
-
-    this->pixmap = pixmap;
-    if (!pixmap) {
-        SkDebugf("Failed to create pixmap.\n");
-        return false;
-    }
-
-    GLXPixmap glxPixmap = glXCreateGLXPixmap(display, vi, pixmap);
-    this->glxPixmap = glxPixmap;
-
-    // Done with the visual info data
-    XFree(vi);
-
-    // Create the context
-    GLXContext ctx = 0;
-
-    // Install an X error handler so the application won't exit if GL 3.0
-    // context allocation fails.
-    //
-    // Note this error handler is global.
-    // All display connections in all threads of a process use the same
-    // error handler, so be sure to guard against other threads issuing
-    // X commands while this code is running.
-    ctxErrorOccurred = false;
-    int (*oldHandler)(Display*, XErrorEvent*) =
-        XSetErrorHandler(&ctxErrorHandler);
-
-    // Get the default screen's GLX extension list
-    const char *glxExts = glXQueryExtensionsString(
-        display, DefaultScreen(display)
-    );
-    // Check for the GLX_ARB_create_context extension string and the function.
-    // If either is not present, use GLX 1.3 context creation method.
-    if (!gluCheckExtension(
-          reinterpret_cast<const GLubyte*>("GLX_ARB_create_context")
-          , reinterpret_cast<const GLubyte*>(glxExts)))
-    {
-        //SkDebugf("GLX_ARB_create_context not found."
-        //       " Using old-style GLX context.\n");
-        ctx = glXCreateNewContext(display, bestFbc, GLX_RGBA_TYPE, 0, True);
-
-    } else {
-        //SkDebugf("Creating context.\n");
-
-        SK_GL_GET_PROC(PFNGLXCREATECONTEXTATTRIBSARBPROC, glXCreateContextAttribsARB)
-        int context_attribs[] = {
-            GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
-            GLX_CONTEXT_MINOR_VERSION_ARB, 0,
-            //GLX_CONTEXT_FLAGS_ARB        , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
-            None
-        };
-        ctx = glXCreateContextAttribsARB(
-            display, bestFbc, 0, True, context_attribs
-        );
-
-        // Sync to ensure any errors generated are processed.
-        XSync(display, False);
-        if (!ctxErrorOccurred && ctx) {
-           //SkDebugf( "Created GL 3.0 context.\n" );
-        } else {
-            // Couldn't create GL 3.0 context.
-            // Fall back to old-style 2.x context.
-            // When a context version below 3.0 is requested,
-            // implementations will return the newest context version compatible
-            // with OpenGL versions less than version 3.0.
-
-            // GLX_CONTEXT_MAJOR_VERSION_ARB = 1
-            context_attribs[1] = 1;
-            // GLX_CONTEXT_MINOR_VERSION_ARB = 0
-            context_attribs[3] = 0;
-
-            ctxErrorOccurred = false;
-
-            //SkDebugf("Failed to create GL 3.0 context."
-            //       " Using old-style GLX context.\n");
-            ctx = glXCreateContextAttribsARB(
-                display, bestFbc, 0, True, context_attribs
-            );
-        }
-    }
-
-    // Sync to ensure any errors generated are processed.
-    XSync(display, False);
-
-    // Restore the original error handler
-    XSetErrorHandler(oldHandler);
-
-    if (ctxErrorOccurred || !ctx) {
-        SkDebugf("Failed to create an OpenGL context.\n");
-        return false;
-    }
-    this->context = ctx;
-
-    // Verify that context is a direct context
-    if (!glXIsDirect(display, ctx)) {
-        //SkDebugf("Indirect GLX rendering context obtained.\n");
-    } else {
-        //SkDebugf("Direct GLX rendering context obtained.\n");
-    }
-
-    //SkDebugf("Making context current.\n");
-    if (!glXMakeCurrent(display, glxPixmap, ctx)) {
-      SkDebugf("Could not set the context.\n");
-      return false;
-    }
-
-    //Setup the framebuffers
-    const GLubyte* glExts = glGetString(GL_EXTENSIONS);
-    if (!gluCheckExtension(
-          reinterpret_cast<const GLubyte*>("GL_EXT_framebuffer_object")
-          , glExts))
-    {
-      SkDebugf("GL_EXT_framebuffer_object not found.\n");
-      return false;
-    }
-    SK_GL_GET_PROC(PFNGLGENFRAMEBUFFERSEXTPROC, glGenFramebuffersEXT)
-    SK_GL_GET_PROC(PFNGLBINDFRAMEBUFFEREXTPROC, glBindFramebufferEXT)
-    SK_GL_GET_PROC(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffersEXT)
-    SK_GL_GET_PROC(PFNGLBINDRENDERBUFFERPROC, glBindRenderbufferEXT)
-    SK_GL_GET_PROC(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorageEXT)
-    SK_GL_GET_PROC(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbufferEXT)
-    SK_GL_GET_PROC(PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC, glCheckFramebufferStatusEXT)
-
-    GLuint cbID;
-    GLuint dsID;
-    glGenFramebuffersEXT(1, &fFBO);
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fFBO);
-    glGenRenderbuffersEXT(1, &cbID);
-    glBindRenderbufferEXT(GL_RENDERBUFFER, cbID);
-    glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, width, height);
-    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, cbID);
-    glGenRenderbuffersEXT(1, &dsID);
-    glBindRenderbufferEXT(GL_RENDERBUFFER, dsID);
-    glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height);
-    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, dsID);
-    glViewport(0, 0, width, height);
-    glClearStencil(0);
-    glClear(GL_STENCIL_BUFFER_BIT);
-
-    GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
-    return GL_FRAMEBUFFER_COMPLETE == status;
-}
diff --git a/src/gpu/unix/SkNativeGLContext_unix.cpp b/src/gpu/unix/SkNativeGLContext_unix.cpp
new file mode 100644
index 0000000..870ff45
--- /dev/null
+++ b/src/gpu/unix/SkNativeGLContext_unix.cpp
@@ -0,0 +1,245 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkNativeGLContext.h"
+
+#include <GL/glu.h>
+
+
+static bool ctxErrorOccurred = false;
+static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) {
+    ctxErrorOccurred = true;
+    return 0;
+}
+
+SkNativeGLContext::SkNativeGLContext() 
+    : fContext(NULL)
+    , fDisplay(NULL)
+    , fPixmap(0)
+    , fGlxPixmap(0) {
+}
+
+SkNativeGLContext::~SkNativeGLContext() {
+    this->destroyGLContext();
+}
+
+void SkNativeGLContext::destroyGLContext() {
+    if (fDisplay) {
+        glXMakeCurrent(fDisplay, 0, 0);
+
+        if (fContext) {
+            glXDestroyContext(fDisplay, fContext);
+            fContext = NULL;
+        }
+
+        if (fGlxPixmap) {
+            glXDestroyGLXPixmap(fDisplay, fGlxPixmap);
+            fGlxPixmap = 0;
+        }
+
+        if (fPixmap) {
+            XFreePixmap(fDisplay, fPixmap);
+            fPixmap = 0;
+        }
+
+        XCloseDisplay(fDisplay);
+        fDisplay = NULL;
+    }
+}
+
+const GrGLInterface* SkNativeGLContext::createGLContext() {
+    fDisplay = XOpenDisplay(0);
+
+    if (!fDisplay) {
+        SkDebugf("Failed to open X display.\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+
+    // Get a matching FB config
+    static int visual_attribs[] = {
+        GLX_X_RENDERABLE    , True,
+        GLX_DRAWABLE_TYPE   , GLX_PIXMAP_BIT,
+        None
+    };
+
+    int glx_major, glx_minor;
+
+    // FBConfigs were added in GLX version 1.3.
+    if (!glXQueryVersion(fDisplay, &glx_major, &glx_minor) ||
+            ( (glx_major == 1) && (glx_minor < 3) ) || (glx_major < 1))
+    {
+        SkDebugf("Invalid GLX version.");
+        this->destroyGLContext();
+        return NULL;
+    }
+
+    //SkDebugf("Getting matching framebuffer configs.\n");
+    int fbcount;
+    GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay),
+                                          visual_attribs, &fbcount);
+    if (!fbc) {
+        SkDebugf("Failed to retrieve a framebuffer config.\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+    //SkDebugf("Found %d matching FB configs.\n", fbcount);
+
+    // Pick the FB config/visual with the most samples per pixel
+    //SkDebugf("Getting XVisualInfos.\n");
+    int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;
+
+    int i;
+    for (i = 0; i < fbcount; ++i) {
+        XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, fbc[i]);
+        if (vi) {
+            int samp_buf, samples;
+            glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
+            glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLES, &samples);
+
+            //SkDebugf("  Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
+            //       " SAMPLES = %d\n",
+            //        i, (unsigned int)vi->visualid, samp_buf, samples);
+
+            if (best_fbc < 0 || (samp_buf && samples > best_num_samp))
+                best_fbc = i, best_num_samp = samples;
+            if (worst_fbc < 0 || !samp_buf || samples < worst_num_samp)
+                worst_fbc = i, worst_num_samp = samples;
+        }
+        XFree(vi);
+    }
+
+    GLXFBConfig bestFbc = fbc[best_fbc];
+
+    // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
+    XFree(fbc);
+
+    // Get a visual
+    XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc);
+    //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid);
+
+    fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10, vi->depth);
+
+    if (!fPixmap) {
+        SkDebugf("Failed to create pixmap.\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+
+    fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap);
+
+    // Done with the visual info data
+    XFree(vi);
+
+    // Create the context
+
+    // Install an X error handler so the application won't exit if GL 3.0
+    // context allocation fails.
+    //
+    // Note this error handler is global.
+    // All display connections in all threads of a process use the same
+    // error handler, so be sure to guard against other threads issuing
+    // X commands while this code is running.
+    ctxErrorOccurred = false;
+    int (*oldHandler)(Display*, XErrorEvent*) =
+        XSetErrorHandler(&ctxErrorHandler);
+
+    // Get the default screen's GLX extension list
+    const char *glxExts = glXQueryExtensionsString(
+        fDisplay, DefaultScreen(fDisplay)
+    );
+    // Check for the GLX_ARB_create_context extension string and the function.
+    // If either is not present, use GLX 1.3 context creation method.
+    if (!gluCheckExtension(
+          reinterpret_cast<const GLubyte*>("GLX_ARB_create_context")
+          , reinterpret_cast<const GLubyte*>(glxExts)))
+    {
+        //SkDebugf("GLX_ARB_create_context not found."
+        //       " Using old-style GLX context.\n");
+        fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True);
+
+    } else {
+        //SkDebugf("Creating context.\n");
+
+        PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = 
+            (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddressARB((GrGLubyte*)"glXCreateContextAttribsARB");
+        int context_attribs[] = {
+            GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+            GLX_CONTEXT_MINOR_VERSION_ARB, 0,
+            //GLX_CONTEXT_FLAGS_ARB        , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+            None
+        };
+        fContext = glXCreateContextAttribsARB(
+            fDisplay, bestFbc, 0, True, context_attribs
+        );
+
+        // Sync to ensure any errors generated are processed.
+        XSync(fDisplay, False);
+        if (!ctxErrorOccurred && fContext) {
+           //SkDebugf( "Created GL 3.0 context.\n" );
+        } else {
+            // Couldn't create GL 3.0 context.
+            // Fall back to old-style 2.x context.
+            // When a context version below 3.0 is requested,
+            // implementations will return the newest context version compatible
+            // with OpenGL versions less than version 3.0.
+
+            // GLX_CONTEXT_MAJOR_VERSION_ARB = 1
+            context_attribs[1] = 1;
+            // GLX_CONTEXT_MINOR_VERSION_ARB = 0
+            context_attribs[3] = 0;
+
+            ctxErrorOccurred = false;
+
+            //SkDebugf("Failed to create GL 3.0 context."
+            //       " Using old-style GLX context.\n");
+            fContext = glXCreateContextAttribsARB(
+                fDisplay, bestFbc, 0, True, context_attribs
+            );
+        }
+    }
+
+    // Sync to ensure any errors generated are processed.
+    XSync(fDisplay, False);
+
+    // Restore the original error handler
+    XSetErrorHandler(oldHandler);
+
+    if (ctxErrorOccurred || !fContext) {
+        SkDebugf("Failed to create an OpenGL context.\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+
+    // Verify that context is a direct context
+    if (!glXIsDirect(fDisplay, fContext)) {
+        //SkDebugf("Indirect GLX rendering context obtained.\n");
+    } else {
+        //SkDebugf("Direct GLX rendering context obtained.\n");
+    }
+
+    //SkDebugf("Making context current.\n");
+    if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) {
+      SkDebugf("Could not set the context.\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+
+    const GrGLInterface* interface = GrGLCreateNativeInterface();
+    if (!interface) {
+        SkDebugf("Failed to create gl interface");
+        this->destroyGLContext();
+        return NULL;
+    }
+    return interface;
+}
+
+void SkNativeGLContext::makeCurrent() const {
+    if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) {
+        SkDebugf("Could not set the context.\n");
+    }
+}
diff --git a/src/gpu/win/GrGLDefaultInterface_win.cpp b/src/gpu/win/GrGLCreateNativeInterface_win.cpp
similarity index 97%
rename from src/gpu/win/GrGLDefaultInterface_win.cpp
rename to src/gpu/win/GrGLCreateNativeInterface_win.cpp
index 609869f..d018906 100644
--- a/src/gpu/win/GrGLDefaultInterface_win.cpp
+++ b/src/gpu/win/GrGLCreateNativeInterface_win.cpp
@@ -8,7 +8,7 @@
 
 
 #include "GrGLInterface.h"
-
+#define WIN32_LEAN_AND_MEAN
 #include <Windows.h>
 #include <GL/GL.h>
 
@@ -21,7 +21,7 @@
 #define GR_GL_GET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F);
 #define GR_GL_GET_PROC_SUFFIX(F, S) interface->f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F #S);
 
-const GrGLInterface* GrGLDefaultInterface() {
+const GrGLInterface* GrGLCreateNativeInterface() {
     // wglGetProcAddress requires a context.
     // GL Function pointers retrieved in one context may not be valid in another
     // context. For that reason we create a new GrGLInterface each time we're 
@@ -62,6 +62,8 @@
         interface->fEnable = glEnable;
         interface->fEnableClientState = glEnableClientState;
         interface->fFrontFace = glFrontFace;
+        interface->fFinish = glFinish;
+        interface->fFlush = glFlush;
         interface->fGenTextures = glGenTextures;
         interface->fGetError = glGetError;
         interface->fGetIntegerv = glGetIntegerv;
diff --git a/src/gpu/win/SkGLContext_win.cpp b/src/gpu/win/SkGLContext_win.cpp
deleted file mode 100644
index dc24af3..0000000
--- a/src/gpu/win/SkGLContext_win.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#define WIN32_LEAN_AND_MEAN 1
-#include <Windows.h>
-#include <GL/GL.h>
-
-#include "SkGLContext.h"
-#include "SkTypes.h"
-
-#define SK_GL_DECLARE_PROC(F) SkGL ## F ## Proc SkGL ## F = NULL;
-#define SK_GL_GET_PROC(F) SkGL ## F = (SkGL ## F ## Proc) \
-        wglGetProcAddress("gl" #F);
-#define SK_GL_GET_PROC_SUFFIX(F, S) SkGL ## F = (SkGL ## F ## Proc) \
-        wglGetProcAddress("gl" #F #S);
-
-#define SK_GL_FRAMEBUFFER 0x8D40
-#define SK_GL_RENDERBUFFER 0x8D41
-#define SK_GL_COLOR_ATTACHMENT0 0x8CE0
-#define SK_GL_DEPTH_STENCIL 0x84F9
-#define SK_GL_DEPTH_STENCIL_ATTACHMENT 0x821A
-#define SK_GL_FRAMEBUFFER_COMPLETE 0x8CD5
-
-#define SK_GL_FUNCTION_TYPE __stdcall
-typedef void (SK_GL_FUNCTION_TYPE *SkGLGenFramebuffersProc) (GLsizei n, GLuint *framebuffers);
-typedef void (SK_GL_FUNCTION_TYPE *SkGLBindFramebufferProc) (GLenum target, GLuint framebuffer);
-typedef void (SK_GL_FUNCTION_TYPE *SkGLGenRenderbuffersProc) (GLsizei n, GLuint *renderbuffers);
-typedef void (SK_GL_FUNCTION_TYPE *SkGLBindRenderbufferProc) (GLenum target, GLuint renderbuffer);
-typedef void (SK_GL_FUNCTION_TYPE *SkGLRenderbufferStorageProc) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
-typedef void (SK_GL_FUNCTION_TYPE *SkGLFramebufferRenderbufferProc) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
-typedef GLenum (SK_GL_FUNCTION_TYPE *SkGLCheckFramebufferStatusProc) (GLenum target);
-
-SkGLContext::SkGLContext()
-        : fFBO(0)
-        , fWindow(NULL)
-        , fDeviceContext(NULL)
-        , fGlRenderContext(0) {
-}
-
-SkGLContext::~SkGLContext() {
-    if (this->fGlRenderContext) {
-        wglDeleteContext(this->fGlRenderContext);
-    }
-    if (this->fWindow && this->fDeviceContext) {
-        ReleaseDC(this->fWindow, this->fDeviceContext);
-    }
-    if (this->fWindow) {
-        DestroyWindow(this->fWindow);
-    }
-}
-
-bool skGLCheckExtension(const char* ext,
-                         const char* extensionString) {
-    int extLength = strlen(ext);
-
-    while (true) {
-        int n = strcspn(extensionString, " ");
-        if (n == extLength && 0 == strncmp(ext, extensionString, n)) {
-            return true;
-        }
-        if (0 == extensionString[n]) {
-            return false;
-        }
-        extensionString += n+1;
-    }
-
-    return false;
-}
-
-bool SkGLContext::init(const int width, const int height) {
-    HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
-
-    WNDCLASS wc;
-    wc.cbClsExtra = 0;
-    wc.cbWndExtra = 0;
-    wc.hbrBackground = NULL;
-    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
-    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
-    wc.hInstance = hInstance;
-    wc.lpfnWndProc = (WNDPROC) DefWindowProc;
-    wc.lpszClassName = TEXT("Griffin");
-    wc.lpszMenuName = NULL;
-    wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
- 
-    if (!RegisterClass(&wc)) {
-        SkDebugf("Could not register window class.\n");
-        return false;
-    }
-
-    if (!(
-        this->fWindow = CreateWindow(
-        TEXT("Griffin"),
-        TEXT("The Invisible Man"),
-        WS_OVERLAPPEDWINDOW,
-        10, 10,                 // x, y
-        200, 200,               // width, height
-        NULL, NULL,             // parent, menu
-        hInstance, NULL)        // hInstance, param
-        ))
-    {
-        SkDebugf("Could not create window.\n");
-        return false;
-    }
-
-    if (!(this->fDeviceContext = GetDC(this->fWindow))) {
-        SkDebugf("Could not get device context.\n");
-        return false;
-    }
-    
-    PIXELFORMATDESCRIPTOR pfd;
-    ZeroMemory(&pfd, sizeof(pfd));
-    pfd.nSize = sizeof(pfd);
-    pfd.nVersion = 1;
-    pfd.dwFlags = PFD_DRAW_TO_WINDOW |
-                  PFD_SUPPORT_OPENGL |
-                  PFD_DOUBLEBUFFER;
-    pfd.iPixelType = PFD_TYPE_RGBA;
-    pfd.cColorBits = 32;
-    pfd.cDepthBits = 24;
-    pfd.cStencilBits = 8;
-    pfd.iLayerType = PFD_MAIN_PLANE;
-    
-    int pixelFormat = 0;
-    if (!(pixelFormat = ChoosePixelFormat(this->fDeviceContext, &pfd))) {
-	    SkDebugf("No matching pixel format descriptor.\n");
-        return false;
-    }
-    
-    if (!SetPixelFormat(this->fDeviceContext, pixelFormat, &pfd)) {
-	    SkDebugf("Could not set the pixel format %d.\n", pixelFormat);
-        return false;
-    }
-    
-    if (!(this->fGlRenderContext = wglCreateContext(this->fDeviceContext))) {
-	    SkDebugf("Could not create rendering context.\n");
-        return false;
-    }
-
-    if (!(wglMakeCurrent(this->fDeviceContext, this->fGlRenderContext))) {
-        SkDebugf("Could not set the context.\n");
-        return false;
-    }
-
-    //TODO: in the future we need to use this context
-    // to test for WGL_ARB_create_context
-    // and then create a new window / context.
-
-    //Setup the framebuffers
-    const char* glExts =
-        reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
-    if (!skGLCheckExtension(
-          "GL_EXT_framebuffer_object"
-          , glExts))
-    {
-        SkDebugf("GL_EXT_framebuffer_object not found.\n");
-        return false;
-    }
-    SK_GL_DECLARE_PROC(GenFramebuffers)
-    SK_GL_DECLARE_PROC(BindFramebuffer)
-    SK_GL_DECLARE_PROC(GenRenderbuffers)
-    SK_GL_DECLARE_PROC(BindRenderbuffer)
-    SK_GL_DECLARE_PROC(RenderbufferStorage)
-    SK_GL_DECLARE_PROC(FramebufferRenderbuffer)
-    SK_GL_DECLARE_PROC(CheckFramebufferStatus)
-
-    SK_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT)
-    SK_GL_GET_PROC_SUFFIX(BindFramebuffer, EXT)
-    SK_GL_GET_PROC_SUFFIX(GenRenderbuffers, EXT)
-    SK_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT)
-    SK_GL_GET_PROC_SUFFIX(RenderbufferStorage, EXT)
-    SK_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT)
-    SK_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT)
-
-    GLuint cbID;
-    GLuint dsID;
-    SkGLGenFramebuffers(1, &fFBO);
-    SkGLBindFramebuffer(SK_GL_FRAMEBUFFER, fFBO);
-    SkGLGenRenderbuffers(1, &cbID);
-    SkGLBindRenderbuffer(SK_GL_RENDERBUFFER, cbID);
-    SkGLRenderbufferStorage(SK_GL_RENDERBUFFER, GL_RGBA, width, height);
-    SkGLFramebufferRenderbuffer(SK_GL_FRAMEBUFFER
-                                , SK_GL_COLOR_ATTACHMENT0
-                                , SK_GL_RENDERBUFFER, cbID);
-    SkGLGenRenderbuffers(1, &dsID);
-    SkGLBindRenderbuffer(SK_GL_RENDERBUFFER, dsID);
-    SkGLRenderbufferStorage(SK_GL_RENDERBUFFER, SK_GL_DEPTH_STENCIL
-                             , width, height);
-    SkGLFramebufferRenderbuffer(SK_GL_FRAMEBUFFER
-                                 , SK_GL_DEPTH_STENCIL_ATTACHMENT
-                                 , SK_GL_RENDERBUFFER
-                                 , dsID);
-    glViewport(0, 0, width, height);
-    glClearStencil(0);
-    glClear(GL_STENCIL_BUFFER_BIT);
-
-    GLenum status = SkGLCheckFramebufferStatus(SK_GL_FRAMEBUFFER);
-    return SK_GL_FRAMEBUFFER_COMPLETE == status;
-}
diff --git a/src/gpu/win/SkNativeGLContext_win.cpp b/src/gpu/win/SkNativeGLContext_win.cpp
new file mode 100644
index 0000000..c19f7cc
--- /dev/null
+++ b/src/gpu/win/SkNativeGLContext_win.cpp
@@ -0,0 +1,126 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkNativeGLContext.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+
+ATOM SkNativeGLContext::gWC = 0;
+
+SkNativeGLContext::SkNativeGLContext()
+        : fWindow(NULL)
+        , fDeviceContext(NULL)
+        , fGlRenderContext(0) {
+}
+
+SkNativeGLContext::~SkNativeGLContext() {
+    this->destroyGLContext();
+}
+
+void SkNativeGLContext::destroyGLContext() {
+    if (fGlRenderContext) {
+        wglDeleteContext(fGlRenderContext);
+    }
+    if (fWindow && fDeviceContext) {
+        ReleaseDC(fWindow, fDeviceContext);
+    }
+    if (fWindow) {
+        DestroyWindow(fWindow);
+    }
+}
+
+const GrGLInterface* SkNativeGLContext::createGLContext() {
+    HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
+
+    if (!gWC) {
+        WNDCLASS wc;
+        wc.cbClsExtra = 0;
+        wc.cbWndExtra = 0;
+        wc.hbrBackground = NULL;
+        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+        wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+        wc.hInstance = hInstance;
+        wc.lpfnWndProc = (WNDPROC) DefWindowProc;
+        wc.lpszClassName = TEXT("Griffin");
+        wc.lpszMenuName = NULL;
+        wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
+
+        gWC = RegisterClass(&wc);
+        if (!gWC) {
+            SkDebugf("Could not register window class.\n");
+            return NULL;
+        }
+    }
+
+    if (!(fWindow = CreateWindow(TEXT("Griffin"),
+                                 TEXT("The Invisible Man"),
+                                 WS_OVERLAPPEDWINDOW,
+                                 0, 0, 1, 1,
+                                 NULL, NULL,
+                                 hInstance, NULL))) {
+        SkDebugf("Could not create window.\n");
+        return NULL;
+    }
+
+    if (!(fDeviceContext = GetDC(fWindow))) {
+        SkDebugf("Could not get device context.\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+    
+    PIXELFORMATDESCRIPTOR pfd;
+    ZeroMemory(&pfd, sizeof(pfd));
+    pfd.nSize = sizeof(pfd);
+    pfd.nVersion = 1;
+    pfd.dwFlags = PFD_SUPPORT_OPENGL;
+    pfd.iPixelType = PFD_TYPE_RGBA;
+    pfd.cColorBits = 32;
+    pfd.cDepthBits = 0;
+    pfd.cStencilBits = 0;
+    pfd.iLayerType = PFD_MAIN_PLANE;
+    
+    int pixelFormat = 0;
+    if (!(pixelFormat = ChoosePixelFormat(fDeviceContext, &pfd))) {
+        SkDebugf("No matching pixel format descriptor.\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+    
+    if (!SetPixelFormat(fDeviceContext, pixelFormat, &pfd)) {
+        SkDebugf("Could not set the pixel format %d.\n", pixelFormat);
+        this->destroyGLContext();
+        return NULL;
+    }
+    
+    if (!(fGlRenderContext = wglCreateContext(fDeviceContext))) {
+        SkDebugf("Could not create rendering context.\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+
+    if (!(wglMakeCurrent(fDeviceContext, fGlRenderContext))) {
+        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");
+        this->destroyGLContext();
+        return NULL;
+    }
+
+    return interface;
+}
+
+void SkNativeGLContext::makeCurrent() const {
+    if (!wglMakeCurrent(fDeviceContext, fGlRenderContext)) {
+        SkDebugf("Could not create rendering context.\n");
+    }
+}