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();