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/bench/BenchGpuTimer_gl.cpp b/bench/BenchGpuTimer_gl.cpp
index 7236231..885f7b2 100644
--- a/bench/BenchGpuTimer_gl.cpp
+++ b/bench/BenchGpuTimer_gl.cpp
@@ -6,161 +6,36 @@
  * found in the LICENSE file.
  */
 #include "BenchGpuTimer_gl.h"
-#include <string.h>
+#include "SkGLContext.h"
 
-//GL
-#define BENCH_GL_FUNCTION_TYPE
-#if defined(SK_MESA)
-    #include <GL/osmesa.h>
-    #define SK_BENCH_CONTEXT_CHECK (NULL != OSMesaGetCurrentContext())
+BenchGpuTimer::BenchGpuTimer(const SkGLContext* glctx) {
+    fContext = glctx;
+    glctx->ref();
+    glctx->makeCurrent();
+    fStarted = false;
+    fSupported = GrGLGetVersion(glctx->gl()) > GR_GL_VER(3,3) ||
+                 GrGLHasExtension(glctx->gl(), "GL_ARB_timer_query") ||
+                 GrGLHasExtension(glctx->gl(), "GL_EXT_timer_query");
     
-    #define SK_GL_GET_PROC(F) gBenchGL.f ## F = (BenchGL ## F ## Proc) \
-            OSMesaGetProcAddress("gl" #F);
-    #define SK_GL_GET_PROC_SUFFIX(F, S) gBenchGL.f ## F = (BenchGL##F##Proc)\
-            OSMesaGetProcAddress("gl" #F #S);
-
-#elif defined(SK_BUILD_FOR_WIN32)
-    #define WIN32_LEAN_AND_MEAN 1
-    #include <Windows.h>
-    #include <GL/GL.h>
-    #define SK_BENCH_CONTEXT_CHECK (NULL != wglGetCurrentContext())
-    
-    #undef BENCH_GL_FUNCTION_TYPE
-    #define BENCH_GL_FUNCTION_TYPE __stdcall
-
-    #define SK_GL_GET_PROC(F) gBenchGL.f ## F = (BenchGL ## F ## Proc) \
-            wglGetProcAddress("gl" #F);
-    #define SK_GL_GET_PROC_SUFFIX(F, S) gBenchGL.f ## F = (BenchGL##F##Proc)\
-            wglGetProcAddress("gl" #F #S);
-    
-#elif defined(SK_BUILD_FOR_MAC)
-    #include <OpenGL/gl.h>
-    #include <OpenGL/CGLCurrent.h>
-    #define SK_BENCH_CONTEXT_CHECK (NULL != CGLGetCurrentContext())
-    
-#elif defined(SK_BUILD_FOR_UNIX)
-    #include <GL/gl.h>
-    #include <GL/glx.h>
-    #define SK_BENCH_CONTEXT_CHECK (NULL != glXGetCurrentContext())
-    
-    #define SK_GL_GET_PROC(F) gBenchGL.f ## F = (BenchGL ## F ## Proc) \
-            glXGetProcAddressARB(reinterpret_cast<const GLubyte*>("gl" #F));
-    #define SK_GL_GET_PROC_SUFFIX(F, S) gBenchGL.f ## F = (BenchGL##F##Proc)\
-            glXGetProcAddressARB(reinterpret_cast<const GLubyte*>("gl" #F #S));
-#else
-    #error unsupported platform
-#endif
-
-#define BenchGL_TIME_ELAPSED 0x88BF
-#define BenchGL_QUERY_RESULT 0x8866
-#define BenchGL_QUERY_RESULT_AVAILABLE 0x8867
-
-#if defined(SK_BUILD_FOR_WIN32)
-typedef UINT64 BenchGLuint64;
-#else
-#include <stdint.h>
-typedef uint64_t BenchGLuint64;
-#endif
-
-typedef void (BENCH_GL_FUNCTION_TYPE *BenchGLGenQueriesProc) (GLsizei n, GLuint *ids);
-typedef void (BENCH_GL_FUNCTION_TYPE *BenchGLBeginQueryProc) (GLenum target, GLuint id);
-typedef void (BENCH_GL_FUNCTION_TYPE *BenchGLEndQueryProc) (GLenum target);
-typedef void (BENCH_GL_FUNCTION_TYPE *BenchGLDeleteQueriesProc) (GLsizei n, const GLuint *ids);
-typedef void (BENCH_GL_FUNCTION_TYPE *BenchGLGetQueryObjectivProc) (GLuint id, GLenum pname, GLint *params);
-typedef void (BENCH_GL_FUNCTION_TYPE *BenchGLGetQueryObjectui64vProc) (GLuint id, GLenum pname, BenchGLuint64 *params);
-
-struct BenchGLInterface {
-    bool fHasTimer;
-    BenchGLGenQueriesProc fGenQueries;
-    BenchGLBeginQueryProc fBeginQuery;
-    BenchGLEndQueryProc fEndQuery;
-    BenchGLDeleteQueriesProc fDeleteQueries;
-    BenchGLGetQueryObjectivProc fGetQueryObjectiv;
-    BenchGLGetQueryObjectui64vProc fGetQueryObjectui64v;
-};
-
-static bool BenchGLCheckExtension(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;
-}
-
-static BenchGLInterface gBenchGL;
-static bool gBenchGLInterfaceInit = false;
-
-static void BenchGLSetDefaultGLInterface() {
-    gBenchGL.fHasTimer = false;
-    if (gBenchGLInterfaceInit || !SK_BENCH_CONTEXT_CHECK) return;
-
-    const char* glExts =
-        reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
-    const GLboolean ext =
-        BenchGLCheckExtension("GL_EXT_timer_query", glExts);
-    const GLboolean arb =
-        BenchGLCheckExtension("GL_ARB_timer_query", glExts);
-    if (ext || arb) {
-#if defined(SK_BUILD_FOR_MAC)
-        #if GL_EXT_timer_query || GL_ARB_timer_query
-        gBenchGL.fHasTimer = true;
-        gBenchGL.fGenQueries = glGenQueries;
-        gBenchGL.fBeginQuery = glBeginQuery;
-        gBenchGL.fEndQuery = glEndQuery;
-        gBenchGL.fDeleteQueries = glDeleteQueries;
-        gBenchGL.fGetQueryObjectiv = glGetQueryObjectiv;
-        #endif
-        #if GL_ARB_timer_query
-        gBenchGL.fGetQueryObjectui64v = glGetQueryObjectui64v;
-        #elif GL_EXT_timer_query
-        gBenchGL.fGetQueryObjectui64v = glGetQueryObjectui64vEXT;
-        #endif
-#else
-        gBenchGL.fHasTimer = true;
-        SK_GL_GET_PROC(GenQueries)
-        SK_GL_GET_PROC(BeginQuery)
-        SK_GL_GET_PROC(EndQuery)
-        SK_GL_GET_PROC(DeleteQueries)
-        
-        SK_GL_GET_PROC(GetQueryObjectiv)
-        if (arb) {
-            SK_GL_GET_PROC(GetQueryObjectui64v)
-        } else {
-            SK_GL_GET_PROC_SUFFIX(GetQueryObjectui64v, EXT)
-        }
-#endif
-    }
-    gBenchGLInterfaceInit = true;
-}
-
-BenchGpuTimer::BenchGpuTimer() {
-    BenchGLSetDefaultGLInterface();
-    if (gBenchGL.fHasTimer) {
-        gBenchGL.fGenQueries(1, &this->fQuery);
+    if (fSupported) {
+        SK_GL(*glctx, GenQueries(1, &fQuery));
     }
 }
 
 BenchGpuTimer::~BenchGpuTimer() {
-    if (gBenchGL.fHasTimer) {
-        gBenchGL.fDeleteQueries(1, &this->fQuery);
+    if (fSupported) {
+        fContext->makeCurrent();
+        SK_GL(*fContext, DeleteQueries(1, &fQuery));
     }
+    fContext->unref();
 }
 
 void BenchGpuTimer::startGpu() {
-    if (!gBenchGL.fHasTimer) return;
-    
-    this->fStarted = true;
-    gBenchGL.fBeginQuery(BenchGL_TIME_ELAPSED, this->fQuery);
+    if (fSupported) {
+        fContext->makeCurrent();
+        fStarted = true;
+        SK_GL(*fContext, BeginQuery(GR_GL_TIME_ELAPSED, fQuery));
+    }
 }
 
 /**
@@ -168,21 +43,24 @@
  * as this will cpu wait for the gpu to finish.
  */
 double BenchGpuTimer::endGpu() {
-    if (!gBenchGL.fHasTimer) return 0;
-    
-    this->fStarted = false;
-    gBenchGL.fEndQuery(BenchGL_TIME_ELAPSED);
-    
-    GLint available = 0;
-    while (!available) {
-        gBenchGL.fGetQueryObjectiv(this->fQuery
-                                 , BenchGL_QUERY_RESULT_AVAILABLE
-                                 , &available);
+    if (fSupported) {
+        fStarted = false;
+        fContext->makeCurrent();
+        SK_GL(*fContext, EndQuery(GR_GL_TIME_ELAPSED));
+        
+        GrGLint available = 0;
+        while (!available) {
+            SK_GL(*fContext, GetQueryObjectiv(fQuery,
+                                             GR_GL_QUERY_RESULT_AVAILABLE,
+                                             &available));
+        }
+        GrGLuint64 totalGPUTimeElapsed = 0;
+        SK_GL(*fContext, GetQueryObjectui64v(fQuery,
+                                             GR_GL_QUERY_RESULT,
+                                             &totalGPUTimeElapsed));
+        
+        return totalGPUTimeElapsed / 1000000.0;
+    } else {
+        return 0;
     }
-    BenchGLuint64 totalGPUTimeElapsed = 0;
-    gBenchGL.fGetQueryObjectui64v(this->fQuery
-                                , BenchGL_QUERY_RESULT
-                                , &totalGPUTimeElapsed);
-    
-    return totalGPUTimeElapsed / 1000000.0;
 }
diff --git a/bench/BenchGpuTimer_gl.h b/bench/BenchGpuTimer_gl.h
index a393c1d..7c7b5c2 100644
--- a/bench/BenchGpuTimer_gl.h
+++ b/bench/BenchGpuTimer_gl.h
@@ -8,33 +8,19 @@
 #ifndef SkBenchGpuTimer_DEFINED
 #define SkBenchGpuTimer_DEFINED
 
-#if defined(SK_MESA)
-    #include <GL/osmesa.h>
-
-#elif defined(SK_BUILD_FOR_WIN32)
-    #define WIN32_LEAN_AND_MEAN 1
-    #include <Windows.h>
-    #include <GL/GL.h>
-    
-#elif defined(SK_BUILD_FOR_MAC)
-    #include <OpenGL/gl.h>
-    
-#elif defined(SK_BUILD_FOR_UNIX)
-    #include <GL/gl.h>
-
-#else
-    #error unsupported platform
-#endif
+class SkGLContext;
 
 class BenchGpuTimer {
 public:
-    BenchGpuTimer();
+    BenchGpuTimer(const SkGLContext* glctx);
     ~BenchGpuTimer();
     void startGpu();
     double endGpu();
 private:
-    GLuint fQuery;
+    unsigned fQuery;
     int fStarted;
+    const SkGLContext* fContext;
+    bool fSupported;
 };
 
 #endif
diff --git a/bench/BenchGpuTimer_none.cpp b/bench/BenchGpuTimer_none.cpp
deleted file mode 100644
index 5b0bbf8..0000000
--- a/bench/BenchGpuTimer_none.cpp
+++ /dev/null
@@ -1,21 +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 "BenchGpuTimer_none.h"
-
-BenchGpuTimer::BenchGpuTimer() {
-}
-
-BenchGpuTimer::~BenchGpuTimer() {
-}
-
-void BenchGpuTimer::startGpu() {
-}
-
-double BenchGpuTimer::endGpu() {
-    return -1.0;
-}
diff --git a/bench/BenchGpuTimer_none.h b/bench/BenchGpuTimer_none.h
deleted file mode 100644
index 3fad8d8..0000000
--- a/bench/BenchGpuTimer_none.h
+++ /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.
- */
-#ifndef SkBenchGpuTimer_DEFINED
-#define SkBenchGpuTimer_DEFINED
-
-class BenchGpuTimer {
-public:
-    BenchGpuTimer();
-    ~BenchGpuTimer();
-    void startGpu();
-    double endGpu();
-};
-
-#endif
diff --git a/bench/BenchTimer.cpp b/bench/BenchTimer.cpp
index 2297a56..be24a57 100644
--- a/bench/BenchTimer.cpp
+++ b/bench/BenchTimer.cpp
@@ -16,40 +16,40 @@
     #include "BenchSysTimer_c.h"
 #endif
 
-#if defined(SK_MESA) || \
-    defined(SK_BUILD_FOR_WIN32) || \
-    defined(SK_BUILD_FOR_MAC) || \
-    defined(SK_BUILD_FOR_UNIX)
-    #include "BenchGpuTimer_gl.h"
+#include "BenchGpuTimer_gl.h"
 
-#else
-    #include "BenchGpuTimer_none.h"
-#endif
-
-BenchTimer::BenchTimer()
+BenchTimer::BenchTimer(SkGLContext* gl)
         : fCpu(-1.0)
         , fWall(-1.0)
         , fGpu(-1.0)
 {
-    this->fSysTimer = new BenchSysTimer();
-    this->fGpuTimer = new BenchGpuTimer();
+    fSysTimer = new BenchSysTimer();
+    if (gl) {
+        fGpuTimer = new BenchGpuTimer(gl);
+    } else {
+        fGpuTimer = NULL;
+    }
 }
 
 BenchTimer::~BenchTimer() {
-    delete this->fSysTimer;
-    delete this->fGpuTimer;
+    delete fSysTimer;
+    delete fGpuTimer;
 }
 
 void BenchTimer::start() {
-    this->fSysTimer->startWall();
-    this->fGpuTimer->startGpu();
-    this->fSysTimer->startCpu();
+    fSysTimer->startWall();
+    if (fGpuTimer) {
+        fGpuTimer->startGpu();
+    }
+    fSysTimer->startCpu();
 }
 
 void BenchTimer::end() {
-    this->fCpu = this->fSysTimer->endCpu();
+    fCpu = fSysTimer->endCpu();
     //It is important to stop the cpu clocks first,
     //as the following will cpu wait for the gpu to finish.
-    this->fGpu = this->fGpuTimer->endGpu();
-    this->fWall = this->fSysTimer->endWall();
+    if (fGpuTimer) {
+        fGpu = fGpuTimer->endGpu();
+    }
+    fWall = fSysTimer->endWall();
 }
diff --git a/bench/BenchTimer.h b/bench/BenchTimer.h
index e1411d2..080bc6d 100644
--- a/bench/BenchTimer.h
+++ b/bench/BenchTimer.h
@@ -8,9 +8,14 @@
 #ifndef SkBenchTimer_DEFINED
 #define SkBenchTimer_DEFINED
 
+#include <SkTypes.h>
+
+
 class BenchSysTimer;
 class BenchGpuTimer;
 
+class SkGLContext;
+
 /**
  * SysTimers and GpuTimers are implemented orthogonally.
  * This class combines a SysTimer and a GpuTimer into one single,
@@ -18,7 +23,7 @@
  */
 class BenchTimer {
 public:
-    BenchTimer();
+    BenchTimer(SkGLContext* gl = NULL);
     ~BenchTimer();
     void start();
     void end();
diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp
index 3b2be8d..c988e12 100644
--- a/bench/benchmain.cpp
+++ b/bench/benchmain.cpp
@@ -15,7 +15,7 @@
 #include "SkBenchmark.h"
 #include "SkCanvas.h"
 #include "SkColorPriv.h"
-#include "SkGLContext.h"
+#include "SkNativeGLContext.h"
 #include "SkGpuDevice.h"
 #include "SkGraphics.h"
 #include "SkImageEncoder.h"
@@ -416,9 +416,11 @@
     GrRenderTarget* rt = NULL;
     //Don't do GL when fixed.
 #if !defined(SK_SCALAR_IS_FIXED)
-    SkGLContext glContext;
+    SkNativeGLContext glContext;
     if (glContext.init(1024, 1024)) {
-        context = GrContext::CreateGLShaderContext();
+        GrPlatform3DContext ctx =
+            reinterpret_cast<GrPlatform3DContext>(glContext.gl());
+        context = GrContext::Create(kOpenGL_Shaders_GrEngine, ctx);
         if (NULL != context) {
             GrPlatformSurfaceDesc desc;
             desc.reset();
@@ -435,9 +437,11 @@
             }
         }
     }
+    BenchTimer timer = BenchTimer(&glContext);
+#else
+    BenchTimer timer = BenchTimer();
 #endif
     
-    BenchTimer timer = BenchTimer();
     
     Iter iter(&defineDict);
     SkBenchmark* bench;
@@ -500,7 +504,7 @@
                 bench->draw(&canvas);
                 if (gpu) {
                     context->flush();
-                    glFinish();
+                    SK_GL(glContext, Finish());
                 }
             }
             
@@ -513,7 +517,7 @@
                 }
             }
             if (gpu) {
-                glFinish();
+                SK_GL(glContext, Finish());
             }
             timer.end();
             
diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index 1f10c5a..35a14f4 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -12,12 +12,13 @@
 #include "SkColorPriv.h"
 #include "SkData.h"
 #include "SkDevice.h"
-#include "SkGLContext.h"
 #include "SkGpuCanvas.h"
 #include "SkGpuDevice.h"
 #include "SkGraphics.h"
 #include "SkImageDecoder.h"
 #include "SkImageEncoder.h"
+#include "SkNativeGLContext.h"
+#include "SkMesaGLContext.h"
 #include "SkPicture.h"
 #include "SkStream.h"
 #include "SkRefCnt.h"
@@ -522,6 +523,9 @@
     SkDebugf(
 "    --serialize: exercise SkPicture serialization & deserialization.\n");
     SkDebugf("    --match foo will only run tests that substring match foo.\n");
+#if SK_MESA
+    SkDebugf("    --mesagl will run using the osmesa sw gl rasterizer.\n");
+#endif
 }
 
 static const ConfigData gRec[] = {
@@ -557,6 +561,8 @@
     bool doPDF = true;
     bool doReplay = true;
     bool doSerialize = false;
+    bool useMesa = false;
+    
     const char* const commandName = argv[0];
     char* const* stop = argv + argc;
     for (++argv; argv < stop; ++argv) {
@@ -586,6 +592,10 @@
             if (argv < stop && **argv) {
                 matchStr = *argv;
             }
+#if SK_MESA
+        } else if (strcmp(*argv, "--mesagl") == 0) {
+            useMesa = true;
+#endif
         } else {
           usage(commandName);
           return -1;
@@ -606,10 +616,21 @@
         maxH = SkMax32(size.height(), maxH);
     }
     // setup a GL context for drawing offscreen
-    SkGLContext glContext;
+    SkAutoTUnref<SkGLContext> glContext;
+#if SK_MESA
+    if (useMesa) {
+        glContext.reset(new SkMesaGLContext());
+    } else
+#endif
+    {
+        glContext.reset(new SkNativeGLContext());
+    }
+
     GrRenderTarget* rt = NULL;
-    if (glContext.init(maxW, maxH)) {
-        gGrContext = GrContext::CreateGLShaderContext();
+    if (glContext.get()->init(maxW, maxH)) {
+        GrPlatform3DContext ctx =
+            reinterpret_cast<GrPlatform3DContext>(glContext.get()->gl());
+        gGrContext = GrContext::Create(kOpenGL_Shaders_GrEngine, ctx);
         if (NULL != gGrContext) {
             GrPlatformSurfaceDesc desc;
             desc.reset();
@@ -617,7 +638,7 @@
             desc.fWidth = maxW;
             desc.fHeight = maxH;
             desc.fStencilBits = 8;
-            desc.fPlatformRenderTarget = glContext.getFBOID();
+            desc.fPlatformRenderTarget = glContext.get()->getFBOID();
             desc.fSurfaceType = kRenderTarget_GrPlatformSurfaceType;
             rt = static_cast<GrRenderTarget*>(gGrContext->createPlatformSurface(desc));
             if (NULL == rt) {
@@ -625,6 +646,8 @@
                 gGrContext = NULL;
             }
         }
+    } else {
+        fprintf(stderr, "could not create GL context.\n");
     }
 
     if (readPath) {
diff --git a/gyp/bench.gypi b/gyp/bench.gypi
index 3b79380..127c62a 100644
--- a/gyp/bench.gypi
+++ b/gyp/bench.gypi
@@ -13,8 +13,6 @@
     '../bench/BenchSysTimer_windows.cpp',
     '../bench/BenchGpuTimer_gl.h',
     '../bench/BenchGpuTimer_gl.cpp',
-    '../bench/BenchGpuTimer_none.h',
-    '../bench/BenchGpuTimer_none.cpp',
 
     '../bench/SkBenchmark.h',
     '../bench/SkBenchmark.cpp',
@@ -56,17 +54,6 @@
         '../bench/BenchSysTimer_windows.cpp',
       ],
     }],
-    [ 'skia_os in ["win", "mac", "linux", "freebsd", "openbsd", "solaris"]', {
-      'sources!': [
-        '../bench/BenchGpuTimer_none.h',
-        '../bench/BenchGpuTimer_none.cpp',
-      ],
-    },{
-      'sources!': [
-        '../bench/BenchGpuTimer_gl.h',
-        '../bench/BenchGpuTimer_gl.cpp',
-      ],
-    }],
   ],
 }
 
diff --git a/gyp/common.gypi b/gyp/common.gypi
index 51d68e8..30424de 100644
--- a/gyp/common.gypi
+++ b/gyp/common.gypi
@@ -15,6 +15,8 @@
       'conditions': [
         ['skia_os != OS and not (skia_os == "ios" and OS == "mac")',
           {'error': '<!(Cannot build with skia_os=<(skia_os) on OS=<(OS))'}],
+        ['skia_mesa and skia_os not in ["mac", "linux"]',
+          {'error': '<!(skia_mesa=1 only supported with skia_os="mac" or "linux".)'}],
       ],
     },
     'includes': [
@@ -34,6 +36,16 @@
           ],
         }
       ],
+      [ 'skia_mesa', {
+        'defines': [
+          'SK_MESA',
+        ],
+        'direct_dependent_settings': {
+          'defines': [
+            'SK_MESA',
+          ],
+        },
+      }],
     ],
     'configurations': {
       'Debug': {
diff --git a/gyp/common_variables.gypi b/gyp/common_variables.gypi
index 5c27cc3..42e7c22 100644
--- a/gyp/common_variables.gypi
+++ b/gyp/common_variables.gypi
@@ -9,9 +9,11 @@
   'variables': {
     'skia_scalar%': 'float',
     'skia_os%': '<(OS)',
+    'skia_mesa%': 0,
   },
   'skia_scalar%': '<(skia_scalar)',
   'skia_os': '<(skia_os)',
+  'skia_mesa': '<(skia_mesa)',
 }
 
 # Local Variables:
diff --git a/gyp/gpu.gyp b/gyp/gpu.gyp
index 690258a..132b8e9 100644
--- a/gyp/gpu.gyp
+++ b/gyp/gpu.gyp
@@ -96,29 +96,41 @@
         '../include/gpu',
       ],
       'sources': [
+        '../include/gpu/SkGLContext.h',
+        '../include/gpu/SkMesaGLContext.h',
+        '../include/gpu/SkNativeGLContext.h',
         '../include/gpu/SkGpuCanvas.h',
         '../include/gpu/SkGpuDevice.h',
         '../include/gpu/SkGr.h',
         '../include/gpu/SkGrTexturePixelRef.h',
 
         '../src/gpu/GrPrintf_skia.cpp',
+        '../src/gpu/SkGLContext.cpp',
         '../src/gpu/SkGpuCanvas.cpp',
         '../src/gpu/SkGpuDevice.cpp',
         '../src/gpu/SkGr.cpp',
         '../src/gpu/SkGrFontScaler.cpp',
         '../src/gpu/SkGrTexturePixelRef.cpp',
 
-        '../src/gpu/mac/SkGLContext_mac.cpp',
+        '../src/gpu/mac/SkNativeGLContext_mac.cpp',
 
-        '../src/gpu/win/SkGLContext_win.cpp',
+        '../src/gpu/win/SkNativeGLContext_win.cpp',
 
-        '../src/gpu/unix/SkGLContext_unix.cpp',
+        '../src/gpu/unix/SkNativeGLContext_unix.cpp',
 
-        '../src/gpu/mesa/SkGLContext_mesa.cpp',
+        '../src/gpu/mesa/SkMesaGLContext.cpp',
       ],
-      # Removed for now
-      'sources!': [
-        '../src/gpu/mesa/SkGLContext_mesa.cpp',
+      'conditions': [
+        [ 'not skia_mesa', {
+          'sources!': [
+            '../src/gpu/mesa/SkMesaGLContext.cpp',
+          ],
+        }],
+        [ 'skia_mesa and skia_os == "mac"', {
+          'include_dirs': [
+             '$(SDKROOT)/usr/X11/include/',
+          ],
+        }],
       ],
     },
     {
@@ -194,7 +206,9 @@
         '../src/gpu/GrDrawTarget.cpp',
         '../src/gpu/GrDrawTarget.h',
         '../src/gpu/GrGeometryBuffer.h',
+        '../src/gpu/GrGLCreateNativeInterface_none.cpp',
         '../src/gpu/GrGLDefaultInterface_none.cpp',
+        '../src/gpu/GrGLDefaultInterface_native.cpp',
         '../src/gpu/GrGLIndexBuffer.cpp',
         '../src/gpu/GrGLIndexBuffer.h',
         '../src/gpu/GrGLInterface.cpp',
@@ -249,17 +263,14 @@
         '../src/gpu/GrVertexBuffer.h',
         '../src/gpu/gr_unittests.cpp',
 
-        '../src/gpu/mac/GrGLDefaultInterface_mac.cpp',
 
-        '../src/gpu/win/GrGLDefaultInterface_win.cpp',
+        '../src/gpu/mac/GrGLCreateNativeInterface_mac.cpp',
 
-        '../src/gpu/unix/GrGLDefaultInterface_unix.cpp',
+        '../src/gpu/win/GrGLCreateNativeInterface_win.cpp',
 
-        '../src/gpu/mesa/GrGLDefaultInterface_mesa.cpp',
-      ],
-      # Removed for now
-      'sources!': [
-        '../src/gpu/mesa/GrGLDefaultInterface_mesa.cpp',
+        '../src/gpu/unix/GrGLCreateNativeInterface_unix.cpp',
+
+        '../src/gpu/mesa/GrGLCreateMesaInterface.cpp',
       ],
       'defines': [
         'GR_IMPLEMENTATION=1',
@@ -268,6 +279,7 @@
         [ 'skia_os == "linux"', {
           'sources!': [
             '../src/gpu/GrGLDefaultInterface_none.cpp',
+            '../src/gpu/GrGLCreateNativeInterface_none.cpp',
           ],
           'link_settings': {
             'libraries': [
@@ -276,6 +288,13 @@
             ],
           },
         }],
+        [ 'skia_mesa and skia_os == "linux"', {
+          'link_settings': {
+            'libraries': [
+              '-lOSMesa',
+            ],
+          },
+        }],
         [ 'skia_os == "mac"', {
           'link_settings': {
             'libraries': [
@@ -284,11 +303,28 @@
           },
           'sources!': [
             '../src/gpu/GrGLDefaultInterface_none.cpp',
+            '../src/gpu/GrGLCreateNativeInterface_none.cpp',
           ],
-          }],
+        }],
+        [ 'skia_mesa and skia_os == "mac"', {
+          'link_settings': {
+            'libraries': [
+              '$(SDKROOT)/usr/X11/lib/libOSMesa.dylib',
+            ],
+          },
+          'include_dirs': [
+             '$(SDKROOT)/usr/X11/include/',
+          ],
+        }],
+        [ 'not skia_mesa', {
+          'sources!': [
+            '../src/gpu/mesa/GrGLCreateMesaInterface.cpp',
+          ],
+        }],
         [ 'skia_os == "win"', {
           'sources!': [
             '../src/gpu/GrGLDefaultInterface_none.cpp',
+            '../src/gpu/GrGLCreateNativeInterface_none.cpp',
           ],
         }],
       ],
diff --git a/include/gpu/GrGLDefines.h b/include/gpu/GrGLDefines.h
index dcacb77..7a3d676 100644
--- a/include/gpu/GrGLDefines.h
+++ b/include/gpu/GrGLDefines.h
@@ -589,6 +589,19 @@
 #define GR_GL_MEDIUM_INT                     0x8DF4
 #define GR_GL_HIGH_INT                       0x8DF5
 
+/* Queries */
+#define GR_GL_QUERY_COUNTER_BITS             0x8864
+#define GR_GL_CURRENT_QUERY                  0x8865
+#define GR_GL_QUERY_RESULT                   0x8866
+#define GR_GL_QUERY_RESULT_AVAILABLE         0x8867
+#define GR_GL_SAMPLES_PASSED                 0x8914
+#define GR_GL_ANY_SAMPLES_PASSED             0x8C2F
+#define GR_GL_TIME_ELAPSED                   0x88BF
+#define GR_GL_TIMESTAMP                      0x8E28
+#define GR_GL_PRIMITIVES_GENERATED           0x8C87
+#define GR_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+
+
 /* Framebuffer Object. */
 #define GR_GL_FRAMEBUFFER                    0x8D40
 #define GR_GL_READ_FRAMEBUFFER               0x8CA8
diff --git a/include/gpu/GrGLInterface.h b/include/gpu/GrGLInterface.h
index 8271dcb..b3e0cf1 100644
--- a/include/gpu/GrGLInterface.h
+++ b/include/gpu/GrGLInterface.h
@@ -38,7 +38,7 @@
 bool GrGLHasExtensionFromString(const char* ext, const char* extensionString);
 
 // these variants call glGetString()
-bool GrGLGetString(const GrGLInterface*, const char* ext);
+bool GrGLHasExtension(const GrGLInterface*, const char* ext);
 GrGLVersion GrGLGetVersion(const GrGLInterface*);
 GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface*);
 
@@ -69,6 +69,10 @@
 
 const GrGLInterface* GrGLDefaultInterface();
 
+const GrGLInterface* GrGLCreateNativeInterface();
+
+const GrGLInterface* GrGLCreateMesaInterface();
+
 typedef unsigned int GrGLenum;
 typedef unsigned char GrGLboolean;
 typedef unsigned int GrGLbitfield;
@@ -77,9 +81,11 @@
 typedef short GrGLshort;
 typedef int GrGLint;
 typedef int GrGLsizei;
+typedef int64_t GrGLint64;
 typedef unsigned char GrGLubyte;
 typedef unsigned short GrGLushort;
 typedef unsigned int GrGLuint;
+typedef uint64_t GrGLuint64;
 typedef float GrGLfloat;
 typedef float GrGLclampf;
 typedef double GrGLdouble;
@@ -97,6 +103,7 @@
 extern "C" {
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLActiveTextureProc)(GrGLenum texture);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLAttachShaderProc)(GrGLuint program, GrGLuint shader);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBeginQueryProc)(GrGLenum target, GrGLuint id);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBindAttribLocationProc)(GrGLuint program, GrGLuint index, const char* name);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBindBufferProc)(GrGLenum target, GrGLuint buffer);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBindTextureProc)(GrGLenum target, GrGLuint texture);
@@ -119,6 +126,7 @@
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLCullFaceProc)(GrGLenum mode);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteBuffersProc)(GrGLsizei n, const GrGLuint* buffers);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteProgramProc)(GrGLuint program);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteQueriesProc)(GrGLsizei n, const GrGLuint *ids);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteShaderProc)(GrGLuint shader);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteTexturesProc)(GrGLsizei n, const GrGLuint* textures);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDepthMaskProc)(GrGLboolean flag);
@@ -132,18 +140,27 @@
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLEnableProc)(GrGLenum cap);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLEnableClientStateProc)(GrGLenum cap);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLEnableVertexAttribArrayProc)(GrGLuint index);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLEndQueryProc)(GrGLenum target);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLFinishProc)();
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLFlushProc)();
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLFrontFaceProc)(GrGLenum mode);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGenBuffersProc)(GrGLsizei n, GrGLuint* buffers);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGenQueriesProc)(GrGLsizei n, GrGLuint *ids);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGenTexturesProc)(GrGLsizei n, GrGLuint* textures);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetBufferParameterivProc)(GrGLenum target, GrGLenum pname, GrGLint* params);
-    typedef GrGLenum (GR_GL_FUNCTION_TYPE *GrGLGetErrorProc)(void);
+    typedef GrGLenum (GR_GL_FUNCTION_TYPE *GrGLGetErrorProc)();
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetIntegervProc)(GrGLenum pname, GrGLint* params);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetProgramInfoLogProc)(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length, char* infolog);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetProgramivProc)(GrGLuint program, GrGLenum pname, GrGLint* params);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetQueryivProc)(GrGLenum GLtarget, GrGLenum pname, GrGLint *params);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetQueryObjecti64vProc)(GrGLuint id, GrGLenum pname, GrGLint64 *params);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetQueryObjectivProc)(GrGLuint id, GrGLenum pname, GrGLint *params);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetQueryObjectui64vProc)(GrGLuint id, GrGLenum pname, GrGLuint64 *params);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetQueryObjectuivProc)(GrGLuint id, GrGLenum pname, GrGLuint *params);    
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetShaderInfoLogProc)(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length, char* infolog);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetShaderivProc)(GrGLuint shader, GrGLenum pname, GrGLint* params);
     typedef const GrGLubyte* (GR_GL_FUNCTION_TYPE *GrGLGetStringProc)(GrGLenum name);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetTexLevelParameteriv)(GrGLenum target, GrGLint level, GrGLenum pname, GrGLint* params);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetTexLevelParameterivProc)(GrGLenum target, GrGLint level, GrGLenum pname, GrGLint* params);
     typedef GrGLint (GR_GL_FUNCTION_TYPE *GrGLGetUniformLocationProc)(GrGLuint program, const char* name);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLLineWidthProc)(GrGLfloat width);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLLinkProgramProc)(GrGLuint program);
@@ -151,6 +168,7 @@
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLMatrixModeProc)(GrGLenum mode);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLPixelStoreiProc)(GrGLenum pname, GrGLint param);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLPointSizeProc)(GrGLfloat size);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLQueryCounterProc)(GrGLuint id, GrGLenum target);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLReadBufferProc)(GrGLenum src);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLReadPixelsProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLScissorProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height);
@@ -276,6 +294,7 @@
 
     GrGLActiveTextureProc fActiveTexture;
     GrGLAttachShaderProc fAttachShader;
+    GrGLBeginQueryProc fBeginQuery;
     GrGLBindAttribLocationProc fBindAttribLocation;
     GrGLBindBufferProc fBindBuffer;
     GrGLBindFragDataLocationProc fBindFragDataLocation;
@@ -298,6 +317,7 @@
     GrGLCullFaceProc fCullFace;
     GrGLDeleteBuffersProc fDeleteBuffers;
     GrGLDeleteProgramProc fDeleteProgram;
+    GrGLDeleteQueriesProc fDeleteQueries;
     GrGLDeleteShaderProc fDeleteShader;
     GrGLDeleteTexturesProc fDeleteTextures;
     GrGLDepthMaskProc fDepthMask;
@@ -311,18 +331,27 @@
     GrGLEnableProc fEnable;
     GrGLEnableClientStateProc fEnableClientState;
     GrGLEnableVertexAttribArrayProc fEnableVertexAttribArray;
+    GrGLEndQueryProc fEndQuery;
+    GrGLFinishProc fFinish;
+    GrGLFlushProc fFlush;
     GrGLFrontFaceProc fFrontFace;
     GrGLGenBuffersProc fGenBuffers;
+    GrGLGenQueriesProc fGenQueries;
     GrGLGenTexturesProc fGenTextures;
     GrGLGetBufferParameterivProc fGetBufferParameteriv;
     GrGLGetErrorProc fGetError;
     GrGLGetIntegervProc fGetIntegerv;
+    GrGLGetQueryObjecti64vProc fGetQueryObjecti64v;
+    GrGLGetQueryObjectivProc fGetQueryObjectiv;
+    GrGLGetQueryObjectui64vProc fGetQueryObjectui64v;
+    GrGLGetQueryObjectuivProc fGetQueryObjectuiv;
+    GrGLGetQueryivProc fGetQueryiv;
     GrGLGetProgramInfoLogProc fGetProgramInfoLog;
     GrGLGetProgramivProc fGetProgramiv;
     GrGLGetShaderInfoLogProc fGetShaderInfoLog;
     GrGLGetShaderivProc fGetShaderiv;
     GrGLGetStringProc fGetString;
-    GrGLGetTexLevelParameteriv fGetTexLevelParameteriv;
+    GrGLGetTexLevelParameterivProc fGetTexLevelParameteriv;
     GrGLGetUniformLocationProc fGetUniformLocation;
     GrGLLineWidthProc fLineWidth;
     GrGLLinkProgramProc fLinkProgram;
@@ -330,6 +359,7 @@
     GrGLMatrixModeProc fMatrixMode;
     GrGLPixelStoreiProc fPixelStorei;
     GrGLPointSizeProc fPointSize;
+    GrGLQueryCounterProc fQueryCounter;
     GrGLReadBufferProc fReadBuffer;
     GrGLReadPixelsProc fReadPixels;
     GrGLScissorProc fScissor;
diff --git a/include/gpu/SkGLContext.h b/include/gpu/SkGLContext.h
index 2e8a8ab..d36a9f9 100644
--- a/include/gpu/SkGLContext.h
+++ b/include/gpu/SkGLContext.h
@@ -8,51 +8,49 @@
 #ifndef SkGLContext_DEFINED
 #define SkGLContext_DEFINED
 
-#if defined(SK_MESA)
-    #include "GL/osmesa.h"
-#elif defined(SK_BUILD_FOR_MAC)
-    #include <AGL/agl.h>
-#elif defined(SK_BUILD_FOR_UNIX)
-    #include <X11/Xlib.h>
-    #include <GL/glx.h>
-#elif defined(SK_BUILD_FOR_WIN32)
-    #include <Windows.h>
-    #include <GL/GL.h>
-#else
-
-#endif
+#include "GrGLInterface.h"
 
 /**
- *  Create an offscreen opengl context with an RGBA8 / 8bit stencil FBO.
+ * Create an offscreen opengl context with an RGBA8 / 8bit stencil FBO.
+ * Provides a GrGLInterface struct of function pointers for the context.
  */
-class SkGLContext {
+
+class SkGLContext : public SkRefCnt {
 public:
     SkGLContext();
-    ~SkGLContext();
+    virtual ~SkGLContext();
 
     bool init(const int width, const int height);
 
     int getFBOID() const { return fFBO; }
 
-private:
-    GLuint fFBO;
-#if defined(SK_MESA)
-    OSMesaContext context;
-    GLfloat *image;
-#elif defined(SK_BUILD_FOR_MAC)
-    AGLContext context;
-#elif defined(SK_BUILD_FOR_UNIX)
-    GLXContext context;
-    Display *display;
-    Pixmap pixmap;
-    GLXPixmap glxPixmap;
-#elif defined(SK_BUILD_FOR_WIN32)
-    HWND fWindow;
-    HDC fDeviceContext;
-    HGLRC fGlRenderContext;
-#else
+    const GrGLInterface* gl() const { return fGL; }
 
-#endif
+    virtual void makeCurrent() const = 0;
+
+protected:
+    /**
+     * Subclass implements this to make a GL context. The returned GrGLInterface 
+     * should be populated with functions compatible with the context. The 
+     * format and size of backbuffers does not matter since an FBO will be
+     * created.
+     */
+    virtual const GrGLInterface* createGLContext() = 0;
+
+    /**
+     * Subclass should destroy the underlying GL context.
+     */
+    virtual void destroyGLContext() = 0;
+
+private:
+    GrGLuint fFBO;
+    const GrGLInterface* fGL;
 };
 
+/**
+ * Helper macro for using the GL context through the GrGLInterface. Example:
+ * SK_GL(glCtx, GenTextures(1, &texID));
+ */
+#define SK_GL(ctx, X) (ctx).gl()->f ## X
+
 #endif
diff --git a/include/gpu/SkMesaGLContext.h b/include/gpu/SkMesaGLContext.h
new file mode 100644
index 0000000..4351f66
--- /dev/null
+++ b/include/gpu/SkMesaGLContext.h
@@ -0,0 +1,35 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkMesaGLContext_DEFINED
+#define SkMesaGLContext_DEFINED
+
+#include "SkGLContext.h"
+
+#if SK_MESA
+
+class SkMesaGLContext : public SkGLContext {
+public:
+    SkMesaGLContext();
+
+    virtual ~SkMesaGLContext();
+
+    virtual void makeCurrent() const SK_OVERRIDE;
+
+protected:
+    virtual const GrGLInterface* createGLContext() SK_OVERRIDE;
+    void destroyGLContext() SK_OVERRIDE;
+
+private:
+    typedef intptr_t Context;
+    Context fContext;
+    GrGLubyte *fImage;
+};
+
+#endif
+
+#endif
\ No newline at end of file
diff --git a/include/gpu/SkNativeGLContext.h b/include/gpu/SkNativeGLContext.h
new file mode 100644
index 0000000..512e66a
--- /dev/null
+++ b/include/gpu/SkNativeGLContext.h
@@ -0,0 +1,51 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkNativeGLContext_DEFINED
+#define SkNativeGLContext_DEFINED
+
+#include "SkGLContext.h"
+
+#if defined(SK_BUILD_FOR_MAC)
+    #include <AGL/agl.h>
+#elif defined(SK_BUILD_FOR_UNIX)
+    #include <X11/Xlib.h>
+    #include <GL/glx.h>
+#elif defined(SK_BUILD_FOR_WIN32)
+    #include <Windows.h>
+    #include <GL/GL.h>
+#endif
+
+class SkNativeGLContext : public SkGLContext {
+public:
+    SkNativeGLContext();
+
+    virtual ~SkNativeGLContext();
+
+    virtual void makeCurrent() const SK_OVERRIDE;
+
+protected:
+    virtual const GrGLInterface* createGLContext() SK_OVERRIDE;
+    void destroyGLContext() SK_OVERRIDE;
+
+private:
+#if defined(SK_BUILD_FOR_MAC)
+    AGLContext fContext;
+#elif defined(SK_BUILD_FOR_UNIX)
+    GLXContext fContext;
+    Display* fDisplay;
+    Pixmap fPixmap;
+    GLXPixmap fGlxPixmap;
+#elif defined(SK_BUILD_FOR_WIN32)
+    HWND fWindow;
+    HDC fDeviceContext;
+    HGLRC fGlRenderContext;
+    static ATOM gWC;
+#endif
+};
+
+#endif
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");
+    }
+}
diff --git a/tests/Test.cpp b/tests/Test.cpp
index 55d884d..d91eeed 100644
--- a/tests/Test.cpp
+++ b/tests/Test.cpp
@@ -8,7 +8,7 @@
 #include "Test.h"
 
 #include "GrContext.h"
-#include "SkGLContext.h"
+#include "SkNativeGLContext.h"
 #include "SkTLazy.h"
 
 using namespace skiatest;
@@ -79,13 +79,14 @@
 
 GrContext* GpuTest::GetContext() {
     // preserve this order, we want gGrContext destroyed after gEGLContext
-    static SkTLazy<SkGLContext> gGLContext;
+    static SkTLazy<SkNativeGLContext> gGLContext;
     static SkAutoTUnref<GrContext> gGrContext;
 
     if (NULL == gGrContext.get()) {
         gGLContext.init();
         if (gGLContext.get()->init(800, 600)) {
-            gGrContext.reset(GrContext::Create(kOpenGL_Shaders_GrEngine, NULL));
+            GrPlatform3DContext ctx = reinterpret_cast<GrPlatform3DContext>(gGLContext.get()->gl());
+            gGrContext.reset(GrContext::Create(kOpenGL_Shaders_GrEngine, ctx));
         }
     }
     return gGrContext.get();