diff options
Diffstat (limited to 'gpu/gl/win')
-rw-r--r-- | gpu/gl/win/GrGLCreateNativeInterface_win.cpp | 316 | ||||
-rw-r--r-- | gpu/gl/win/SkNativeGLContext_win.cpp | 114 |
2 files changed, 430 insertions, 0 deletions
diff --git a/gpu/gl/win/GrGLCreateNativeInterface_win.cpp b/gpu/gl/win/GrGLCreateNativeInterface_win.cpp new file mode 100644 index 00000000..53b1eddd --- /dev/null +++ b/gpu/gl/win/GrGLCreateNativeInterface_win.cpp @@ -0,0 +1,316 @@ + +/* + * 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/GrGLExtensions.h" +#include "gl/GrGLInterface.h" +#include "gl/GrGLUtil.h" +#define WIN32_LEAN_AND_MEAN +#include <Windows.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 SET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) GetProcAddress(alu.get(), "gl" #F); +#define WGL_SET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F); +#define WGL_SET_PROC_SUFFIX(F, S) interface->f ## F = \ + (GrGL ## F ## Proc) wglGetProcAddress("gl" #F #S); + +class AutoLibraryUnload { +public: + AutoLibraryUnload(const char* moduleName) { + fModule = LoadLibrary(moduleName); + } + ~AutoLibraryUnload() { + if (NULL != fModule) { + FreeLibrary(fModule); + } + } + HMODULE get() const { return fModule; } + +private: + HMODULE fModule; +}; + +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. + AutoLibraryUnload alu("opengl32.dll"); + if (NULL == alu.get()) { + return NULL; + } + + if (NULL != wglGetCurrentContext()) { + + // These should always be present and don't require wglGetProcAddress + GrGLGetStringProc glGetString = + (GrGLGetStringProc) GetProcAddress(alu.get(), "glGetString"); + GrGLGetIntegervProc glGetIntegerv = + (GrGLGetIntegervProc) GetProcAddress(alu.get(), "glGetIntegerv"); + if (NULL == glGetString || NULL == glGetIntegerv) { + return NULL; + } + + // This may or may not succeed depending on the gl version. + GrGLGetStringiProc glGetStringi = (GrGLGetStringiProc) wglGetProcAddress("glGetStringi"); + + GrGLExtensions extensions; + if (!extensions.init(kDesktop_GrGLBinding, glGetString, glGetStringi, glGetIntegerv)) { + return NULL; + } + const char* versionString = (const char*) glGetString(GR_GL_VERSION); + 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 + SET_PROC(BindTexture) + SET_PROC(BlendFunc) + + if (glVer >= GR_GL_VER(1,4) || + extensions.has("GL_ARB_imaging") || + extensions.has("GL_EXT_blend_color")) { + WGL_SET_PROC(BlendColor); + } + + SET_PROC(Clear) + SET_PROC(ClearColor) + SET_PROC(ClearStencil) + SET_PROC(ColorMask) + SET_PROC(CopyTexSubImage2D) + SET_PROC(CullFace) + SET_PROC(DeleteTextures) + SET_PROC(DepthMask) + SET_PROC(Disable) + SET_PROC(DrawArrays) + SET_PROC(DrawElements) + SET_PROC(DrawBuffer) + SET_PROC(Enable) + SET_PROC(FrontFace) + SET_PROC(Finish) + SET_PROC(Flush) + SET_PROC(GenTextures) + SET_PROC(GetError) + SET_PROC(GetIntegerv) + SET_PROC(GetString) + SET_PROC(GetTexLevelParameteriv) + SET_PROC(LineWidth) + SET_PROC(LoadIdentity) + SET_PROC(LoadMatrixf) + SET_PROC(MatrixMode) + SET_PROC(PixelStorei) + SET_PROC(ReadBuffer) + SET_PROC(ReadPixels) + SET_PROC(Scissor) + SET_PROC(StencilFunc) + SET_PROC(StencilMask) + SET_PROC(StencilOp) + SET_PROC(TexImage2D) + SET_PROC(TexParameteri) + SET_PROC(TexParameteriv) + if (glVer >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage")) { + WGL_SET_PROC(TexStorage2D); + } else if (extensions.has("GL_EXT_texture_storage")) { + WGL_SET_PROC_SUFFIX(TexStorage2D, EXT); + } + SET_PROC(TexSubImage2D) + SET_PROC(Viewport) + + WGL_SET_PROC(ActiveTexture); + WGL_SET_PROC(AttachShader); + WGL_SET_PROC(BeginQuery); + WGL_SET_PROC(BindAttribLocation); + WGL_SET_PROC(BindBuffer); + WGL_SET_PROC(BindFragDataLocation); + WGL_SET_PROC(BufferData); + WGL_SET_PROC(BufferSubData); + WGL_SET_PROC(CompileShader); + WGL_SET_PROC(CompressedTexImage2D); + WGL_SET_PROC(CreateProgram); + WGL_SET_PROC(CreateShader); + WGL_SET_PROC(DeleteBuffers); + WGL_SET_PROC(DeleteQueries); + WGL_SET_PROC(DeleteProgram); + WGL_SET_PROC(DeleteShader); + WGL_SET_PROC(DisableVertexAttribArray); + WGL_SET_PROC(DrawBuffers); + WGL_SET_PROC(EnableVertexAttribArray); + WGL_SET_PROC(EndQuery); + WGL_SET_PROC(GenBuffers); + WGL_SET_PROC(GenerateMipmap); + WGL_SET_PROC(GenQueries); + WGL_SET_PROC(GetBufferParameteriv); + WGL_SET_PROC(GetQueryiv); + WGL_SET_PROC(GetQueryObjectiv); + WGL_SET_PROC(GetQueryObjectuiv); + if (glVer > GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) { + WGL_SET_PROC(GetQueryObjecti64v); + WGL_SET_PROC(GetQueryObjectui64v); + WGL_SET_PROC(QueryCounter); + } else if (extensions.has("GL_EXT_timer_query")) { + WGL_SET_PROC_SUFFIX(GetQueryObjecti64v, EXT); + WGL_SET_PROC_SUFFIX(GetQueryObjectui64v, EXT); + } + WGL_SET_PROC(GetProgramInfoLog); + WGL_SET_PROC(GetProgramiv); + WGL_SET_PROC(GetShaderInfoLog); + WGL_SET_PROC(GetShaderiv); + WGL_SET_PROC(GetStringi) + WGL_SET_PROC(GetUniformLocation); + WGL_SET_PROC(LinkProgram); + if (extensions.has("GL_NV_framebuffer_multisample_coverage")) { + WGL_SET_PROC_SUFFIX(RenderbufferStorageMultisampleCoverage, NV); + } + WGL_SET_PROC(ShaderSource); + WGL_SET_PROC(StencilFuncSeparate); + WGL_SET_PROC(StencilMaskSeparate); + WGL_SET_PROC(StencilOpSeparate); + WGL_SET_PROC(Uniform1f); + WGL_SET_PROC(Uniform1i); + WGL_SET_PROC(Uniform1fv); + WGL_SET_PROC(Uniform1iv); + WGL_SET_PROC(Uniform2f); + WGL_SET_PROC(Uniform2i); + WGL_SET_PROC(Uniform2fv); + WGL_SET_PROC(Uniform2iv); + WGL_SET_PROC(Uniform3f); + WGL_SET_PROC(Uniform3i); + WGL_SET_PROC(Uniform3fv); + WGL_SET_PROC(Uniform3iv); + WGL_SET_PROC(Uniform4f); + WGL_SET_PROC(Uniform4i); + WGL_SET_PROC(Uniform4fv); + WGL_SET_PROC(Uniform4iv); + WGL_SET_PROC(UniformMatrix2fv); + WGL_SET_PROC(UniformMatrix3fv); + WGL_SET_PROC(UniformMatrix4fv); + WGL_SET_PROC(UseProgram); + WGL_SET_PROC(VertexAttrib4fv); + WGL_SET_PROC(VertexAttribPointer); + WGL_SET_PROC(BindFragDataLocationIndexed); + + if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_vertex_array_object")) { + // no ARB suffix for GL_ARB_vertex_array_object + WGL_SET_PROC(BindVertexArray); + WGL_SET_PROC(DeleteVertexArrays); + WGL_SET_PROC(GenVertexArrays); + } + + // 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) || extensions.has("GL_ARB_framebuffer_object")) { + WGL_SET_PROC(GenFramebuffers); + WGL_SET_PROC(GetFramebufferAttachmentParameteriv); + WGL_SET_PROC(GetRenderbufferParameteriv); + WGL_SET_PROC(BindFramebuffer); + WGL_SET_PROC(FramebufferTexture2D); + WGL_SET_PROC(CheckFramebufferStatus); + WGL_SET_PROC(DeleteFramebuffers); + WGL_SET_PROC(RenderbufferStorage); + WGL_SET_PROC(GenRenderbuffers); + WGL_SET_PROC(DeleteRenderbuffers); + WGL_SET_PROC(FramebufferRenderbuffer); + WGL_SET_PROC(BindRenderbuffer); + WGL_SET_PROC(RenderbufferStorageMultisample); + WGL_SET_PROC(BlitFramebuffer); + } else if (extensions.has("GL_EXT_framebuffer_object")) { + WGL_SET_PROC_SUFFIX(GenFramebuffers, EXT); + WGL_SET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT); + WGL_SET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT); + WGL_SET_PROC_SUFFIX(BindFramebuffer, EXT); + WGL_SET_PROC_SUFFIX(FramebufferTexture2D, EXT); + WGL_SET_PROC_SUFFIX(CheckFramebufferStatus, EXT); + WGL_SET_PROC_SUFFIX(DeleteFramebuffers, EXT); + WGL_SET_PROC_SUFFIX(RenderbufferStorage, EXT); + WGL_SET_PROC_SUFFIX(GenRenderbuffers, EXT); + WGL_SET_PROC_SUFFIX(DeleteRenderbuffers, EXT); + WGL_SET_PROC_SUFFIX(FramebufferRenderbuffer, EXT); + WGL_SET_PROC_SUFFIX(BindRenderbuffer, EXT); + if (extensions.has("GL_EXT_framebuffer_multisample")) { + WGL_SET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT); + } + if (extensions.has("GL_EXT_framebuffer_blit")) { + WGL_SET_PROC_SUFFIX(BlitFramebuffer, EXT); + } + } else { + // we must have FBOs + delete interface; + return NULL; + } + WGL_SET_PROC(MapBuffer); + WGL_SET_PROC(UnmapBuffer); + + if (extensions.has("GL_NV_path_rendering")) { + WGL_SET_PROC_SUFFIX(PathCommands, NV); + WGL_SET_PROC_SUFFIX(PathCoords, NV); + WGL_SET_PROC_SUFFIX(PathSubCommands, NV); + WGL_SET_PROC_SUFFIX(PathSubCoords, NV); + WGL_SET_PROC_SUFFIX(PathString, NV); + WGL_SET_PROC_SUFFIX(PathGlyphs, NV); + WGL_SET_PROC_SUFFIX(PathGlyphRange, NV); + WGL_SET_PROC_SUFFIX(WeightPaths, NV); + WGL_SET_PROC_SUFFIX(CopyPath, NV); + WGL_SET_PROC_SUFFIX(InterpolatePaths, NV); + WGL_SET_PROC_SUFFIX(TransformPath, NV); + WGL_SET_PROC_SUFFIX(PathParameteriv, NV); + WGL_SET_PROC_SUFFIX(PathParameteri, NV); + WGL_SET_PROC_SUFFIX(PathParameterfv, NV); + WGL_SET_PROC_SUFFIX(PathParameterf, NV); + WGL_SET_PROC_SUFFIX(PathDashArray, NV); + WGL_SET_PROC_SUFFIX(GenPaths, NV); + WGL_SET_PROC_SUFFIX(DeletePaths, NV); + WGL_SET_PROC_SUFFIX(IsPath, NV); + WGL_SET_PROC_SUFFIX(PathStencilFunc, NV); + WGL_SET_PROC_SUFFIX(PathStencilDepthOffset, NV); + WGL_SET_PROC_SUFFIX(StencilFillPath, NV); + WGL_SET_PROC_SUFFIX(StencilStrokePath, NV); + WGL_SET_PROC_SUFFIX(StencilFillPathInstanced, NV); + WGL_SET_PROC_SUFFIX(StencilStrokePathInstanced, NV); + WGL_SET_PROC_SUFFIX(PathCoverDepthFunc, NV); + WGL_SET_PROC_SUFFIX(PathColorGen, NV); + WGL_SET_PROC_SUFFIX(PathTexGen, NV); + WGL_SET_PROC_SUFFIX(PathFogGen, NV); + WGL_SET_PROC_SUFFIX(CoverFillPath, NV); + WGL_SET_PROC_SUFFIX(CoverStrokePath, NV); + WGL_SET_PROC_SUFFIX(CoverFillPathInstanced, NV); + WGL_SET_PROC_SUFFIX(CoverStrokePathInstanced, NV); + WGL_SET_PROC_SUFFIX(GetPathParameteriv, NV); + WGL_SET_PROC_SUFFIX(GetPathParameterfv, NV); + WGL_SET_PROC_SUFFIX(GetPathCommands, NV); + WGL_SET_PROC_SUFFIX(GetPathCoords, NV); + WGL_SET_PROC_SUFFIX(GetPathDashArray, NV); + WGL_SET_PROC_SUFFIX(GetPathMetrics, NV); + WGL_SET_PROC_SUFFIX(GetPathMetricRange, NV); + WGL_SET_PROC_SUFFIX(GetPathSpacing, NV); + WGL_SET_PROC_SUFFIX(GetPathColorGeniv, NV); + WGL_SET_PROC_SUFFIX(GetPathColorGenfv, NV); + WGL_SET_PROC_SUFFIX(GetPathTexGeniv, NV); + WGL_SET_PROC_SUFFIX(GetPathTexGenfv, NV); + WGL_SET_PROC_SUFFIX(IsPointInFillPath, NV); + WGL_SET_PROC_SUFFIX(IsPointInStrokePath, NV); + WGL_SET_PROC_SUFFIX(GetPathLength, NV); + WGL_SET_PROC_SUFFIX(PointAlongPath, NV); + } + + interface->fBindingsExported = kDesktop_GrGLBinding; + + return interface; + } else { + return NULL; + } +} diff --git a/gpu/gl/win/SkNativeGLContext_win.cpp b/gpu/gl/win/SkNativeGLContext_win.cpp new file mode 100644 index 00000000..4c736994 --- /dev/null +++ b/gpu/gl/win/SkNativeGLContext_win.cpp @@ -0,0 +1,114 @@ + +/* + * 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 "SkWGL.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; + } + + if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, true))) { + 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"); + } +} |