GrGLCreateNativeInterface_win.cpp revision fe11cb6486adfccc1a9ca9658ae25907192a8642
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->fLoadIdentity = glLoadIdentity;
83        interface->fLoadMatrixf = glLoadMatrixf;
84        interface->fMatrixMode = glMatrixMode;
85        interface->fPixelStorei = glPixelStorei;
86        interface->fReadBuffer = glReadBuffer;
87        interface->fReadPixels = glReadPixels;
88        interface->fScissor = glScissor;
89        interface->fStencilFunc = glStencilFunc;
90        interface->fStencilMask = glStencilMask;
91        interface->fStencilOp = glStencilOp;
92        interface->fTexImage2D = glTexImage2D;
93        interface->fTexParameteri = glTexParameteri;
94        interface->fTexParameteriv = glTexParameteriv;
95        if (glVer >= GR_GL_VER(4,2) ||
96            GrGLHasExtensionFromString("GL_ARB_texture_storage", extString)) {
97            GR_GL_GET_PROC(TexStorage2D);
98        } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", extString)) {
99            GR_GL_GET_PROC_SUFFIX(TexStorage2D, EXT);
100        }
101        interface->fTexSubImage2D = glTexSubImage2D;
102        interface->fViewport = glViewport;
103
104        GR_GL_GET_PROC(ActiveTexture);
105        GR_GL_GET_PROC(AttachShader);
106        GR_GL_GET_PROC(BeginQuery);
107        GR_GL_GET_PROC(BindAttribLocation);
108        GR_GL_GET_PROC(BindBuffer);
109        GR_GL_GET_PROC(BindFragDataLocation);
110        GR_GL_GET_PROC(BufferData);
111        GR_GL_GET_PROC(BufferSubData);
112        GR_GL_GET_PROC(CompileShader);
113        GR_GL_GET_PROC(CompressedTexImage2D);
114        GR_GL_GET_PROC(CreateProgram);
115        GR_GL_GET_PROC(CreateShader);
116        GR_GL_GET_PROC(DeleteBuffers);
117        GR_GL_GET_PROC(DeleteQueries);
118        GR_GL_GET_PROC(DeleteProgram);
119        GR_GL_GET_PROC(DeleteShader);
120        GR_GL_GET_PROC(DisableVertexAttribArray);
121        GR_GL_GET_PROC(DrawBuffers);
122        GR_GL_GET_PROC(EnableVertexAttribArray);
123        GR_GL_GET_PROC(EndQuery);
124        GR_GL_GET_PROC(GenBuffers);
125        GR_GL_GET_PROC(GenQueries);
126        GR_GL_GET_PROC(GetBufferParameteriv);
127        GR_GL_GET_PROC(GetQueryiv);
128        GR_GL_GET_PROC(GetQueryObjectiv);
129        GR_GL_GET_PROC(GetQueryObjectuiv);
130        if (glVer > GR_GL_VER(3,3) ||
131            GrGLHasExtensionFromString("GL_ARB_timer_query", extString)) {
132            GR_GL_GET_PROC(GetQueryObjecti64v);
133            GR_GL_GET_PROC(GetQueryObjectui64v);
134            GR_GL_GET_PROC(QueryCounter);
135        } else if (GrGLHasExtensionFromString("GL_EXT_timer_query", extString)) {
136            GR_GL_GET_PROC_SUFFIX(GetQueryObjecti64v, EXT);
137            GR_GL_GET_PROC_SUFFIX(GetQueryObjectui64v, EXT);
138        }
139        GR_GL_GET_PROC(GetProgramInfoLog);
140        GR_GL_GET_PROC(GetProgramiv);
141        GR_GL_GET_PROC(GetShaderInfoLog);
142        GR_GL_GET_PROC(GetShaderiv);
143        GR_GL_GET_PROC(GetUniformLocation);
144        GR_GL_GET_PROC(LinkProgram);
145        if (GrGLHasExtensionFromString("GL_NV_framebuffer_multisample_coverage", extString)) {
146            GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisampleCoverage, NV);
147        }
148        GR_GL_GET_PROC(ShaderSource);
149        GR_GL_GET_PROC(StencilFuncSeparate);
150        GR_GL_GET_PROC(StencilMaskSeparate);
151        GR_GL_GET_PROC(StencilOpSeparate);
152        GR_GL_GET_PROC(Uniform1f);
153        GR_GL_GET_PROC(Uniform1i);
154        GR_GL_GET_PROC(Uniform1fv);
155        GR_GL_GET_PROC(Uniform1iv);
156        GR_GL_GET_PROC(Uniform2f);
157        GR_GL_GET_PROC(Uniform2i);
158        GR_GL_GET_PROC(Uniform2fv);
159        GR_GL_GET_PROC(Uniform2iv);
160        GR_GL_GET_PROC(Uniform3f);
161        GR_GL_GET_PROC(Uniform3i);
162        GR_GL_GET_PROC(Uniform3fv);
163        GR_GL_GET_PROC(Uniform3iv);
164        GR_GL_GET_PROC(Uniform4f);
165        GR_GL_GET_PROC(Uniform4i);
166        GR_GL_GET_PROC(Uniform4fv);
167        GR_GL_GET_PROC(Uniform4iv);
168        GR_GL_GET_PROC(UniformMatrix2fv);
169        GR_GL_GET_PROC(UniformMatrix3fv);
170        GR_GL_GET_PROC(UniformMatrix4fv);
171        GR_GL_GET_PROC(UseProgram);
172        GR_GL_GET_PROC(VertexAttrib4fv);
173        GR_GL_GET_PROC(VertexAttribPointer);
174        GR_GL_GET_PROC(BindFragDataLocationIndexed);
175
176        // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since
177        // GL_ARB_framebuffer_object doesn't use ARB suffix.)
178        if (glVer > GR_GL_VER(3,0) ||
179            GrGLHasExtensionFromString("GL_ARB_framebuffer_object", extString)) {
180            GR_GL_GET_PROC(GenFramebuffers);
181            GR_GL_GET_PROC(GetFramebufferAttachmentParameteriv);
182            GR_GL_GET_PROC(GetRenderbufferParameteriv);
183            GR_GL_GET_PROC(BindFramebuffer);
184            GR_GL_GET_PROC(FramebufferTexture2D);
185            GR_GL_GET_PROC(CheckFramebufferStatus);
186            GR_GL_GET_PROC(DeleteFramebuffers);
187            GR_GL_GET_PROC(RenderbufferStorage);
188            GR_GL_GET_PROC(GenRenderbuffers);
189            GR_GL_GET_PROC(DeleteRenderbuffers);
190            GR_GL_GET_PROC(FramebufferRenderbuffer);
191            GR_GL_GET_PROC(BindRenderbuffer);
192            GR_GL_GET_PROC(RenderbufferStorageMultisample);
193            GR_GL_GET_PROC(BlitFramebuffer);
194        } else if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object",
195                   extString)) {
196            GR_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT);
197            GR_GL_GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT);
198            GR_GL_GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT);
199            GR_GL_GET_PROC_SUFFIX(BindFramebuffer, EXT);
200            GR_GL_GET_PROC_SUFFIX(FramebufferTexture2D, EXT);
201            GR_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT);
202            GR_GL_GET_PROC_SUFFIX(DeleteFramebuffers, EXT);
203            GR_GL_GET_PROC_SUFFIX(RenderbufferStorage, EXT);
204            GR_GL_GET_PROC_SUFFIX(GenRenderbuffers, EXT);
205            GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
206            GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
207            GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT);
208            if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", extString)) {
209                GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
210            }
211            if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", extString)) {
212                GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT);
213            }
214        } else {
215            // we must have FBOs
216            delete interface;
217            return NULL;
218        }
219        GR_GL_GET_PROC(MapBuffer);
220        GR_GL_GET_PROC(UnmapBuffer);
221
222        if (GrGLHasExtensionFromString("GL_NV_path_rendering", extString)) {
223            GR_GL_GET_PROC_SUFFIX(PathCommands, NV);
224            GR_GL_GET_PROC_SUFFIX(PathCoords, NV);
225            GR_GL_GET_PROC_SUFFIX(PathSubCommands, NV);
226            GR_GL_GET_PROC_SUFFIX(PathSubCoords, NV);
227            GR_GL_GET_PROC_SUFFIX(PathString, NV);
228            GR_GL_GET_PROC_SUFFIX(PathGlyphs, NV);
229            GR_GL_GET_PROC_SUFFIX(PathGlyphRange, NV);
230            GR_GL_GET_PROC_SUFFIX(WeightPaths, NV);
231            GR_GL_GET_PROC_SUFFIX(CopyPath, NV);
232            GR_GL_GET_PROC_SUFFIX(InterpolatePaths, NV);
233            GR_GL_GET_PROC_SUFFIX(TransformPath, NV);
234            GR_GL_GET_PROC_SUFFIX(PathParameteriv, NV);
235            GR_GL_GET_PROC_SUFFIX(PathParameteri, NV);
236            GR_GL_GET_PROC_SUFFIX(PathParameterfv, NV);
237            GR_GL_GET_PROC_SUFFIX(PathParameterf, NV);
238            GR_GL_GET_PROC_SUFFIX(PathDashArray, NV);
239            GR_GL_GET_PROC_SUFFIX(GenPaths, NV);
240            GR_GL_GET_PROC_SUFFIX(DeletePaths, NV);
241            GR_GL_GET_PROC_SUFFIX(IsPath, NV);
242            GR_GL_GET_PROC_SUFFIX(PathStencilFunc, NV);
243            GR_GL_GET_PROC_SUFFIX(PathStencilDepthOffset, NV);
244            GR_GL_GET_PROC_SUFFIX(StencilFillPath, NV);
245            GR_GL_GET_PROC_SUFFIX(StencilStrokePath, NV);
246            GR_GL_GET_PROC_SUFFIX(StencilFillPathInstanced, NV);
247            GR_GL_GET_PROC_SUFFIX(StencilStrokePathInstanced, NV);
248            GR_GL_GET_PROC_SUFFIX(PathCoverDepthFunc, NV);
249            GR_GL_GET_PROC_SUFFIX(PathColorGen, NV);
250            GR_GL_GET_PROC_SUFFIX(PathTexGen, NV);
251            GR_GL_GET_PROC_SUFFIX(PathFogGen, NV);
252            GR_GL_GET_PROC_SUFFIX(CoverFillPath, NV);
253            GR_GL_GET_PROC_SUFFIX(CoverStrokePath, NV);
254            GR_GL_GET_PROC_SUFFIX(CoverFillPathInstanced, NV);
255            GR_GL_GET_PROC_SUFFIX(CoverStrokePathInstanced, NV);
256            GR_GL_GET_PROC_SUFFIX(GetPathParameteriv, NV);
257            GR_GL_GET_PROC_SUFFIX(GetPathParameterfv, NV);
258            GR_GL_GET_PROC_SUFFIX(GetPathCommands, NV);
259            GR_GL_GET_PROC_SUFFIX(GetPathCoords, NV);
260            GR_GL_GET_PROC_SUFFIX(GetPathDashArray, NV);
261            GR_GL_GET_PROC_SUFFIX(GetPathMetrics, NV);
262            GR_GL_GET_PROC_SUFFIX(GetPathMetricRange, NV);
263            GR_GL_GET_PROC_SUFFIX(GetPathSpacing, NV);
264            GR_GL_GET_PROC_SUFFIX(GetPathColorGeniv, NV);
265            GR_GL_GET_PROC_SUFFIX(GetPathColorGenfv, NV);
266            GR_GL_GET_PROC_SUFFIX(GetPathTexGeniv, NV);
267            GR_GL_GET_PROC_SUFFIX(GetPathTexGenfv, NV);
268            GR_GL_GET_PROC_SUFFIX(IsPointInFillPath, NV);
269            GR_GL_GET_PROC_SUFFIX(IsPointInStrokePath, NV);
270            GR_GL_GET_PROC_SUFFIX(GetPathLength, NV);
271            GR_GL_GET_PROC_SUFFIX(PointAlongPath, NV);
272        }
273
274        interface->fBindingsExported = kDesktop_GrGLBinding;
275
276        return interface;
277    } else {
278        return NULL;
279    }
280}
281