diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-10-19 20:43:20 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-10-19 20:43:20 +0000 |
commit | 373a6635b7190b4af4d265fdd4b70f102ec3a6fd (patch) | |
tree | dfa02655ebe3cc2f4f3ead29426c2eb1a80adcf9 | |
parent | 5960d0049585d66efdba058a0930870dafd44079 (diff) |
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
37 files changed, 973 insertions, 943 deletions
diff --git a/bench/BenchGpuTimer_gl.cpp b/bench/BenchGpuTimer_gl.cpp index 7236231b25..885f7b2bfa 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> - -//GL -#define BENCH_GL_FUNCTION_TYPE -#if defined(SK_MESA) - #include <GL/osmesa.h> - #define SK_BENCH_CONTEXT_CHECK (NULL != OSMesaGetCurrentContext()) - - #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); +#include "SkGLContext.h" + +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"); -#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 @@ void BenchGpuTimer::startGpu() { * 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 a393c1dc28..7c7b5c2949 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 5b0bbf803b..0000000000 --- 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 3fad8d84f9..0000000000 --- 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 2297a56072..be24a57568 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 e1411d261a..080bc6db10 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 BenchGpuTimer; */ class BenchTimer { public: - BenchTimer(); + BenchTimer(SkGLContext* gl = NULL); ~BenchTimer(); void start(); void end(); diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp index 3b2be8dc60..c988e12db1 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 @@ int main (int argc, char * const argv[]) { 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 @@ int main (int argc, char * const argv[]) { } } } + BenchTimer timer = BenchTimer(&glContext); +#else + BenchTimer timer = BenchTimer(); #endif - BenchTimer timer = BenchTimer(); Iter iter(&defineDict); SkBenchmark* bench; @@ -500,7 +504,7 @@ int main (int argc, char * const argv[]) { bench->draw(&canvas); if (gpu) { context->flush(); - glFinish(); + SK_GL(glContext, Finish()); } } @@ -513,7 +517,7 @@ int main (int argc, char * const argv[]) { } } if (gpu) { - glFinish(); + SK_GL(glContext, Finish()); } timer.end(); diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp index 1f10c5a944..35a14f4896 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 @@ static void usage(const char * argv0) { 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 @@ int main(int argc, char * const argv[]) { 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 @@ int main(int argc, char * const argv[]) { 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 @@ int main(int argc, char * const argv[]) { 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 @@ int main(int argc, char * const argv[]) { 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 @@ int main(int argc, char * const argv[]) { gGrContext = NULL; } } + } else { + fprintf(stderr, "could not create GL context.\n"); } if (readPath) { diff --git a/gyp/bench.gypi b/gyp/bench.gypi index 3b79380eec..127c62a56c 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 51d68e8778..30424de9fd 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 5c27cc37c1..42e7c22f1f 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 690258a1a9..132b8e96ab 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 dcacb77686..7a3d6767fa 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 8271dcbe93..b3e0cf191b 100644 --- a/include/gpu/GrGLInterface.h +++ b/include/gpu/GrGLInterface.h @@ -38,7 +38,7 @@ GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString); 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 @@ struct GrGLInterface; 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 char GrGLchar; 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 @@ enum GrGLBinding { 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 @@ extern "C" { 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 @@ extern "C" { 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 @@ extern "C" { 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 @@ struct GR_API GrGLInterface : public GrRefCnt { GrGLActiveTextureProc fActiveTexture; GrGLAttachShaderProc fAttachShader; + GrGLBeginQueryProc fBeginQuery; GrGLBindAttribLocationProc fBindAttribLocation; GrGLBindBufferProc fBindBuffer; GrGLBindFragDataLocationProc fBindFragDataLocation; @@ -298,6 +317,7 @@ struct GR_API GrGLInterface : public GrRefCnt { GrGLCullFaceProc fCullFace; GrGLDeleteBuffersProc fDeleteBuffers; GrGLDeleteProgramProc fDeleteProgram; + GrGLDeleteQueriesProc fDeleteQueries; GrGLDeleteShaderProc fDeleteShader; GrGLDeleteTexturesProc fDeleteTextures; GrGLDepthMaskProc fDepthMask; @@ -311,18 +331,27 @@ struct GR_API GrGLInterface : public GrRefCnt { 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 @@ struct GR_API GrGLInterface : public GrRefCnt { 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 2e8a8abd65..d36a9f9d43 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 0000000000..4351f66f33 --- /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 0000000000..512e66a3ab --- /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 0000000000..7de59126ce --- /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 0000000000..7b8b84a9a8 --- /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 70dd019f83..db57947885 100644 --- a/src/gpu/GrGLInterface.cpp +++ b/src/gpu/GrGLInterface.cpp @@ -345,6 +345,8 @@ bool GrGLInterface::validate(GrEngine engine) const { NULL == fCheckFramebufferStatus || NULL == fDeleteFramebuffers || NULL == fDeleteRenderbuffers || + NULL == fFinish || + NULL == fFlush || NULL == fFramebufferRenderbuffer || NULL == fFramebufferTexture2D || NULL == fGetFramebufferAttachmentParameteriv || @@ -417,6 +419,32 @@ bool GrGLInterface::validate(GrEngine engine) const { 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 e05b6c3880..26ada9c988 100644 --- a/src/gpu/GrGLProgram.cpp +++ b/src/gpu/GrGLProgram.cpp @@ -363,13 +363,13 @@ namespace { 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 @@ bool decl_and_get_fs_color_output(GrGLProgram::GLSLVersion v, 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 @@ bool GrGLProgram::CompileShaders(const GrGLInterface* gl, 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 @@ bool GrGLProgram::CompileShaders(const GrGLInterface* gl, 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 678a56d1d8..e0ae4ebea5 100644 --- a/src/gpu/GrGLProgram.h +++ b/src/gpu/GrGLProgram.h @@ -35,10 +35,21 @@ struct ShaderCodeSegments; */ 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 71444daf77..0742c3bdd9 100644 --- a/src/gpu/GrGpuGLShaders.cpp +++ b/src/gpu/GrGpuGLShaders.cpp @@ -149,22 +149,22 @@ GrGLProgram::GLSLVersion get_glsl_version(GrGLBinding binding, 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 0000000000..c50ee6ee1f --- /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 921f583f54..0000000000 --- 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 index ba43975406..c0e93d7819 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 @@ const GrGLInterface* GrGLDefaultInterface() { 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 @@ const GrGLInterface* GrGLDefaultInterface() { 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 @@ const GrGLInterface* GrGLDefaultInterface() { 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 @@ const GrGLInterface* GrGLDefaultInterface() { 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 @@ const GrGLInterface* GrGLDefaultInterface() { 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 @@ const GrGLInterface* GrGLDefaultInterface() { 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 0992be84d4..0000000000 --- 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 0000000000..3f864c2e01 --- /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 index 793e65c61e..f7d162668d 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 @@ const GrGLInterface* GrGLDefaultInterface() { 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 @@ const GrGLInterface* GrGLDefaultInterface() { 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 6ba42e749d..0000000000 --- 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 0000000000..23ccc9593e --- /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 index 041caec1c5..90338a5992 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 @@ const GrGLInterface* GrGLDefaultInterface() { 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 @@ const GrGLInterface* GrGLDefaultInterface() { 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 @@ const GrGLInterface* GrGLDefaultInterface() { 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 @@ const GrGLInterface* GrGLDefaultInterface() { 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/SkNativeGLContext_unix.cpp index ea15a4b0e2..870ff45a4f 100644 --- a/src/gpu/unix/SkGLContext_unix.cpp +++ b/src/gpu/unix/SkNativeGLContext_unix.cpp @@ -5,17 +5,10 @@ * 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 "SkNativeGLContext.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) { @@ -23,75 +16,76 @@ static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) { return 0; } -SkGLContext::SkGLContext() - : fFBO(0) - , context(NULL) - , display(NULL) - , pixmap(0) - , glxPixmap(0) { +SkNativeGLContext::SkNativeGLContext() + : fContext(NULL) + , fDisplay(NULL) + , fPixmap(0) + , fGlxPixmap(0) { } -SkGLContext::~SkGLContext() { - if (this->display) { - glXMakeCurrent(this->display, 0, 0); +SkNativeGLContext::~SkNativeGLContext() { + this->destroyGLContext(); +} + +void SkNativeGLContext::destroyGLContext() { + if (fDisplay) { + glXMakeCurrent(fDisplay, 0, 0); - if (this->context) - glXDestroyContext(this->display, this->context); + if (fContext) { + glXDestroyContext(fDisplay, fContext); + fContext = NULL; + } - if (this->glxPixmap) - glXDestroyGLXPixmap(this->display, this->glxPixmap); + if (fGlxPixmap) { + glXDestroyGLXPixmap(fDisplay, fGlxPixmap); + fGlxPixmap = 0; + } - if (this->pixmap) - XFreePixmap(this->display, this->pixmap); + if (fPixmap) { + XFreePixmap(fDisplay, fPixmap); + fPixmap = 0; + } - XCloseDisplay(this->display); + XCloseDisplay(fDisplay); + fDisplay = NULL; } } -bool SkGLContext::init(const int width, const int height) { - Display *display = XOpenDisplay(0); - this->display = display; +const GrGLInterface* SkNativeGLContext::createGLContext() { + fDisplay = XOpenDisplay(0); - if (!display) { + if (!fDisplay) { SkDebugf("Failed to open X display.\n"); - return false; + this->destroyGLContext(); + return NULL; } // 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) || + if (!glXQueryVersion(fDisplay, &glx_major, &glx_minor) || ( (glx_major == 1) && (glx_minor < 3) ) || (glx_major < 1)) { SkDebugf("Invalid GLX version."); - return false; + this->destroyGLContext(); + return NULL; } //SkDebugf("Getting matching framebuffer configs.\n"); int fbcount; - GLXFBConfig *fbc = glXChooseFBConfig(display, DefaultScreen(display), + GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), visual_attribs, &fbcount); if (!fbc) { SkDebugf("Failed to retrieve a framebuffer config.\n"); - return false; + this->destroyGLContext(); + return NULL; } //SkDebugf("Found %d matching FB configs.\n", fbcount); @@ -101,11 +95,11 @@ bool SkGLContext::init(const int width, const int height) { int i; for (i = 0; i < fbcount; ++i) { - XVisualInfo *vi = glXGetVisualFromFBConfig(display, fbc[i]); + XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, fbc[i]); if (vi) { int samp_buf, samples; - glXGetFBConfigAttrib(display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf); - glXGetFBConfigAttrib(display, fbc[i], GLX_SAMPLES, &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", @@ -125,27 +119,23 @@ bool SkGLContext::init(const int width, const int height) { XFree(fbc); // Get a visual - XVisualInfo *vi = glXGetVisualFromFBConfig(display, bestFbc); + XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc); //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid); - Pixmap pixmap = XCreatePixmap( - display, RootWindow(display, vi->screen), width, height, vi->depth - ); + fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10, vi->depth); - this->pixmap = pixmap; - if (!pixmap) { + if (!fPixmap) { SkDebugf("Failed to create pixmap.\n"); - return false; + this->destroyGLContext(); + return NULL; } - GLXPixmap glxPixmap = glXCreateGLXPixmap(display, vi, pixmap); - this->glxPixmap = glxPixmap; + fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap); // 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. @@ -160,7 +150,7 @@ bool SkGLContext::init(const int width, const int height) { // Get the default screen's GLX extension list const char *glxExts = glXQueryExtensionsString( - display, DefaultScreen(display) + 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. @@ -170,25 +160,26 @@ bool SkGLContext::init(const int width, const int height) { { //SkDebugf("GLX_ARB_create_context not found." // " Using old-style GLX context.\n"); - ctx = glXCreateNewContext(display, bestFbc, GLX_RGBA_TYPE, 0, True); + fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True); } else { //SkDebugf("Creating context.\n"); - SK_GL_GET_PROC(PFNGLXCREATECONTEXTATTRIBSARBPROC, glXCreateContextAttribsARB) + 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 }; - ctx = glXCreateContextAttribsARB( - display, bestFbc, 0, True, context_attribs + fContext = glXCreateContextAttribsARB( + fDisplay, bestFbc, 0, True, context_attribs ); // Sync to ensure any errors generated are processed. - XSync(display, False); - if (!ctxErrorOccurred && ctx) { + XSync(fDisplay, False); + if (!ctxErrorOccurred && fContext) { //SkDebugf( "Created GL 3.0 context.\n" ); } else { // Couldn't create GL 3.0 context. @@ -206,70 +197,49 @@ bool SkGLContext::init(const int width, const int height) { //SkDebugf("Failed to create GL 3.0 context." // " Using old-style GLX context.\n"); - ctx = glXCreateContextAttribsARB( - display, bestFbc, 0, True, context_attribs + fContext = glXCreateContextAttribsARB( + fDisplay, bestFbc, 0, True, context_attribs ); } } // Sync to ensure any errors generated are processed. - XSync(display, False); + XSync(fDisplay, False); // Restore the original error handler XSetErrorHandler(oldHandler); - if (ctxErrorOccurred || !ctx) { + if (ctxErrorOccurred || !fContext) { SkDebugf("Failed to create an OpenGL context.\n"); - return false; + this->destroyGLContext(); + return NULL; } - this->context = ctx; // Verify that context is a direct context - if (!glXIsDirect(display, ctx)) { + 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(display, glxPixmap, ctx)) { + if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { SkDebugf("Could not set the context.\n"); - return false; + this->destroyGLContext(); + return NULL; } - //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; + 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"); } - 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/win/GrGLDefaultInterface_win.cpp b/src/gpu/win/GrGLCreateNativeInterface_win.cpp index 609869f83d..d0189064f7 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 @@ const GrGLInterface* GrGLDefaultInterface() { 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 dc24af33ef..0000000000 --- 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 0000000000..c19f7cca45 --- /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 55d884d255..d91eeedb8f 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 @@ bool Test::run() { 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(); |