OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "gl/GrGLInterface.h" | 9 #include "gl/GrGLInterface.h" |
10 #include "gl/GrGLUtil.h" | 10 #include "gl/GrGLAssembleInterface.h" |
11 #define WIN32_LEAN_AND_MEAN | 11 #define WIN32_LEAN_AND_MEAN |
12 #include <windows.h> | 12 #include <windows.h> |
13 | 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) GetProcAd
dress(alu.get(), "gl" #F); | |
21 #define WGL_SET_PROC(F) interface->fFunctions.f ## F = (GrGL ## F ## Proc) wglGe
tProcAddress("gl" #F); | |
22 #define WGL_SET_PROC_SUFFIX(F, S) interface->fFunctions.f ## F = (GrGL ## F ## P
roc) wglGetProcAddress("gl" #F #S); | |
23 | |
24 class AutoLibraryUnload { | 14 class AutoLibraryUnload { |
25 public: | 15 public: |
26 AutoLibraryUnload(const char* moduleName) { | 16 AutoLibraryUnload(const char* moduleName) { |
27 fModule = LoadLibrary(moduleName); | 17 fModule = LoadLibrary(moduleName); |
28 } | 18 } |
29 ~AutoLibraryUnload() { | 19 ~AutoLibraryUnload() { |
30 if (NULL != fModule) { | 20 if (NULL != fModule) { |
31 FreeLibrary(fModule); | 21 FreeLibrary(fModule); |
32 } | 22 } |
33 } | 23 } |
34 HMODULE get() const { return fModule; } | 24 HMODULE get() const { return fModule; } |
35 | 25 |
36 private: | 26 private: |
37 HMODULE fModule; | 27 HMODULE fModule; |
38 }; | 28 }; |
39 | 29 |
40 const GrGLInterface* GrGLCreateNativeInterface() { | 30 class GLProcGetter { |
41 AutoLibraryUnload alu("opengl32.dll"); | 31 public: |
42 if (NULL == alu.get()) { | 32 GLProcGetter() : fGLLib("opengl32.dll") {} |
| 33 |
| 34 bool isInitialized() const { return NULL != fGLLib.get(); } |
| 35 |
| 36 GrGLFuncPtr getProc(const char name[]) const { |
| 37 GrGLFuncPtr proc; |
| 38 if (NULL != (proc = (GrGLFuncPtr) GetProcAddress(fGLLib.get(), name))) { |
| 39 return proc; |
| 40 } |
| 41 if (NULL != (proc = (GrGLFuncPtr) wglGetProcAddress(name))) { |
| 42 return proc; |
| 43 } |
43 return NULL; | 44 return NULL; |
44 } | 45 } |
45 | 46 |
46 if (NULL != wglGetCurrentContext()) { | 47 private: |
| 48 AutoLibraryUnload fGLLib; |
| 49 }; |
47 | 50 |
48 // These should always be present and don't require wglGetProcAddress | 51 static GrGLFuncPtr win_get_gl_proc(void* ctx, const char name[]) { |
49 GrGLGetStringProc glGetString = | 52 SkASSERT(NULL != ctx); |
50 (GrGLGetStringProc) GetProcAddress(alu.get(), "glGetString"); | 53 SkASSERT(NULL != wglGetCurrentContext()); |
51 GrGLGetIntegervProc glGetIntegerv = | 54 const GLProcGetter* getter = (const GLProcGetter*) ctx; |
52 (GrGLGetIntegervProc) GetProcAddress(alu.get(), "glGetIntegerv"); | 55 return getter->getProc(name); |
53 if (NULL == glGetString || NULL == glGetIntegerv) { | 56 } |
54 return NULL; | |
55 } | |
56 | 57 |
57 // This may or may not succeed depending on the gl version. | 58 /* |
58 GrGLGetStringiProc glGetStringi = (GrGLGetStringiProc) wglGetProcAddres
s("glGetStringi"); | 59 * Windows makes the GL funcs all be __stdcall instead of __cdecl :( |
59 | 60 * This implementation will only work if GR_GL_FUNCTION_TYPE is __stdcall. |
60 GrGLExtensions extensions; | 61 * Otherwise, a springboard would be needed that hides the calling convention. |
61 if (!extensions.init(kGL_GrGLStandard, glGetString, glGetStringi, glGetI
ntegerv)) { | 62 */ |
62 return NULL; | 63 const GrGLInterface* GrGLCreateNativeInterface() { |
63 } | 64 if (NULL == wglGetCurrentContext()) { |
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(PixelStorei) | |
107 SET_PROC(ReadBuffer) | |
108 SET_PROC(ReadPixels) | |
109 SET_PROC(Scissor) | |
110 SET_PROC(StencilFunc) | |
111 SET_PROC(StencilMask) | |
112 SET_PROC(StencilOp) | |
113 SET_PROC(TexImage2D) | |
114 SET_PROC(TexParameteri) | |
115 SET_PROC(TexParameteriv) | |
116 if (glVer >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage"))
{ | |
117 WGL_SET_PROC(TexStorage2D); | |
118 } else if (extensions.has("GL_EXT_texture_storage")) { | |
119 WGL_SET_PROC_SUFFIX(TexStorage2D, EXT); | |
120 } | |
121 SET_PROC(TexSubImage2D) | |
122 SET_PROC(Viewport) | |
123 | |
124 WGL_SET_PROC(ActiveTexture); | |
125 WGL_SET_PROC(AttachShader); | |
126 WGL_SET_PROC(BeginQuery); | |
127 WGL_SET_PROC(BindAttribLocation); | |
128 WGL_SET_PROC(BindBuffer); | |
129 WGL_SET_PROC(BindFragDataLocation); | |
130 WGL_SET_PROC(BufferData); | |
131 WGL_SET_PROC(BufferSubData); | |
132 WGL_SET_PROC(CompileShader); | |
133 WGL_SET_PROC(CompressedTexImage2D); | |
134 WGL_SET_PROC(CreateProgram); | |
135 WGL_SET_PROC(CreateShader); | |
136 WGL_SET_PROC(DeleteBuffers); | |
137 WGL_SET_PROC(DeleteQueries); | |
138 WGL_SET_PROC(DeleteProgram); | |
139 WGL_SET_PROC(DeleteShader); | |
140 WGL_SET_PROC(DisableVertexAttribArray); | |
141 WGL_SET_PROC(DrawBuffers); | |
142 WGL_SET_PROC(EnableVertexAttribArray); | |
143 WGL_SET_PROC(EndQuery); | |
144 WGL_SET_PROC(GenBuffers); | |
145 WGL_SET_PROC(GenerateMipmap); | |
146 WGL_SET_PROC(GenQueries); | |
147 WGL_SET_PROC(GetBufferParameteriv); | |
148 WGL_SET_PROC(GetQueryiv); | |
149 WGL_SET_PROC(GetQueryObjectiv); | |
150 WGL_SET_PROC(GetQueryObjectuiv); | |
151 if (glVer > GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) { | |
152 WGL_SET_PROC(GetQueryObjecti64v); | |
153 WGL_SET_PROC(GetQueryObjectui64v); | |
154 WGL_SET_PROC(QueryCounter); | |
155 } else if (extensions.has("GL_EXT_timer_query")) { | |
156 WGL_SET_PROC_SUFFIX(GetQueryObjecti64v, EXT); | |
157 WGL_SET_PROC_SUFFIX(GetQueryObjectui64v, EXT); | |
158 } | |
159 WGL_SET_PROC(GetProgramInfoLog); | |
160 WGL_SET_PROC(GetProgramiv); | |
161 WGL_SET_PROC(GetShaderInfoLog); | |
162 WGL_SET_PROC(GetShaderiv); | |
163 WGL_SET_PROC(GetStringi) | |
164 WGL_SET_PROC(GetUniformLocation); | |
165 WGL_SET_PROC(LinkProgram); | |
166 WGL_SET_PROC(ShaderSource); | |
167 WGL_SET_PROC(StencilFuncSeparate); | |
168 WGL_SET_PROC(StencilMaskSeparate); | |
169 WGL_SET_PROC(StencilOpSeparate); | |
170 WGL_SET_PROC(Uniform1f); | |
171 WGL_SET_PROC(Uniform1i); | |
172 WGL_SET_PROC(Uniform1fv); | |
173 WGL_SET_PROC(Uniform1iv); | |
174 WGL_SET_PROC(Uniform2f); | |
175 WGL_SET_PROC(Uniform2i); | |
176 WGL_SET_PROC(Uniform2fv); | |
177 WGL_SET_PROC(Uniform2iv); | |
178 WGL_SET_PROC(Uniform3f); | |
179 WGL_SET_PROC(Uniform3i); | |
180 WGL_SET_PROC(Uniform3fv); | |
181 WGL_SET_PROC(Uniform3iv); | |
182 WGL_SET_PROC(Uniform4f); | |
183 WGL_SET_PROC(Uniform4i); | |
184 WGL_SET_PROC(Uniform4fv); | |
185 WGL_SET_PROC(Uniform4iv); | |
186 WGL_SET_PROC(UniformMatrix2fv); | |
187 WGL_SET_PROC(UniformMatrix3fv); | |
188 WGL_SET_PROC(UniformMatrix4fv); | |
189 WGL_SET_PROC(UseProgram); | |
190 WGL_SET_PROC(VertexAttrib4fv); | |
191 WGL_SET_PROC(VertexAttribPointer); | |
192 WGL_SET_PROC(BindFragDataLocationIndexed); | |
193 | |
194 if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_vertex_array_objec
t")) { | |
195 // no ARB suffix for GL_ARB_vertex_array_object | |
196 WGL_SET_PROC(BindVertexArray); | |
197 WGL_SET_PROC(DeleteVertexArrays); | |
198 WGL_SET_PROC(GenVertexArrays); | |
199 } | |
200 | |
201 // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since | |
202 // GL_ARB_framebuffer_object doesn't use ARB suffix.) | |
203 if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object
")) { | |
204 WGL_SET_PROC(GenFramebuffers); | |
205 WGL_SET_PROC(GetFramebufferAttachmentParameteriv); | |
206 WGL_SET_PROC(GetRenderbufferParameteriv); | |
207 WGL_SET_PROC(BindFramebuffer); | |
208 WGL_SET_PROC(FramebufferTexture2D); | |
209 WGL_SET_PROC(CheckFramebufferStatus); | |
210 WGL_SET_PROC(DeleteFramebuffers); | |
211 WGL_SET_PROC(RenderbufferStorage); | |
212 WGL_SET_PROC(GenRenderbuffers); | |
213 WGL_SET_PROC(DeleteRenderbuffers); | |
214 WGL_SET_PROC(FramebufferRenderbuffer); | |
215 WGL_SET_PROC(BindRenderbuffer); | |
216 WGL_SET_PROC(RenderbufferStorageMultisample); | |
217 WGL_SET_PROC(BlitFramebuffer); | |
218 } else if (extensions.has("GL_EXT_framebuffer_object")) { | |
219 WGL_SET_PROC_SUFFIX(GenFramebuffers, EXT); | |
220 WGL_SET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT); | |
221 WGL_SET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT); | |
222 WGL_SET_PROC_SUFFIX(BindFramebuffer, EXT); | |
223 WGL_SET_PROC_SUFFIX(FramebufferTexture2D, EXT); | |
224 WGL_SET_PROC_SUFFIX(CheckFramebufferStatus, EXT); | |
225 WGL_SET_PROC_SUFFIX(DeleteFramebuffers, EXT); | |
226 WGL_SET_PROC_SUFFIX(RenderbufferStorage, EXT); | |
227 WGL_SET_PROC_SUFFIX(GenRenderbuffers, EXT); | |
228 WGL_SET_PROC_SUFFIX(DeleteRenderbuffers, EXT); | |
229 WGL_SET_PROC_SUFFIX(FramebufferRenderbuffer, EXT); | |
230 WGL_SET_PROC_SUFFIX(BindRenderbuffer, EXT); | |
231 if (extensions.has("GL_EXT_framebuffer_multisample")) { | |
232 WGL_SET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT); | |
233 } | |
234 if (extensions.has("GL_EXT_framebuffer_blit")) { | |
235 WGL_SET_PROC_SUFFIX(BlitFramebuffer, EXT); | |
236 } | |
237 } else { | |
238 // we must have FBOs | |
239 delete interface; | |
240 return NULL; | |
241 } | |
242 | |
243 WGL_SET_PROC(MapBuffer); | |
244 if (extensions.has("GL_EXT_direct_state_access")) { | |
245 WGL_SET_PROC_SUFFIX(MatrixLoadf, EXT); | |
246 WGL_SET_PROC_SUFFIX(MatrixLoadIdentity, EXT); | |
247 } | |
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 if (glVer >= GR_GL_VER(4,3) || extensions.has("GL_ARB_invalidate_subdata
")) { | |
309 WGL_SET_PROC(InvalidateBufferData); | |
310 WGL_SET_PROC(InvalidateBufferSubData); | |
311 WGL_SET_PROC(InvalidateFramebuffer); | |
312 WGL_SET_PROC(InvalidateSubFramebuffer); | |
313 WGL_SET_PROC(InvalidateTexImage); | |
314 WGL_SET_PROC(InvalidateTexSubImage); | |
315 } | |
316 | |
317 interface->fStandard = kGL_GrGLStandard; | |
318 interface->fExtensions.swap(&extensions); | |
319 | |
320 return interface; | |
321 } else { | |
322 return NULL; | 65 return NULL; |
323 } | 66 } |
| 67 |
| 68 GLProcGetter getter; |
| 69 if (!getter.isInitialized()) { |
| 70 return NULL; |
| 71 } |
| 72 |
| 73 return GrGLAssembleGLInterface(&getter, win_get_gl_proc); |
324 } | 74 } |
OLD | NEW |