diff options
Diffstat (limited to 'src/gpu/gl')
-rw-r--r-- | src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp | 273 | ||||
-rw-r--r-- | src/gpu/gl/mac/SkNativeGLContext_mac.cpp | 74 | ||||
-rw-r--r-- | src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp | 197 | ||||
-rw-r--r-- | src/gpu/gl/mesa/SkMesaGLContext.cpp | 103 | ||||
-rw-r--r-- | src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp | 200 | ||||
-rw-r--r-- | src/gpu/gl/unix/SkNativeGLContext_unix.cpp | 287 | ||||
-rw-r--r-- | src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp | 206 | ||||
-rw-r--r-- | src/gpu/gl/win/SkNativeGLContext_win.cpp | 137 |
8 files changed, 1477 insertions, 0 deletions
diff --git a/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp b/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp new file mode 100644 index 0000000000..5ae214ae9e --- /dev/null +++ b/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp @@ -0,0 +1,273 @@ + +/* + * 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/GrGLInterface.h" + +#include <OpenGL/gl.h> +#include <OpenGL/glext.h> + +#include <mach-o/dyld.h> + + +// This uses deprecated functions, should rewrite using dlopen, dlsym, dlclose +void* GetProcAddress(const char* name) { + NSSymbol symbol = NULL; + if (NSIsSymbolNameDefined(name)) { + symbol = NSLookupAndBindSymbol(name); + } + return NULL == symbol ? NULL : NSAddressOfSymbol(symbol); +} + +#define GET_PROC(name) ((GrGL ## name ## Proc) GetProcAddress("_gl" #name)) +#define GET_PROC_SUFFIX(name, suffix) ((GrGL ## name ## Proc) GetProcAddress("_gl" #name #suffix)) + +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; + glInterface.reset(interface); + const char* verStr = (const char*) glGetString(GL_VERSION); + GrGLVersion ver = GrGLGetVersionFromString(verStr); + const char* extStr = (const char*) glGetString(GL_EXTENSIONS); + + interface->fBindingsExported = kDesktop_GrGLBinding; + interface->fActiveTexture = glActiveTexture; + interface->fAttachShader = glAttachShader; + interface->fBeginQuery = glBeginQuery; + interface->fBindAttribLocation = glBindAttribLocation; + interface->fBindBuffer = glBindBuffer; + if (ver >= GR_GL_VER(3,0)) { + #if GL_VERSION_3_0 + interface->fBindFragDataLocation = glBindFragDataLocation; + #else + interface->fBindFragDataLocation = GET_PROC(BindFragDataLocation); + #endif + } + interface->fBindTexture = glBindTexture; + interface->fBlendColor = glBlendColor; + interface->fBlendFunc = glBlendFunc; + interface->fBufferData = glBufferData; + interface->fBufferSubData = glBufferSubData; + interface->fClear = glClear; + interface->fClearColor = glClearColor; + interface->fClearStencil = glClearStencil; + interface->fColorMask = glColorMask; + interface->fColorPointer = glColorPointer; + interface->fCompileShader = glCompileShader; + interface->fCompressedTexImage2D = glCompressedTexImage2D; + interface->fCreateProgram = glCreateProgram; + interface->fCreateShader = glCreateShader; + 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->fDisableVertexAttribArray = + glDisableVertexAttribArray; + interface->fDrawArrays = glDrawArrays; + interface->fDrawBuffer = glDrawBuffer; + interface->fDrawBuffers = glDrawBuffers; + interface->fDrawElements = glDrawElements; + interface->fEnable = glEnable; + 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; + interface->fGetTexLevelParameteriv = glGetTexLevelParameteriv; + interface->fGenTextures = glGenTextures; + interface->fGetUniformLocation = glGetUniformLocation; + interface->fLineWidth = glLineWidth; + interface->fLinkProgram = glLinkProgram; + interface->fMapBuffer = glMapBuffer; + interface->fPixelStorei = glPixelStorei; + interface->fReadBuffer = glReadBuffer; + interface->fReadPixels = glReadPixels; + interface->fScissor = glScissor; + interface->fShaderSource = glShaderSource; + interface->fStencilFunc = glStencilFunc; + interface->fStencilFuncSeparate = glStencilFuncSeparate; + interface->fStencilMask = glStencilMask; + interface->fStencilMaskSeparate = glStencilMaskSeparate; + interface->fStencilOp = glStencilOp; + interface->fStencilOpSeparate = glStencilOpSeparate; + // mac uses GLenum for internalFormat param (non-standard) + // amounts to int vs. uint. + interface->fTexImage2D = (GrGLTexImage2DProc)glTexImage2D; + interface->fTexParameteri = glTexParameteri; + #if GL_ARB_texture_storage || GL_VERSION_4_2 + interface->fTexStorage2D = glTexStorage2D + #elif GL_EXT_texture_storage + interface->fTexStorage2D = glTexStorage2DEXT; + #else + if (ver >= GR_GL_VER(4,2) || + GrGLHasExtensionFromString("GL_ARB_texture_storage", extStr)) { + GET_PROC(TexStorage2D); + } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", extStr)) { + GET_PROC_SUFFIX(TexStorage2D, EXT); + } + #endif + interface->fTexSubImage2D = glTexSubImage2D; + interface->fUniform1f = glUniform1f; + interface->fUniform1i = glUniform1i; + interface->fUniform1fv = glUniform1fv; + interface->fUniform1iv = glUniform1iv; + interface->fUniform2f = glUniform2f; + interface->fUniform2i = glUniform2i; + interface->fUniform2fv = glUniform2fv; + interface->fUniform2iv = glUniform2iv; + interface->fUniform3f = glUniform3f; + interface->fUniform3i = glUniform3i; + interface->fUniform3fv = glUniform3fv; + interface->fUniform3iv = glUniform3iv; + interface->fUniform4f = glUniform4f; + interface->fUniform4i = glUniform4i; + interface->fUniform4fv = glUniform4fv; + interface->fUniform4iv = glUniform4iv; + interface->fUniform4fv = glUniform4fv; + interface->fUniformMatrix2fv = glUniformMatrix2fv; + interface->fUniformMatrix3fv = glUniformMatrix3fv; + interface->fUniformMatrix4fv = glUniformMatrix4fv; + interface->fUnmapBuffer = glUnmapBuffer; + interface->fUseProgram = glUseProgram; + interface->fVertexAttrib4fv = glVertexAttrib4fv; + interface->fVertexAttribPointer = glVertexAttribPointer; + interface->fViewport = glViewport; + + if (ver >= GR_GL_VER(3,3) || GrGLHasExtensionFromString("GL_ARB_timer_query", extStr)) { + // ARB extension doesn't use the ARB suffix on the function name + #if GL_ARB_timer_query || GL_VERSION_3_3 + interface->fQueryCounter = glQueryCounter; + interface->fGetQueryObjecti64v = glGetQueryObjecti64v; + interface->fGetQueryObjectui64v = glGetQueryObjectui64v; + #else + interface->fQueryCounter = GET_PROC(QueryCounter); + interface->fGetQueryObjecti64v = GET_PROC(GetQueryObjecti64v); + interface->fGetQueryObjectui64v = GET_PROC(GetQueryObjectui64v); + #endif + } else if (GrGLHasExtensionFromString("GL_EXT_timer_query", extStr)) { + #if GL_EXT_timer_query + interface->fGetQueryObjecti64v = glGetQueryObjecti64vEXT; + interface->fGetQueryObjectui64v = glGetQueryObjectui64vEXT; + #else + interface->fGetQueryObjecti64v = GET_PROC_SUFFIX(GetQueryObjecti64v, EXT); + interface->fGetQueryObjectui64v = GET_PROC_SUFFIX(GetQueryObjectui64v, EXT); + #endif + } + + if (ver >= GR_GL_VER(3,0) || GrGLHasExtensionFromString("GL_ARB_framebuffer_object", extStr)) { + // ARB extension doesn't use the ARB suffix on the function names + #if GL_VERSION_3_0 || GL_ARB_framebuffer_object + interface->fGenFramebuffers = glGenFramebuffers; + interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv; + interface->fGetRenderbufferParameteriv = glGetRenderbufferParameteriv; + interface->fBindFramebuffer = glBindFramebuffer; + interface->fFramebufferTexture2D = glFramebufferTexture2D; + interface->fCheckFramebufferStatus = glCheckFramebufferStatus; + interface->fDeleteFramebuffers = glDeleteFramebuffers; + interface->fRenderbufferStorage = glRenderbufferStorage; + interface->fGenRenderbuffers = glGenRenderbuffers; + interface->fDeleteRenderbuffers = glDeleteRenderbuffers; + interface->fFramebufferRenderbuffer = glFramebufferRenderbuffer; + interface->fBindRenderbuffer = glBindRenderbuffer; + interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisample; + interface->fBlitFramebuffer = glBlitFramebuffer; + #else + interface->fGenFramebuffers = GET_PROC(GenFramebuffers); + interface->fGetFramebufferAttachmentParameteriv = GET_PROC(GetFramebufferAttachmentParameteriv); + interface->fGetRenderbufferParameteriv = GET_PROC(GetRenderbufferParameteriv); + interface->fBindFramebuffer = GET_PROC(BindFramebuffer); + interface->fFramebufferTexture2D = GET_PROC(FramebufferTexture2D); + interface->fCheckFramebufferStatus = GET_PROC(CheckFramebufferStatus); + interface->fDeleteFramebuffers = GET_PROC(DeleteFramebuffers); + interface->fRenderbufferStorage = GET_PROC(RenderbufferStorage); + interface->fGenRenderbuffers = GET_PROC(GenRenderbuffers); + interface->fDeleteRenderbuffers = GET_PROC(DeleteRenderbuffers); + interface->fFramebufferRenderbuffer = GET_PROC(FramebufferRenderbuffer); + interface->fBindRenderbuffer = GET_PROC(BindRenderbuffer); + interface->fRenderbufferStorageMultisample = GET_PROC(RenderbufferStorageMultisample); + interface->fBlitFramebuffer = GET_PROC(BlitFramebuffer); + #endif + } else { + if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object", extStr)) { + #if GL_EXT_framebuffer_object + interface->fGenFramebuffers = glGenFramebuffersEXT; + interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameterivEXT; + interface->fGetRenderbufferParameteriv = glGetRenderbufferParameterivEXT; + interface->fBindFramebuffer = glBindFramebufferEXT; + interface->fFramebufferTexture2D = glFramebufferTexture2DEXT; + interface->fCheckFramebufferStatus = glCheckFramebufferStatusEXT; + interface->fDeleteFramebuffers = glDeleteFramebuffersEXT; + interface->fRenderbufferStorage = glRenderbufferStorageEXT; + interface->fGenRenderbuffers = glGenRenderbuffersEXT; + interface->fDeleteRenderbuffers = glDeleteRenderbuffersEXT; + interface->fFramebufferRenderbuffer = glFramebufferRenderbufferEXT; + interface->fBindRenderbuffer = glBindRenderbufferEXT; + #else + interface->fGenFramebuffers = GET_PROC_SUFFIX(GenFramebuffers, EXT); + interface->fGetFramebufferAttachmentParameteriv = GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT); + interface->fGetRenderbufferParameteriv = GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT); + interface->fBindFramebuffer = GET_PROC_SUFFIX(BindFramebuffer, EXT); + interface->fFramebufferTexture2D = GET_PROC_SUFFIX(FramebufferTexture2D, EXT); + interface->fCheckFramebufferStatus = GET_PROC_SUFFIX(CheckFramebufferStatus, EXT); + interface->fDeleteFramebuffers = GET_PROC_SUFFIX(DeleteFramebuffers, EXT); + interface->fRenderbufferStorage = GET_PROC_SUFFIX(RenderbufferStorage, EXT); + interface->fGenRenderbuffers = GET_PROC_SUFFIX(GenRenderbuffers, EXT); + interface->fDeleteRenderbuffers = GET_PROC_SUFFIX(DeleteRenderbuffers, EXT); + interface->fFramebufferRenderbuffer = GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT); + interface->fBindRenderbuffer = GET_PROC_SUFFIX(BindRenderbuffer, EXT); + #endif + } + if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", extStr)) { + #if GL_EXT_framebuffer_multisample + interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisampleEXT; + #else + interface->fRenderbufferStorageMultisample = GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT); + #endif + } + if (GrGLHasExtensionFromString("", extStr)) { + #if GL_EXT_framebuffer_blit + interface->fBlitFramebuffer = glBlitFramebufferEXT; + #else + interface->fBlitFramebuffer = GET_PROC_SUFFIX(BlitFramebuffer, EXT); + #endif + } + } + if (ver >= GR_GL_VER(3,3) || GrGLHasExtensionFromString("GL_ARB_blend_func_extended", extStr)) { + // ARB extension doesn't use the ARB suffix on the function name + #if GL_VERSION_3_3 || GL_ARB_blend_func_extended + interface->fBindFragDataLocationIndexed = glBindFragDataLocationIndexed; + #else + interface->fBindFragDataLocationIndexed = GET_PROC(BindFragDataLocationIndexed); + #endif + } + + interface->fBindingsExported = kDesktop_GrGLBinding; + } + glInterface.get()->ref(); + return glInterface.get(); +} diff --git a/src/gpu/gl/mac/SkNativeGLContext_mac.cpp b/src/gpu/gl/mac/SkNativeGLContext_mac.cpp new file mode 100644 index 0000000000..18b36a5608 --- /dev/null +++ b/src/gpu/gl/mac/SkNativeGLContext_mac.cpp @@ -0,0 +1,74 @@ + +/* + * 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/SkNativeGLContext.h" + +SkNativeGLContext::AutoContextRestore::AutoContextRestore() { + fOldAGLContext = aglGetCurrentContext(); +} + +SkNativeGLContext::AutoContextRestore::~AutoContextRestore() { + aglSetCurrentContext(fOldAGLContext); +} + +/////////////////////////////////////////////////////////////////////////////// + +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/gl/mesa/GrGLCreateMesaInterface.cpp b/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp new file mode 100644 index 0000000000..4686438c62 --- /dev/null +++ b/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp @@ -0,0 +1,197 @@ + +/* + * 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/GrGLInterface.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); + +// We use OSMesaGetProcAddress for every gl function to avoid accidentally using +// non-Mesa gl functions. + +const GrGLInterface* GrGLCreateMesaInterface() { + if (NULL != OSMesaGetCurrentContext()) { + 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)) { + // We must have array and element_array buffer objects. + return NULL; + } + GrGLInterface* interface = new GrGLInterface(); + + 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); + 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); + GR_GL_GET_PROC(Clear); + GR_GL_GET_PROC(ClearColor); + GR_GL_GET_PROC(ClearStencil); + GR_GL_GET_PROC(ColorMask); + GR_GL_GET_PROC(CompileShader); + GR_GL_GET_PROC(CompressedTexImage2D); + GR_GL_GET_PROC(CreateProgram); + GR_GL_GET_PROC(CreateShader); + 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); + GR_GL_GET_PROC(DeleteTextures); + GR_GL_GET_PROC(DepthMask); + GR_GL_GET_PROC(Disable); + GR_GL_GET_PROC(DisableVertexAttribArray); + GR_GL_GET_PROC(DrawArrays); + GR_GL_GET_PROC(DrawBuffer); + GR_GL_GET_PROC(DrawBuffers); + GR_GL_GET_PROC(DrawElements); + GR_GL_GET_PROC(Enable); + GR_GL_GET_PROC(EnableVertexAttribArray); + 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); + 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); + GR_GL_GET_PROC(GetString); + GR_GL_GET_PROC(GetTexLevelParameteriv); + GR_GL_GET_PROC(GenTextures); + GR_GL_GET_PROC(GetUniformLocation); + GR_GL_GET_PROC(LineWidth); + GR_GL_GET_PROC(LinkProgram); + GR_GL_GET_PROC(MapBuffer); + GR_GL_GET_PROC(PixelStorei); + GR_GL_GET_PROC(ReadBuffer); + GR_GL_GET_PROC(ReadPixels); + GR_GL_GET_PROC(Scissor); + GR_GL_GET_PROC(ShaderSource); + GR_GL_GET_PROC(StencilFunc); + GR_GL_GET_PROC(StencilFuncSeparate); + GR_GL_GET_PROC(StencilMask); + GR_GL_GET_PROC(StencilMaskSeparate); + GR_GL_GET_PROC(StencilOp); + GR_GL_GET_PROC(StencilOpSeparate); + GR_GL_GET_PROC(TexImage2D) + GR_GL_GET_PROC(TexParameteri); + GR_GL_GET_PROC(TexStorage2D); + if (NULL == interface->fTexStorage2D) { + GR_GL_GET_PROC_SUFFIX(TexStorage2D, EXT); + } + GR_GL_GET_PROC(TexSubImage2D); + GR_GL_GET_PROC(Uniform1f); + GR_GL_GET_PROC(Uniform1i); + GR_GL_GET_PROC(Uniform1fv); + GR_GL_GET_PROC(Uniform1iv); + GR_GL_GET_PROC(Uniform2f); + GR_GL_GET_PROC(Uniform2i); + GR_GL_GET_PROC(Uniform2fv); + GR_GL_GET_PROC(Uniform2iv); + GR_GL_GET_PROC(Uniform3f); + GR_GL_GET_PROC(Uniform3i); + GR_GL_GET_PROC(Uniform3fv); + GR_GL_GET_PROC(Uniform3iv); + GR_GL_GET_PROC(Uniform4f); + GR_GL_GET_PROC(Uniform4i); + GR_GL_GET_PROC(Uniform4fv); + GR_GL_GET_PROC(Uniform4iv); + GR_GL_GET_PROC(UniformMatrix2fv); + GR_GL_GET_PROC(UniformMatrix3fv); + GR_GL_GET_PROC(UniformMatrix4fv); + GR_GL_GET_PROC(UnmapBuffer); + GR_GL_GET_PROC(UseProgram); + GR_GL_GET_PROC(VertexAttrib4fv); + GR_GL_GET_PROC(VertexAttribPointer); + 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.) + if (glVer >= GR_GL_VER(3,0) || + GrGLHasExtensionFromString("GL_ARB_framebuffer_object", + extString)) { + GR_GL_GET_PROC(GenFramebuffers); + GR_GL_GET_PROC(GetFramebufferAttachmentParameteriv); + GR_GL_GET_PROC(GetRenderbufferParameteriv); + GR_GL_GET_PROC(BindFramebuffer); + GR_GL_GET_PROC(FramebufferTexture2D); + GR_GL_GET_PROC(CheckFramebufferStatus); + GR_GL_GET_PROC(DeleteFramebuffers); + GR_GL_GET_PROC(RenderbufferStorage); + GR_GL_GET_PROC(GenRenderbuffers); + GR_GL_GET_PROC(DeleteRenderbuffers); + GR_GL_GET_PROC(FramebufferRenderbuffer); + GR_GL_GET_PROC(BindRenderbuffer); + GR_GL_GET_PROC(RenderbufferStorageMultisample); + GR_GL_GET_PROC(BlitFramebuffer); + } else if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object", + extString)) { + GR_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT); + GR_GL_GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT); + GR_GL_GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT); + GR_GL_GET_PROC_SUFFIX(BindFramebuffer, EXT); + GR_GL_GET_PROC_SUFFIX(FramebufferTexture2D, EXT); + GR_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT); + GR_GL_GET_PROC_SUFFIX(DeleteFramebuffers, EXT); + GR_GL_GET_PROC_SUFFIX(RenderbufferStorage, EXT); + GR_GL_GET_PROC_SUFFIX(GenRenderbuffers, EXT); + GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, EXT); + GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT); + GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT); + if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", + extString)) { + GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT); + } + if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", + extString)) { + GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT); + } + } else { + // we must have FBOs + delete interface; + return NULL; + } + GR_GL_GET_PROC(BindFragDataLocationIndexed); + interface->fBindingsExported = kDesktop_GrGLBinding; + return interface; + } else { + return NULL; + } +} diff --git a/src/gpu/gl/mesa/SkMesaGLContext.cpp b/src/gpu/gl/mesa/SkMesaGLContext.cpp new file mode 100644 index 0000000000..c4f84cf8d2 --- /dev/null +++ b/src/gpu/gl/mesa/SkMesaGLContext.cpp @@ -0,0 +1,103 @@ + +/* + * 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 "gl/SkMesaGLContext.h" + +SkMesaGLContext::AutoContextRestore::AutoContextRestore() { + fOldContext = (Context)OSMesaGetCurrentContext(); + if (NULL != (OSMesaContext)fOldContext) { + OSMesaGetColorBuffer((OSMesaContext)fOldContext, + &fOldWidth, &fOldHeight, + &fOldFormat, &fOldImage); + } +} + +SkMesaGLContext::AutoContextRestore::~AutoContextRestore() { + if (NULL != (OSMesaContext)fOldContext) { + OSMesaMakeCurrent((OSMesaContext)fOldContext, fOldImage, + fOldFormat, fOldWidth, fOldHeight); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +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/gl/unix/GrGLCreateNativeInterface_unix.cpp b/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp new file mode 100644 index 0000000000..1e9f2e04ad --- /dev/null +++ b/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp @@ -0,0 +1,200 @@ + +/* + * 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/GrGLInterface.h" + +#include <GL/glx.h> +#include <GL/gl.h> +#include <GL/glext.h> +#include <GL/glu.h> + +#define GR_GL_GET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) \ + glXGetProcAddress(reinterpret_cast<const GLubyte*>("gl" #F)); +#define GR_GL_GET_PROC_SUFFIX(F, S) interface->f ## F = (GrGL ## F ## Proc) \ + glXGetProcAddress(reinterpret_cast<const GLubyte*>("gl" #F #S)); + +const GrGLInterface* GrGLCreateNativeInterface() { + if (NULL != glXGetCurrentContext()) { + const char* versionString = (const char*) glGetString(GL_VERSION); + const char* extString = (const char*) glGetString(GL_EXTENSIONS); + GrGLVersion glVer = GrGLGetVersionFromString(versionString); + + if (glVer < GR_GL_VER(1,5)) { + // We must have array and element_array buffer objects. + return NULL; + } + + GrGLInterface* interface = new GrGLInterface(); + + interface->fActiveTexture = glActiveTexture; + GR_GL_GET_PROC(AttachShader); + 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; + GR_GL_GET_PROC(BufferData); + GR_GL_GET_PROC(BufferSubData); + interface->fClear = glClear; + interface->fClearColor = glClearColor; + interface->fClearStencil = glClearStencil; + interface->fColorMask = glColorMask; + interface->fColorPointer = glColorPointer; + GR_GL_GET_PROC(CompileShader); + interface->fCompressedTexImage2D = glCompressedTexImage2D; + GR_GL_GET_PROC(CreateProgram); + GR_GL_GET_PROC(CreateShader); + 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; + interface->fDisable = glDisable; + GR_GL_GET_PROC(DisableVertexAttribArray); + interface->fDrawArrays = glDrawArrays; + interface->fDrawBuffer = glDrawBuffer; + GR_GL_GET_PROC(DrawBuffers); + interface->fDrawElements = glDrawElements; + interface->fEnable = glEnable; + 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; + GR_GL_GET_PROC(LinkProgram); + GR_GL_GET_PROC(MapBuffer); + interface->fPixelStorei = glPixelStorei; + interface->fReadBuffer = glReadBuffer; + interface->fReadPixels = glReadPixels; + interface->fScissor = glScissor; + GR_GL_GET_PROC(ShaderSource); + interface->fStencilFunc = glStencilFunc; + GR_GL_GET_PROC(StencilFuncSeparate); + interface->fStencilMask = glStencilMask; + GR_GL_GET_PROC(StencilMaskSeparate); + interface->fStencilOp = glStencilOp; + GR_GL_GET_PROC(StencilOpSeparate); + interface->fTexImage2D = glTexImage2D; + interface->fTexParameteri = glTexParameteri; + if (glVer >= GR_GL_VER(4,2) || + GrGLHasExtensionFromString("GL_ARB_texture_storage", extString)) { + GR_GL_GET_PROC(TexStorage2D); + } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", extString)) { + GR_GL_GET_PROC_SUFFIX(TexStorage2D, EXT); + } + interface->fTexSubImage2D = glTexSubImage2D; + GR_GL_GET_PROC(Uniform1f); + GR_GL_GET_PROC(Uniform1i); + GR_GL_GET_PROC(Uniform1fv); + GR_GL_GET_PROC(Uniform1iv); + GR_GL_GET_PROC(Uniform2f); + GR_GL_GET_PROC(Uniform2i); + GR_GL_GET_PROC(Uniform2fv); + GR_GL_GET_PROC(Uniform2iv); + GR_GL_GET_PROC(Uniform3f); + GR_GL_GET_PROC(Uniform3i); + GR_GL_GET_PROC(Uniform3fv); + GR_GL_GET_PROC(Uniform3iv); + GR_GL_GET_PROC(Uniform4f); + GR_GL_GET_PROC(Uniform4i); + GR_GL_GET_PROC(Uniform4fv); + GR_GL_GET_PROC(Uniform4iv); + GR_GL_GET_PROC(UniformMatrix2fv); + GR_GL_GET_PROC(UniformMatrix3fv); + GR_GL_GET_PROC(UniformMatrix4fv); + GR_GL_GET_PROC(UnmapBuffer); + GR_GL_GET_PROC(UseProgram); + GR_GL_GET_PROC(VertexAttrib4fv); + GR_GL_GET_PROC(VertexAttribPointer); + interface->fViewport = glViewport; + GR_GL_GET_PROC(BindFragDataLocationIndexed); + + // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since + // GL_ARB_framebuffer_object doesn't use ARB suffix.) + if (glVer >= GR_GL_VER(3,0) || + GrGLHasExtensionFromString("GL_ARB_framebuffer_object", + extString)) { + GR_GL_GET_PROC(GenFramebuffers); + GR_GL_GET_PROC(GetFramebufferAttachmentParameteriv); + GR_GL_GET_PROC(GetRenderbufferParameteriv); + GR_GL_GET_PROC(BindFramebuffer); + GR_GL_GET_PROC(FramebufferTexture2D); + GR_GL_GET_PROC(CheckFramebufferStatus); + GR_GL_GET_PROC(DeleteFramebuffers); + GR_GL_GET_PROC(RenderbufferStorage); + GR_GL_GET_PROC(GenRenderbuffers); + GR_GL_GET_PROC(DeleteRenderbuffers); + GR_GL_GET_PROC(FramebufferRenderbuffer); + GR_GL_GET_PROC(BindRenderbuffer); + GR_GL_GET_PROC(RenderbufferStorageMultisample); + GR_GL_GET_PROC(BlitFramebuffer); + } else if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object", + extString)) { + GR_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT); + GR_GL_GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT); + GR_GL_GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT); + GR_GL_GET_PROC_SUFFIX(BindFramebuffer, EXT); + GR_GL_GET_PROC_SUFFIX(FramebufferTexture2D, EXT); + GR_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT); + GR_GL_GET_PROC_SUFFIX(DeleteFramebuffers, EXT); + GR_GL_GET_PROC_SUFFIX(RenderbufferStorage, EXT); + GR_GL_GET_PROC_SUFFIX(GenRenderbuffers, EXT); + GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, EXT); + GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT); + GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT); + if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", + extString)) { + GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT); + } + if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", + extString)) { + GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT); + } + } else { + // we must have FBOs + delete interface; + return NULL; + } + interface->fBindingsExported = kDesktop_GrGLBinding; + + return interface; + } else { + return NULL; + } +} diff --git a/src/gpu/gl/unix/SkNativeGLContext_unix.cpp b/src/gpu/gl/unix/SkNativeGLContext_unix.cpp new file mode 100644 index 0000000000..f9c582cd09 --- /dev/null +++ b/src/gpu/gl/unix/SkNativeGLContext_unix.cpp @@ -0,0 +1,287 @@ + +/* + * 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/SkNativeGLContext.h" + +#include <GL/glu.h> + +#define GLX_1_3 1 + +SkNativeGLContext::AutoContextRestore::AutoContextRestore() { + fOldGLXContext = glXGetCurrentContext(); + fOldDisplay = glXGetCurrentDisplay(); + fOldDrawable = glXGetCurrentDrawable(); +} + +SkNativeGLContext::AutoContextRestore::~AutoContextRestore() { + if (NULL != fOldDisplay) { + glXMakeCurrent(fOldDisplay, fOldDrawable, fOldGLXContext); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +static bool ctxErrorOccurred = false; +static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) { + ctxErrorOccurred = true; + return 0; +} + +SkNativeGLContext::SkNativeGLContext() + : fContext(NULL) + , fDisplay(NULL) + , fPixmap(0) + , fGlxPixmap(0) { +} + +SkNativeGLContext::~SkNativeGLContext() { + this->destroyGLContext(); +} + +void SkNativeGLContext::destroyGLContext() { + if (fDisplay) { + glXMakeCurrent(fDisplay, 0, 0); + + if (fContext) { + glXDestroyContext(fDisplay, fContext); + fContext = NULL; + } + + if (fGlxPixmap) { + glXDestroyGLXPixmap(fDisplay, fGlxPixmap); + fGlxPixmap = 0; + } + + if (fPixmap) { + XFreePixmap(fDisplay, fPixmap); + fPixmap = 0; + } + + XCloseDisplay(fDisplay); + fDisplay = NULL; + } +} + +const GrGLInterface* SkNativeGLContext::createGLContext() { + fDisplay = XOpenDisplay(0); + + if (!fDisplay) { + SkDebugf("Failed to open X display.\n"); + this->destroyGLContext(); + return NULL; + } + + // Get a matching FB config + static int visual_attribs[] = { + GLX_X_RENDERABLE , True, + GLX_DRAWABLE_TYPE , GLX_PIXMAP_BIT, + None + }; + +#ifdef GLX_1_3 + //SkDebugf("Getting matching framebuffer configs.\n"); + int fbcount; + GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), + visual_attribs, &fbcount); + if (!fbc) { + SkDebugf("Failed to retrieve a framebuffer config.\n"); + this->destroyGLContext(); + return NULL; + } + //SkDebugf("Found %d matching FB configs.\n", fbcount); + + // Pick the FB config/visual with the most samples per pixel + //SkDebugf("Getting XVisualInfos.\n"); + int best_fbc = -1, best_num_samp = -1; + + int i; + for (i = 0; i < fbcount; ++i) { + XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, fbc[i]); + if (vi) { + int samp_buf, samples; + glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf); + glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLES, &samples); + + //SkDebugf(" Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d," + // " SAMPLES = %d\n", + // i, (unsigned int)vi->visualid, samp_buf, samples); + + if (best_fbc < 0 || (samp_buf && samples > best_num_samp)) + best_fbc = i, best_num_samp = samples; + } + XFree(vi); + } + + GLXFBConfig bestFbc = fbc[best_fbc]; + + // Be sure to free the FBConfig list allocated by glXChooseFBConfig() + XFree(fbc); + + // Get a visual + XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc); + //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid); +#else + int numVisuals; + XVisualInfo visTemplate, *visReturn; + + visReturn = XGetVisualInfo(fDisplay, VisualNoMask, &visTemplate, &numVisuals); + if (NULL == visReturn) + { + SkDebugf("Failed to get visual information.\n"); + this->destroyGLContext(); + return NULL; + } + + int best = -1, best_num_samp = -1; + + for (int i = 0; i < numVisuals; ++i) + { + int samp_buf, samples; + + glXGetConfig(fDisplay, &visReturn[i], GLX_SAMPLE_BUFFERS, &samp_buf); + glXGetConfig(fDisplay, &visReturn[i], GLX_SAMPLES, &samples); + + if (best < 0 || (samp_buf && samples > best_num_samp)) + best = i, best_num_samp = samples; + } + + XVisualInfo temp = visReturn[best]; + XVisualInfo *vi = &temp; + + XFree(visReturn); +#endif + + fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10, vi->depth); + + if (!fPixmap) { + SkDebugf("Failed to create pixmap.\n"); + this->destroyGLContext(); + return NULL; + } + + fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap); + +#ifdef GLX_1_3 + // Done with the visual info data + XFree(vi); +#endif + + // Create the context + + // Install an X error handler so the application won't exit if GL 3.0 + // context allocation fails. + // + // Note this error handler is global. + // All display connections in all threads of a process use the same + // error handler, so be sure to guard against other threads issuing + // X commands while this code is running. + ctxErrorOccurred = false; + int (*oldHandler)(Display*, XErrorEvent*) = + XSetErrorHandler(&ctxErrorHandler); + + // Get the default screen's GLX extension list + const char *glxExts = glXQueryExtensionsString( + fDisplay, DefaultScreen(fDisplay) + ); + // Check for the GLX_ARB_create_context extension string and the function. + // If either is not present, use GLX 1.3 context creation method. + if (!gluCheckExtension( + reinterpret_cast<const GLubyte*>("GLX_ARB_create_context") + , reinterpret_cast<const GLubyte*>(glxExts))) + { + //SkDebugf("GLX_ARB_create_context not found." + // " Using old-style GLX context.\n"); +#ifdef GLX_1_3 + fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True); +#else + fContext = glXCreateContext(fDisplay, vi, 0, True); +#endif + + } +#ifdef GLX_1_3 + else { + //SkDebugf("Creating context.\n"); + + PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = + (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddressARB((GrGLubyte*)"glXCreateContextAttribsARB"); + int context_attribs[] = { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 0, + //GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + None + }; + fContext = glXCreateContextAttribsARB( + fDisplay, bestFbc, 0, True, context_attribs + ); + + // Sync to ensure any errors generated are processed. + XSync(fDisplay, False); + if (!ctxErrorOccurred && fContext) { + //SkDebugf( "Created GL 3.0 context.\n" ); + } else { + // Couldn't create GL 3.0 context. + // Fall back to old-style 2.x context. + // When a context version below 3.0 is requested, + // implementations will return the newest context version compatible + // with OpenGL versions less than version 3.0. + + // GLX_CONTEXT_MAJOR_VERSION_ARB = 1 + context_attribs[1] = 1; + // GLX_CONTEXT_MINOR_VERSION_ARB = 0 + context_attribs[3] = 0; + + ctxErrorOccurred = false; + + //SkDebugf("Failed to create GL 3.0 context." + // " Using old-style GLX context.\n"); + fContext = glXCreateContextAttribsARB( + fDisplay, bestFbc, 0, True, context_attribs + ); + } + } +#endif + + // Sync to ensure any errors generated are processed. + XSync(fDisplay, False); + + // Restore the original error handler + XSetErrorHandler(oldHandler); + + if (ctxErrorOccurred || !fContext) { + SkDebugf("Failed to create an OpenGL context.\n"); + this->destroyGLContext(); + return NULL; + } + + // Verify that context is a direct context + if (!glXIsDirect(fDisplay, fContext)) { + //SkDebugf("Indirect GLX rendering context obtained.\n"); + } else { + //SkDebugf("Direct GLX rendering context obtained.\n"); + } + + //SkDebugf("Making context current.\n"); + if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { + SkDebugf("Could not set the context.\n"); + this->destroyGLContext(); + return NULL; + } + + const GrGLInterface* interface = GrGLCreateNativeInterface(); + if (!interface) { + SkDebugf("Failed to create gl interface"); + this->destroyGLContext(); + return NULL; + } + return interface; +} + +void SkNativeGLContext::makeCurrent() const { + if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { + SkDebugf("Could not set the context.\n"); + } +} diff --git a/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp b/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp new file mode 100644 index 0000000000..f050a6f038 --- /dev/null +++ b/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp @@ -0,0 +1,206 @@ + +/* + * 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/GrGLInterface.h" +#define WIN32_LEAN_AND_MEAN +#include <Windows.h> +#include <GL/GL.h> + +/* + * Windows makes the GL funcs all be __stdcall instead of __cdecl :( + * This implementation will only work if GR_GL_FUNCTION_TYPE is __stdcall. + * Otherwise, a springboard would be needed that hides the calling convention. + */ + +#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* 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 + // called. + if (NULL != wglGetCurrentContext()) { + const char* versionString = (const char*) glGetString(GL_VERSION); + const char* extString = (const char*) glGetString(GL_EXTENSIONS); + GrGLVersion glVer = GrGLGetVersionFromString(versionString); + + if (glVer < GR_GL_VER(1,5)) { + // We must have array and element_array buffer objects. + return NULL; + } + GrGLInterface* interface = new GrGLInterface(); + + // Functions that are part of GL 1.1 will return NULL in + // wglGetProcAddress + interface->fBindTexture = glBindTexture; + interface->fBlendFunc = glBlendFunc; + interface->fClear = glClear; + interface->fClearColor = glClearColor; + interface->fClearStencil = glClearStencil; + interface->fColorMask = glColorMask; + interface->fColorPointer = glColorPointer; + interface->fCullFace = glCullFace; + interface->fDeleteTextures = glDeleteTextures; + interface->fDepthMask = glDepthMask; + interface->fDisable = glDisable; + interface->fDrawArrays = glDrawArrays; + interface->fDrawElements = glDrawElements; + interface->fDrawBuffer = glDrawBuffer; + interface->fEnable = glEnable; + interface->fFrontFace = glFrontFace; + interface->fFinish = glFinish; + interface->fFlush = glFlush; + interface->fGenTextures = glGenTextures; + interface->fGetError = glGetError; + interface->fGetIntegerv = glGetIntegerv; + interface->fGetString = glGetString; + interface->fGetTexLevelParameteriv = glGetTexLevelParameteriv; + interface->fLineWidth = glLineWidth; + interface->fPixelStorei = glPixelStorei; + interface->fReadBuffer = glReadBuffer; + interface->fReadPixels = glReadPixels; + interface->fScissor = glScissor; + interface->fStencilFunc = glStencilFunc; + interface->fStencilMask = glStencilMask; + interface->fStencilOp = glStencilOp; + interface->fTexImage2D = glTexImage2D; + interface->fTexParameteri = glTexParameteri; + if (glVer >= GR_GL_VER(4,2) || + GrGLHasExtensionFromString("GL_ARB_texture_storage", extString)) { + GR_GL_GET_PROC(TexStorage2D); + } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", extString)) { + GR_GL_GET_PROC_SUFFIX(TexStorage2D, EXT); + } + interface->fTexSubImage2D = glTexSubImage2D; + interface->fViewport = glViewport; + + GR_GL_GET_PROC(ActiveTexture); + GR_GL_GET_PROC(AttachShader); + GR_GL_GET_PROC(BeginQuery); + GR_GL_GET_PROC(BindAttribLocation); + GR_GL_GET_PROC(BindBuffer); + GR_GL_GET_PROC(BindFragDataLocation); + GR_GL_GET_PROC(BlendColor); + GR_GL_GET_PROC(BufferData); + GR_GL_GET_PROC(BufferSubData); + GR_GL_GET_PROC(CompileShader); + GR_GL_GET_PROC(CompressedTexImage2D); + GR_GL_GET_PROC(CreateProgram); + GR_GL_GET_PROC(CreateShader); + GR_GL_GET_PROC(DeleteBuffers); + GR_GL_GET_PROC(DeleteQueries); + GR_GL_GET_PROC(DeleteProgram); + GR_GL_GET_PROC(DeleteShader); + GR_GL_GET_PROC(DisableVertexAttribArray); + GR_GL_GET_PROC(DrawBuffers); + GR_GL_GET_PROC(EnableVertexAttribArray); + GR_GL_GET_PROC(EndQuery); + GR_GL_GET_PROC(GenBuffers); + GR_GL_GET_PROC(GenQueries); + GR_GL_GET_PROC(GetBufferParameteriv); + GR_GL_GET_PROC(GetQueryiv); + 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(GetProgramInfoLog); + GR_GL_GET_PROC(GetProgramiv); + GR_GL_GET_PROC(GetShaderInfoLog); + GR_GL_GET_PROC(GetShaderiv); + GR_GL_GET_PROC(GetUniformLocation); + GR_GL_GET_PROC(LinkProgram); + GR_GL_GET_PROC(ShaderSource); + GR_GL_GET_PROC(StencilFuncSeparate); + GR_GL_GET_PROC(StencilMaskSeparate); + GR_GL_GET_PROC(StencilOpSeparate); + GR_GL_GET_PROC(Uniform1f); + GR_GL_GET_PROC(Uniform1i); + GR_GL_GET_PROC(Uniform1fv); + GR_GL_GET_PROC(Uniform1iv); + GR_GL_GET_PROC(Uniform2f); + GR_GL_GET_PROC(Uniform2i); + GR_GL_GET_PROC(Uniform2fv); + GR_GL_GET_PROC(Uniform2iv); + GR_GL_GET_PROC(Uniform3f); + GR_GL_GET_PROC(Uniform3i); + GR_GL_GET_PROC(Uniform3fv); + GR_GL_GET_PROC(Uniform3iv); + GR_GL_GET_PROC(Uniform4f); + GR_GL_GET_PROC(Uniform4i); + GR_GL_GET_PROC(Uniform4fv); + GR_GL_GET_PROC(Uniform4iv); + GR_GL_GET_PROC(UniformMatrix2fv); + GR_GL_GET_PROC(UniformMatrix3fv); + GR_GL_GET_PROC(UniformMatrix4fv); + GR_GL_GET_PROC(UseProgram); + GR_GL_GET_PROC(VertexAttrib4fv); + GR_GL_GET_PROC(VertexAttribPointer); + GR_GL_GET_PROC(BindFragDataLocationIndexed); + + // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since + // GL_ARB_framebuffer_object doesn't use ARB suffix.) + if (glVer > GR_GL_VER(3,0) || + GrGLHasExtensionFromString("GL_ARB_framebuffer_object", extString)) { + GR_GL_GET_PROC(GenFramebuffers); + GR_GL_GET_PROC(GetFramebufferAttachmentParameteriv); + GR_GL_GET_PROC(GetRenderbufferParameteriv); + GR_GL_GET_PROC(BindFramebuffer); + GR_GL_GET_PROC(FramebufferTexture2D); + GR_GL_GET_PROC(CheckFramebufferStatus); + GR_GL_GET_PROC(DeleteFramebuffers); + GR_GL_GET_PROC(RenderbufferStorage); + GR_GL_GET_PROC(GenRenderbuffers); + GR_GL_GET_PROC(DeleteRenderbuffers); + GR_GL_GET_PROC(FramebufferRenderbuffer); + GR_GL_GET_PROC(BindRenderbuffer); + GR_GL_GET_PROC(RenderbufferStorageMultisample); + GR_GL_GET_PROC(BlitFramebuffer); + } else if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object", + extString)) { + GR_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT); + GR_GL_GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT); + GR_GL_GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT); + GR_GL_GET_PROC_SUFFIX(BindFramebuffer, EXT); + GR_GL_GET_PROC_SUFFIX(FramebufferTexture2D, EXT); + GR_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT); + GR_GL_GET_PROC_SUFFIX(DeleteFramebuffers, EXT); + GR_GL_GET_PROC_SUFFIX(RenderbufferStorage, EXT); + GR_GL_GET_PROC_SUFFIX(GenRenderbuffers, EXT); + GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, EXT); + GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT); + GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT); + if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", extString)) { + GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT); + } + if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", extString)) { + GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT); + } + } else { + // we must have FBOs + delete interface; + return NULL; + } + GR_GL_GET_PROC(MapBuffer); + GR_GL_GET_PROC(UnmapBuffer); + + interface->fBindingsExported = kDesktop_GrGLBinding; + + return interface; + } else { + return NULL; + } +} diff --git a/src/gpu/gl/win/SkNativeGLContext_win.cpp b/src/gpu/gl/win/SkNativeGLContext_win.cpp new file mode 100644 index 0000000000..9650bc1199 --- /dev/null +++ b/src/gpu/gl/win/SkNativeGLContext_win.cpp @@ -0,0 +1,137 @@ + +/* + * 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/SkNativeGLContext.h" + +#define WIN32_LEAN_AND_MEAN +#include <Windows.h> + +SkNativeGLContext::AutoContextRestore::AutoContextRestore() { + fOldHGLRC = wglGetCurrentContext(); + fOldHDC = wglGetCurrentDC(); +} + +SkNativeGLContext::AutoContextRestore::~AutoContextRestore() { + wglMakeCurrent(fOldHDC, fOldHGLRC); +} + +/////////////////////////////////////////////////////////////////////////////// + +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"); + } +} |