diff options
author | 2011-10-19 20:43:20 +0000 | |
---|---|---|
committer | 2011-10-19 20:43:20 +0000 | |
commit | 373a6635b7190b4af4d265fdd4b70f102ec3a6fd (patch) | |
tree | dfa02655ebe3cc2f4f3ead29426c2eb1a80adcf9 /src | |
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
Diffstat (limited to 'src')
19 files changed, 629 insertions, 620 deletions
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"); + } +} |