GrGLCreateNativeInterface_win.cpp revision 9c1f1ac5d399c73f5f331bdf7b392ea7f0c44daf
1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#include "gl/GrGLInterface.h"
11#include "../GrGLUtil.h"
12#define WIN32_LEAN_AND_MEAN
13#include <Windows.h>
14#include <GL/GL.h>
15
16/*
17 * Windows makes the GL funcs all be __stdcall instead of __cdecl :(
18 * This implementation will only work if GR_GL_FUNCTION_TYPE is __stdcall.
19 * Otherwise, a springboard would be needed that hides the calling convention.
20 */
21
22#define GR_GL_GET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F);
23#define GR_GL_GET_PROC_SUFFIX(F, S) interface->f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F #S);
24
25const GrGLInterface* GrGLCreateNativeInterface() {
26    // wglGetProcAddress requires a context.
27    // GL Function pointers retrieved in one context may not be valid in another
28    // context. For that reason we create a new GrGLInterface each time we're
29    // called.
30    if (NULL != wglGetCurrentContext()) {
31        const char* versionString = (const char*) glGetString(GL_VERSION);
32        const char* extString = (const char*) glGetString(GL_EXTENSIONS);
33        GrGLVersion glVer = GrGLGetVersionFromString(versionString);
34
35        if (glVer < GR_GL_VER(1,5)) {
36            // We must have array and element_array buffer objects.
37            return NULL;
38        }
39        GrGLInterface* interface = new GrGLInterface();
40
41        // Functions that are part of GL 1.1 will return NULL in
42        // wglGetProcAddress
43        interface->fBindTexture = glBindTexture;
44        interface->fBlendFunc = glBlendFunc;
45
46        if (glVer >= GR_GL_VER(1,4) ||
47            GrGLHasExtensionFromString("GL_ARB_imaging", extString)) {
48            GR_GL_GET_PROC(BlendColor);
49            GR_GL_GET_PROC(BlendEquation);
50        } else {
51            if (GrGLHasExtensionFromString("GL_EXT_blend_color", extString)) {
52                GR_GL_GET_PROC_SUFFIX(BlendColor, EXT);
53            }
54            if (GrGLHasExtensionFromString("GL_EXT_blend_minmax", extString) ||
55                GrGLHasExtensionFromString("GL_EXT_blend_subtract", extString)) {
56                GR_GL_GET_PROC_SUFFIX(BlendEquation, EXT);
57            }
58        }
59
60        interface->fClear = glClear;
61        interface->fClearColor = glClearColor;
62        interface->fClearStencil = glClearStencil;
63        interface->fColorMask = glColorMask;
64        interface->fColorPointer = glColorPointer;
65        interface->fCullFace = glCullFace;
66        interface->fDeleteTextures = glDeleteTextures;
67        interface->fDepthMask = glDepthMask;
68        interface->fDisable = glDisable;
69        interface->fDrawArrays = glDrawArrays;
70        interface->fDrawElements = glDrawElements;
71        interface->fDrawBuffer = glDrawBuffer;
72        interface->fEnable = glEnable;
73        interface->fFrontFace = glFrontFace;
74        interface->fFinish = glFinish;
75        interface->fFlush = glFlush;
76        interface->fGenTextures = glGenTextures;
77        interface->fGetError = glGetError;
78        interface->fGetIntegerv = glGetIntegerv;
79        interface->fGetString = glGetString;
80        interface->fGetTexLevelParameteriv = glGetTexLevelParameteriv;
81        interface->fLineWidth = glLineWidth;
82        interface->fPixelStorei = glPixelStorei;
83        interface->fReadBuffer = glReadBuffer;
84        interface->fReadPixels = glReadPixels;
85        interface->fScissor = glScissor;
86        interface->fStencilFunc = glStencilFunc;
87        interface->fStencilMask = glStencilMask;
88        interface->fStencilOp = glStencilOp;
89        interface->fTexImage2D = glTexImage2D;
90        interface->fTexParameteri = glTexParameteri;
91        if (glVer >= GR_GL_VER(4,2) ||
92            GrGLHasExtensionFromString("GL_ARB_texture_storage", extString)) {
93            GR_GL_GET_PROC(TexStorage2D);
94        } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", extString)) {
95            GR_GL_GET_PROC_SUFFIX(TexStorage2D, EXT);
96        }
97        interface->fTexSubImage2D = glTexSubImage2D;
98        interface->fViewport = glViewport;
99
100        GR_GL_GET_PROC(ActiveTexture);
101        GR_GL_GET_PROC(AttachShader);
102        GR_GL_GET_PROC(BeginQuery);
103        GR_GL_GET_PROC(BindAttribLocation);
104        GR_GL_GET_PROC(BindBuffer);
105        GR_GL_GET_PROC(BindFragDataLocation);
106        GR_GL_GET_PROC(BufferData);
107        GR_GL_GET_PROC(BufferSubData);
108        GR_GL_GET_PROC(CompileShader);
109        GR_GL_GET_PROC(CompressedTexImage2D);
110        GR_GL_GET_PROC(CreateProgram);
111        GR_GL_GET_PROC(CreateShader);
112        GR_GL_GET_PROC(DeleteBuffers);
113        GR_GL_GET_PROC(DeleteQueries);
114        GR_GL_GET_PROC(DeleteProgram);
115        GR_GL_GET_PROC(DeleteShader);
116        GR_GL_GET_PROC(DisableVertexAttribArray);
117        GR_GL_GET_PROC(DrawBuffers);
118        GR_GL_GET_PROC(EnableVertexAttribArray);
119        GR_GL_GET_PROC(EndQuery);
120        GR_GL_GET_PROC(GenBuffers);
121        GR_GL_GET_PROC(GenQueries);
122        GR_GL_GET_PROC(GetBufferParameteriv);
123        GR_GL_GET_PROC(GetQueryiv);
124        GR_GL_GET_PROC(GetQueryObjectiv);
125        GR_GL_GET_PROC(GetQueryObjectuiv);
126        if (glVer > GR_GL_VER(3,3) ||
127            GrGLHasExtensionFromString("GL_ARB_timer_query", extString)) {
128            GR_GL_GET_PROC(GetQueryObjecti64v);
129            GR_GL_GET_PROC(GetQueryObjectui64v);
130            GR_GL_GET_PROC(QueryCounter);
131        } else if (GrGLHasExtensionFromString("GL_EXT_timer_query", extString)) {
132            GR_GL_GET_PROC_SUFFIX(GetQueryObjecti64v, EXT);
133            GR_GL_GET_PROC_SUFFIX(GetQueryObjectui64v, EXT);
134        }
135        GR_GL_GET_PROC(GetProgramInfoLog);
136        GR_GL_GET_PROC(GetProgramiv);
137        GR_GL_GET_PROC(GetShaderInfoLog);
138        GR_GL_GET_PROC(GetShaderiv);
139        GR_GL_GET_PROC(GetUniformLocation);
140        GR_GL_GET_PROC(LinkProgram);
141        if (GrGLHasExtensionFromString("GL_NV_framebuffer_multisample_coverage", extString)) {
142            GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisampleCoverage, NV);
143        }
144        GR_GL_GET_PROC(ShaderSource);
145        GR_GL_GET_PROC(StencilFuncSeparate);
146        GR_GL_GET_PROC(StencilMaskSeparate);
147        GR_GL_GET_PROC(StencilOpSeparate);
148        GR_GL_GET_PROC(Uniform1f);
149        GR_GL_GET_PROC(Uniform1i);
150        GR_GL_GET_PROC(Uniform1fv);
151        GR_GL_GET_PROC(Uniform1iv);
152        GR_GL_GET_PROC(Uniform2f);
153        GR_GL_GET_PROC(Uniform2i);
154        GR_GL_GET_PROC(Uniform2fv);
155        GR_GL_GET_PROC(Uniform2iv);
156        GR_GL_GET_PROC(Uniform3f);
157        GR_GL_GET_PROC(Uniform3i);
158        GR_GL_GET_PROC(Uniform3fv);
159        GR_GL_GET_PROC(Uniform3iv);
160        GR_GL_GET_PROC(Uniform4f);
161        GR_GL_GET_PROC(Uniform4i);
162        GR_GL_GET_PROC(Uniform4fv);
163        GR_GL_GET_PROC(Uniform4iv);
164        GR_GL_GET_PROC(UniformMatrix2fv);
165        GR_GL_GET_PROC(UniformMatrix3fv);
166        GR_GL_GET_PROC(UniformMatrix4fv);
167        GR_GL_GET_PROC(UseProgram);
168        GR_GL_GET_PROC(VertexAttrib4fv);
169        GR_GL_GET_PROC(VertexAttribPointer);
170        GR_GL_GET_PROC(BindFragDataLocationIndexed);
171
172        // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since
173        // GL_ARB_framebuffer_object doesn't use ARB suffix.)
174        if (glVer > GR_GL_VER(3,0) ||
175            GrGLHasExtensionFromString("GL_ARB_framebuffer_object", extString)) {
176            GR_GL_GET_PROC(GenFramebuffers);
177            GR_GL_GET_PROC(GetFramebufferAttachmentParameteriv);
178            GR_GL_GET_PROC(GetRenderbufferParameteriv);
179            GR_GL_GET_PROC(BindFramebuffer);
180            GR_GL_GET_PROC(FramebufferTexture2D);
181            GR_GL_GET_PROC(CheckFramebufferStatus);
182            GR_GL_GET_PROC(DeleteFramebuffers);
183            GR_GL_GET_PROC(RenderbufferStorage);
184            GR_GL_GET_PROC(GenRenderbuffers);
185            GR_GL_GET_PROC(DeleteRenderbuffers);
186            GR_GL_GET_PROC(FramebufferRenderbuffer);
187            GR_GL_GET_PROC(BindRenderbuffer);
188            GR_GL_GET_PROC(RenderbufferStorageMultisample);
189            GR_GL_GET_PROC(BlitFramebuffer);
190        } else if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object",
191                   extString)) {
192            GR_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT);
193            GR_GL_GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT);
194            GR_GL_GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT);
195            GR_GL_GET_PROC_SUFFIX(BindFramebuffer, EXT);
196            GR_GL_GET_PROC_SUFFIX(FramebufferTexture2D, EXT);
197            GR_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT);
198            GR_GL_GET_PROC_SUFFIX(DeleteFramebuffers, EXT);
199            GR_GL_GET_PROC_SUFFIX(RenderbufferStorage, EXT);
200            GR_GL_GET_PROC_SUFFIX(GenRenderbuffers, EXT);
201            GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
202            GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
203            GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT);
204            if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", extString)) {
205                GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
206            }
207            if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", extString)) {
208                GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT);
209            }
210        } else {
211            // we must have FBOs
212            delete interface;
213            return NULL;
214        }
215        GR_GL_GET_PROC(MapBuffer);
216        GR_GL_GET_PROC(UnmapBuffer);
217
218        interface->fBindingsExported = kDesktop_GrGLBinding;
219
220        return interface;
221    } else {
222        return NULL;
223    }
224}
225