|
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 #include "gl/GrGLInterface.h" |
|
10 #include "gl/GrGLUtil.h" |
|
11 #define WIN32_LEAN_AND_MEAN |
|
12 #include <windows.h> |
|
13 |
|
14 /* |
|
15 * Windows makes the GL funcs all be __stdcall instead of __cdecl :( |
|
16 * This implementation will only work if GR_GL_FUNCTION_TYPE is __stdcall. |
|
17 * Otherwise, a springboard would be needed that hides the calling convention. |
|
18 */ |
|
19 |
|
20 #define SET_PROC(F) interface->fFunctions.f ## F = (GrGL ## F ## Proc) GetProcAddress(alu.get(), "gl" #F); |
|
21 #define WGL_SET_PROC(F) interface->fFunctions.f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F); |
|
22 #define WGL_SET_PROC_SUFFIX(F, S) interface->fFunctions.f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F #S); |
|
23 |
|
24 class AutoLibraryUnload { |
|
25 public: |
|
26 AutoLibraryUnload(const char* moduleName) { |
|
27 fModule = LoadLibrary(moduleName); |
|
28 } |
|
29 ~AutoLibraryUnload() { |
|
30 if (NULL != fModule) { |
|
31 FreeLibrary(fModule); |
|
32 } |
|
33 } |
|
34 HMODULE get() const { return fModule; } |
|
35 |
|
36 private: |
|
37 HMODULE fModule; |
|
38 }; |
|
39 |
|
40 const GrGLInterface* GrGLCreateNativeInterface() { |
|
41 AutoLibraryUnload alu("opengl32.dll"); |
|
42 if (NULL == alu.get()) { |
|
43 return NULL; |
|
44 } |
|
45 |
|
46 if (NULL != wglGetCurrentContext()) { |
|
47 |
|
48 // These should always be present and don't require wglGetProcAddress |
|
49 GrGLGetStringProc glGetString = |
|
50 (GrGLGetStringProc) GetProcAddress(alu.get(), "glGetString"); |
|
51 GrGLGetIntegervProc glGetIntegerv = |
|
52 (GrGLGetIntegervProc) GetProcAddress(alu.get(), "glGetIntegerv"); |
|
53 if (NULL == glGetString || NULL == glGetIntegerv) { |
|
54 return NULL; |
|
55 } |
|
56 |
|
57 // This may or may not succeed depending on the gl version. |
|
58 GrGLGetStringiProc glGetStringi = (GrGLGetStringiProc) wglGetProcAddress("glGetStringi"); |
|
59 |
|
60 GrGLExtensions extensions; |
|
61 if (!extensions.init(kGL_GrGLStandard, glGetString, glGetStringi, glGetIntegerv)) { |
|
62 return NULL; |
|
63 } |
|
64 const char* versionString = (const char*) glGetString(GR_GL_VERSION); |
|
65 GrGLVersion glVer = GrGLGetVersionFromString(versionString); |
|
66 |
|
67 if (glVer < GR_GL_VER(1,5)) { |
|
68 // We must have array and element_array buffer objects. |
|
69 return NULL; |
|
70 } |
|
71 GrGLInterface* interface = SkNEW(GrGLInterface); |
|
72 |
|
73 // Functions that are part of GL 1.1 will return NULL in |
|
74 // wglGetProcAddress |
|
75 SET_PROC(BindTexture) |
|
76 SET_PROC(BlendFunc) |
|
77 |
|
78 if (glVer >= GR_GL_VER(1,4) || |
|
79 extensions.has("GL_ARB_imaging") || |
|
80 extensions.has("GL_EXT_blend_color")) { |
|
81 WGL_SET_PROC(BlendColor); |
|
82 } |
|
83 |
|
84 SET_PROC(Clear) |
|
85 SET_PROC(ClearColor) |
|
86 SET_PROC(ClearStencil) |
|
87 SET_PROC(ColorMask) |
|
88 SET_PROC(CopyTexSubImage2D) |
|
89 SET_PROC(CullFace) |
|
90 SET_PROC(DeleteTextures) |
|
91 SET_PROC(DepthMask) |
|
92 SET_PROC(Disable) |
|
93 SET_PROC(DrawArrays) |
|
94 SET_PROC(DrawElements) |
|
95 SET_PROC(DrawBuffer) |
|
96 SET_PROC(Enable) |
|
97 SET_PROC(FrontFace) |
|
98 SET_PROC(Finish) |
|
99 SET_PROC(Flush) |
|
100 SET_PROC(GenTextures) |
|
101 SET_PROC(GetError) |
|
102 SET_PROC(GetIntegerv) |
|
103 SET_PROC(GetString) |
|
104 SET_PROC(GetTexLevelParameteriv) |
|
105 SET_PROC(LineWidth) |
|
106 SET_PROC(LoadIdentity) |
|
107 SET_PROC(LoadMatrixf) |
|
108 SET_PROC(MatrixMode) |
|
109 SET_PROC(PixelStorei) |
|
110 SET_PROC(ReadBuffer) |
|
111 SET_PROC(ReadPixels) |
|
112 SET_PROC(Scissor) |
|
113 SET_PROC(StencilFunc) |
|
114 SET_PROC(StencilMask) |
|
115 SET_PROC(StencilOp) |
|
116 SET_PROC(TexGenfv) |
|
117 SET_PROC(TexGeni) |
|
118 SET_PROC(TexImage2D) |
|
119 SET_PROC(TexParameteri) |
|
120 SET_PROC(TexParameteriv) |
|
121 if (glVer >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage")) { |
|
122 WGL_SET_PROC(TexStorage2D); |
|
123 } else if (extensions.has("GL_EXT_texture_storage")) { |
|
124 WGL_SET_PROC_SUFFIX(TexStorage2D, EXT); |
|
125 } |
|
126 SET_PROC(TexSubImage2D) |
|
127 SET_PROC(Viewport) |
|
128 |
|
129 WGL_SET_PROC(ActiveTexture); |
|
130 WGL_SET_PROC(AttachShader); |
|
131 WGL_SET_PROC(BeginQuery); |
|
132 WGL_SET_PROC(BindAttribLocation); |
|
133 WGL_SET_PROC(BindBuffer); |
|
134 WGL_SET_PROC(BindFragDataLocation); |
|
135 WGL_SET_PROC(BufferData); |
|
136 WGL_SET_PROC(BufferSubData); |
|
137 WGL_SET_PROC(CompileShader); |
|
138 WGL_SET_PROC(CompressedTexImage2D); |
|
139 WGL_SET_PROC(CreateProgram); |
|
140 WGL_SET_PROC(CreateShader); |
|
141 WGL_SET_PROC(DeleteBuffers); |
|
142 WGL_SET_PROC(DeleteQueries); |
|
143 WGL_SET_PROC(DeleteProgram); |
|
144 WGL_SET_PROC(DeleteShader); |
|
145 WGL_SET_PROC(DisableVertexAttribArray); |
|
146 WGL_SET_PROC(DrawBuffers); |
|
147 WGL_SET_PROC(EnableVertexAttribArray); |
|
148 WGL_SET_PROC(EndQuery); |
|
149 WGL_SET_PROC(GenBuffers); |
|
150 WGL_SET_PROC(GenerateMipmap); |
|
151 WGL_SET_PROC(GenQueries); |
|
152 WGL_SET_PROC(GetBufferParameteriv); |
|
153 WGL_SET_PROC(GetQueryiv); |
|
154 WGL_SET_PROC(GetQueryObjectiv); |
|
155 WGL_SET_PROC(GetQueryObjectuiv); |
|
156 if (glVer > GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) { |
|
157 WGL_SET_PROC(GetQueryObjecti64v); |
|
158 WGL_SET_PROC(GetQueryObjectui64v); |
|
159 WGL_SET_PROC(QueryCounter); |
|
160 } else if (extensions.has("GL_EXT_timer_query")) { |
|
161 WGL_SET_PROC_SUFFIX(GetQueryObjecti64v, EXT); |
|
162 WGL_SET_PROC_SUFFIX(GetQueryObjectui64v, EXT); |
|
163 } |
|
164 WGL_SET_PROC(GetProgramInfoLog); |
|
165 WGL_SET_PROC(GetProgramiv); |
|
166 WGL_SET_PROC(GetShaderInfoLog); |
|
167 WGL_SET_PROC(GetShaderiv); |
|
168 WGL_SET_PROC(GetStringi) |
|
169 WGL_SET_PROC(GetUniformLocation); |
|
170 WGL_SET_PROC(LinkProgram); |
|
171 WGL_SET_PROC(ShaderSource); |
|
172 WGL_SET_PROC(StencilFuncSeparate); |
|
173 WGL_SET_PROC(StencilMaskSeparate); |
|
174 WGL_SET_PROC(StencilOpSeparate); |
|
175 WGL_SET_PROC(Uniform1f); |
|
176 WGL_SET_PROC(Uniform1i); |
|
177 WGL_SET_PROC(Uniform1fv); |
|
178 WGL_SET_PROC(Uniform1iv); |
|
179 WGL_SET_PROC(Uniform2f); |
|
180 WGL_SET_PROC(Uniform2i); |
|
181 WGL_SET_PROC(Uniform2fv); |
|
182 WGL_SET_PROC(Uniform2iv); |
|
183 WGL_SET_PROC(Uniform3f); |
|
184 WGL_SET_PROC(Uniform3i); |
|
185 WGL_SET_PROC(Uniform3fv); |
|
186 WGL_SET_PROC(Uniform3iv); |
|
187 WGL_SET_PROC(Uniform4f); |
|
188 WGL_SET_PROC(Uniform4i); |
|
189 WGL_SET_PROC(Uniform4fv); |
|
190 WGL_SET_PROC(Uniform4iv); |
|
191 WGL_SET_PROC(UniformMatrix2fv); |
|
192 WGL_SET_PROC(UniformMatrix3fv); |
|
193 WGL_SET_PROC(UniformMatrix4fv); |
|
194 WGL_SET_PROC(UseProgram); |
|
195 WGL_SET_PROC(VertexAttrib4fv); |
|
196 WGL_SET_PROC(VertexAttribPointer); |
|
197 WGL_SET_PROC(BindFragDataLocationIndexed); |
|
198 |
|
199 if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_vertex_array_object")) { |
|
200 // no ARB suffix for GL_ARB_vertex_array_object |
|
201 WGL_SET_PROC(BindVertexArray); |
|
202 WGL_SET_PROC(DeleteVertexArrays); |
|
203 WGL_SET_PROC(GenVertexArrays); |
|
204 } |
|
205 |
|
206 // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since |
|
207 // GL_ARB_framebuffer_object doesn't use ARB suffix.) |
|
208 if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) { |
|
209 WGL_SET_PROC(GenFramebuffers); |
|
210 WGL_SET_PROC(GetFramebufferAttachmentParameteriv); |
|
211 WGL_SET_PROC(GetRenderbufferParameteriv); |
|
212 WGL_SET_PROC(BindFramebuffer); |
|
213 WGL_SET_PROC(FramebufferTexture2D); |
|
214 WGL_SET_PROC(CheckFramebufferStatus); |
|
215 WGL_SET_PROC(DeleteFramebuffers); |
|
216 WGL_SET_PROC(RenderbufferStorage); |
|
217 WGL_SET_PROC(GenRenderbuffers); |
|
218 WGL_SET_PROC(DeleteRenderbuffers); |
|
219 WGL_SET_PROC(FramebufferRenderbuffer); |
|
220 WGL_SET_PROC(BindRenderbuffer); |
|
221 WGL_SET_PROC(RenderbufferStorageMultisample); |
|
222 WGL_SET_PROC(BlitFramebuffer); |
|
223 } else if (extensions.has("GL_EXT_framebuffer_object")) { |
|
224 WGL_SET_PROC_SUFFIX(GenFramebuffers, EXT); |
|
225 WGL_SET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT); |
|
226 WGL_SET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT); |
|
227 WGL_SET_PROC_SUFFIX(BindFramebuffer, EXT); |
|
228 WGL_SET_PROC_SUFFIX(FramebufferTexture2D, EXT); |
|
229 WGL_SET_PROC_SUFFIX(CheckFramebufferStatus, EXT); |
|
230 WGL_SET_PROC_SUFFIX(DeleteFramebuffers, EXT); |
|
231 WGL_SET_PROC_SUFFIX(RenderbufferStorage, EXT); |
|
232 WGL_SET_PROC_SUFFIX(GenRenderbuffers, EXT); |
|
233 WGL_SET_PROC_SUFFIX(DeleteRenderbuffers, EXT); |
|
234 WGL_SET_PROC_SUFFIX(FramebufferRenderbuffer, EXT); |
|
235 WGL_SET_PROC_SUFFIX(BindRenderbuffer, EXT); |
|
236 if (extensions.has("GL_EXT_framebuffer_multisample")) { |
|
237 WGL_SET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT); |
|
238 } |
|
239 if (extensions.has("GL_EXT_framebuffer_blit")) { |
|
240 WGL_SET_PROC_SUFFIX(BlitFramebuffer, EXT); |
|
241 } |
|
242 } else { |
|
243 // we must have FBOs |
|
244 delete interface; |
|
245 return NULL; |
|
246 } |
|
247 WGL_SET_PROC(MapBuffer); |
|
248 WGL_SET_PROC(UnmapBuffer); |
|
249 |
|
250 if (extensions.has("GL_NV_path_rendering")) { |
|
251 WGL_SET_PROC_SUFFIX(PathCommands, NV); |
|
252 WGL_SET_PROC_SUFFIX(PathCoords, NV); |
|
253 WGL_SET_PROC_SUFFIX(PathSubCommands, NV); |
|
254 WGL_SET_PROC_SUFFIX(PathSubCoords, NV); |
|
255 WGL_SET_PROC_SUFFIX(PathString, NV); |
|
256 WGL_SET_PROC_SUFFIX(PathGlyphs, NV); |
|
257 WGL_SET_PROC_SUFFIX(PathGlyphRange, NV); |
|
258 WGL_SET_PROC_SUFFIX(WeightPaths, NV); |
|
259 WGL_SET_PROC_SUFFIX(CopyPath, NV); |
|
260 WGL_SET_PROC_SUFFIX(InterpolatePaths, NV); |
|
261 WGL_SET_PROC_SUFFIX(TransformPath, NV); |
|
262 WGL_SET_PROC_SUFFIX(PathParameteriv, NV); |
|
263 WGL_SET_PROC_SUFFIX(PathParameteri, NV); |
|
264 WGL_SET_PROC_SUFFIX(PathParameterfv, NV); |
|
265 WGL_SET_PROC_SUFFIX(PathParameterf, NV); |
|
266 WGL_SET_PROC_SUFFIX(PathDashArray, NV); |
|
267 WGL_SET_PROC_SUFFIX(GenPaths, NV); |
|
268 WGL_SET_PROC_SUFFIX(DeletePaths, NV); |
|
269 WGL_SET_PROC_SUFFIX(IsPath, NV); |
|
270 WGL_SET_PROC_SUFFIX(PathStencilFunc, NV); |
|
271 WGL_SET_PROC_SUFFIX(PathStencilDepthOffset, NV); |
|
272 WGL_SET_PROC_SUFFIX(StencilFillPath, NV); |
|
273 WGL_SET_PROC_SUFFIX(StencilStrokePath, NV); |
|
274 WGL_SET_PROC_SUFFIX(StencilFillPathInstanced, NV); |
|
275 WGL_SET_PROC_SUFFIX(StencilStrokePathInstanced, NV); |
|
276 WGL_SET_PROC_SUFFIX(PathCoverDepthFunc, NV); |
|
277 WGL_SET_PROC_SUFFIX(PathColorGen, NV); |
|
278 WGL_SET_PROC_SUFFIX(PathTexGen, NV); |
|
279 WGL_SET_PROC_SUFFIX(PathFogGen, NV); |
|
280 WGL_SET_PROC_SUFFIX(CoverFillPath, NV); |
|
281 WGL_SET_PROC_SUFFIX(CoverStrokePath, NV); |
|
282 WGL_SET_PROC_SUFFIX(CoverFillPathInstanced, NV); |
|
283 WGL_SET_PROC_SUFFIX(CoverStrokePathInstanced, NV); |
|
284 WGL_SET_PROC_SUFFIX(GetPathParameteriv, NV); |
|
285 WGL_SET_PROC_SUFFIX(GetPathParameterfv, NV); |
|
286 WGL_SET_PROC_SUFFIX(GetPathCommands, NV); |
|
287 WGL_SET_PROC_SUFFIX(GetPathCoords, NV); |
|
288 WGL_SET_PROC_SUFFIX(GetPathDashArray, NV); |
|
289 WGL_SET_PROC_SUFFIX(GetPathMetrics, NV); |
|
290 WGL_SET_PROC_SUFFIX(GetPathMetricRange, NV); |
|
291 WGL_SET_PROC_SUFFIX(GetPathSpacing, NV); |
|
292 WGL_SET_PROC_SUFFIX(GetPathColorGeniv, NV); |
|
293 WGL_SET_PROC_SUFFIX(GetPathColorGenfv, NV); |
|
294 WGL_SET_PROC_SUFFIX(GetPathTexGeniv, NV); |
|
295 WGL_SET_PROC_SUFFIX(GetPathTexGenfv, NV); |
|
296 WGL_SET_PROC_SUFFIX(IsPointInFillPath, NV); |
|
297 WGL_SET_PROC_SUFFIX(IsPointInStrokePath, NV); |
|
298 WGL_SET_PROC_SUFFIX(GetPathLength, NV); |
|
299 WGL_SET_PROC_SUFFIX(PointAlongPath, NV); |
|
300 } |
|
301 |
|
302 if (extensions.has("GL_EXT_debug_marker")) { |
|
303 WGL_SET_PROC_SUFFIX(InsertEventMarker, EXT); |
|
304 WGL_SET_PROC_SUFFIX(PushGroupMarker, EXT); |
|
305 WGL_SET_PROC_SUFFIX(PopGroupMarker, EXT); |
|
306 } |
|
307 |
|
308 interface->fStandard = kGL_GrGLStandard; |
|
309 interface->fExtensions.swap(&extensions); |
|
310 |
|
311 return interface; |
|
312 } else { |
|
313 return NULL; |
|
314 } |
|
315 } |