summaryrefslogtreecommitdiff
path: root/gpu/gl/win
diff options
context:
space:
mode:
Diffstat (limited to 'gpu/gl/win')
-rw-r--r--gpu/gl/win/GrGLCreateNativeInterface_win.cpp316
-rw-r--r--gpu/gl/win/SkNativeGLContext_win.cpp114
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");
+ }
+}