OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #include "gl/GrGLInterface.h" | 9 #include "gl/GrGLInterface.h" |
10 #include "GrGLUtil.h" | 10 #include "gl/GrGLExtensions.h" |
| 11 #include "gl/GrGLUtil.h" |
11 | 12 |
12 #include <stdio.h> | 13 #include <stdio.h> |
13 | 14 |
14 SK_DEFINE_INST_COUNT(GrGLInterface) | 15 SK_DEFINE_INST_COUNT(GrGLInterface) |
15 | 16 |
16 #if GR_GL_PER_GL_FUNC_CALLBACK | 17 #if GR_GL_PER_GL_FUNC_CALLBACK |
17 namespace { | 18 namespace { |
18 void GrGLDefaultInterfaceCallback(const GrGLInterface*) {} | 19 void GrGLDefaultInterfaceCallback(const GrGLInterface*) {} |
19 } | 20 } |
20 #endif | 21 #endif |
21 | 22 |
22 GrGLInterface::GrGLInterface() { | 23 GrGLInterface::GrGLInterface() { |
23 fBindingsExported = kNone_GrGLBinding; | 24 fBindingsExported = kNone_GrGLBinding; |
24 | 25 |
25 #if GR_GL_PER_GL_FUNC_CALLBACK | 26 #if GR_GL_PER_GL_FUNC_CALLBACK |
26 fCallback = GrGLDefaultInterfaceCallback; | 27 fCallback = GrGLDefaultInterfaceCallback; |
27 fCallbackData = 0; | 28 fCallbackData = 0; |
28 #endif | 29 #endif |
29 } | 30 } |
30 | 31 |
31 bool GrGLInterface::validate(GrGLBinding binding) const { | 32 bool GrGLInterface::validate(GrGLBinding binding) const { |
32 | 33 |
33 // kNone must be 0 so that the check we're about to do can never succeed if | 34 // kNone must be 0 so that the check we're about to do can never succeed if |
34 // binding == kNone. | 35 // binding == kNone. |
35 GR_STATIC_ASSERT(kNone_GrGLBinding == 0); | 36 GR_STATIC_ASSERT(kNone_GrGLBinding == 0); |
36 | 37 |
37 if (0 == (binding & fBindingsExported)) { | 38 if (0 == (binding & fBindingsExported)) { |
38 return false; | 39 return false; |
39 } | 40 } |
| 41 |
| 42 GrGLExtensions extensions; |
| 43 if (!extensions.init(binding, this)) { |
| 44 return false; |
| 45 } |
40 | 46 |
41 // functions that are always required | 47 // functions that are always required |
42 if (NULL == fActiveTexture || | 48 if (NULL == fActiveTexture || |
43 NULL == fAttachShader || | 49 NULL == fAttachShader || |
44 NULL == fBindAttribLocation || | 50 NULL == fBindAttribLocation || |
45 NULL == fBindBuffer || | 51 NULL == fBindBuffer || |
46 NULL == fBindTexture || | 52 NULL == fBindTexture || |
47 NULL == fBlendFunc || | 53 NULL == fBlendFunc || |
48 NULL == fBlendColor || // -> GL >= 1.4, ES >= 2.0 or extension | 54 NULL == fBlendColor || // -> GL >= 1.4, ES >= 2.0 or extension |
49 NULL == fBufferData || | 55 NULL == fBufferData || |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 NULL == fFramebufferRenderbuffer || | 130 NULL == fFramebufferRenderbuffer || |
125 NULL == fFramebufferTexture2D || | 131 NULL == fFramebufferTexture2D || |
126 NULL == fGetFramebufferAttachmentParameteriv || | 132 NULL == fGetFramebufferAttachmentParameteriv || |
127 NULL == fGetRenderbufferParameteriv || | 133 NULL == fGetRenderbufferParameteriv || |
128 NULL == fGenFramebuffers || | 134 NULL == fGenFramebuffers || |
129 NULL == fGenRenderbuffers || | 135 NULL == fGenRenderbuffers || |
130 NULL == fRenderbufferStorage) { | 136 NULL == fRenderbufferStorage) { |
131 return false; | 137 return false; |
132 } | 138 } |
133 | 139 |
134 const char* ext; | |
135 GrGLVersion glVer = GrGLGetVersion(this); | 140 GrGLVersion glVer = GrGLGetVersion(this); |
136 ext = (const char*)fGetString(GR_GL_EXTENSIONS); | |
137 | 141 |
138 // Now check that baseline ES/Desktop fns not covered above are present | 142 // Now check that baseline ES/Desktop fns not covered above are present |
139 // and that we have fn pointers for any advertised extensions that we will | 143 // and that we have fn pointers for any advertised extensions that we will |
140 // try to use. | 144 // try to use. |
141 | 145 |
142 // these functions are part of ES2, we assume they are available | 146 // these functions are part of ES2, we assume they are available |
143 // On the desktop we assume they are available if the extension | 147 // On the desktop we assume they are available if the extension |
144 // is present or GL version is high enough. | 148 // is present or GL version is high enough. |
145 if (kES2_GrGLBinding == binding) { | 149 if (kES2_GrGLBinding == binding) { |
146 if (NULL == fStencilFuncSeparate || | 150 if (NULL == fStencilFuncSeparate || |
147 NULL == fStencilMaskSeparate || | 151 NULL == fStencilMaskSeparate || |
148 NULL == fStencilOpSeparate) { | 152 NULL == fStencilOpSeparate) { |
149 return false; | 153 return false; |
150 } | 154 } |
151 } else if (kDesktop_GrGLBinding == binding) { | 155 } else if (kDesktop_GrGLBinding == binding) { |
152 | 156 |
153 if (glVer >= GR_GL_VER(2,0)) { | 157 if (glVer >= GR_GL_VER(2,0)) { |
154 if (NULL == fStencilFuncSeparate || | 158 if (NULL == fStencilFuncSeparate || |
155 NULL == fStencilMaskSeparate || | 159 NULL == fStencilMaskSeparate || |
156 NULL == fStencilOpSeparate) { | 160 NULL == fStencilOpSeparate) { |
157 return false; | 161 return false; |
158 } | 162 } |
159 } | 163 } |
160 if (glVer >= GR_GL_VER(3,0) && NULL == fBindFragDataLocation) { | 164 if (glVer >= GR_GL_VER(3,0) && NULL == fBindFragDataLocation) { |
161 return false; | 165 return false; |
162 } | 166 } |
163 if (glVer >= GR_GL_VER(2,0) || | 167 if (glVer >= GR_GL_VER(2,0) || extensions.has("GL_ARB_draw_buffers")) { |
164 GrGLHasExtensionFromString("GL_ARB_draw_buffers", ext)) { | |
165 if (NULL == fDrawBuffers) { | 168 if (NULL == fDrawBuffers) { |
166 return false; | 169 return false; |
167 } | 170 } |
168 } | 171 } |
169 | 172 |
170 if (glVer >= GR_GL_VER(1,5) || | 173 if (glVer >= GR_GL_VER(1,5) || extensions.has("GL_ARB_occlusion_query"))
{ |
171 GrGLHasExtensionFromString("GL_ARB_occlusion_query", ext)) { | |
172 if (NULL == fGenQueries || | 174 if (NULL == fGenQueries || |
173 NULL == fDeleteQueries || | 175 NULL == fDeleteQueries || |
174 NULL == fBeginQuery || | 176 NULL == fBeginQuery || |
175 NULL == fEndQuery || | 177 NULL == fEndQuery || |
176 NULL == fGetQueryiv || | 178 NULL == fGetQueryiv || |
177 NULL == fGetQueryObjectiv || | 179 NULL == fGetQueryObjectiv || |
178 NULL == fGetQueryObjectuiv) { | 180 NULL == fGetQueryObjectuiv) { |
179 return false; | 181 return false; |
180 } | 182 } |
181 } | 183 } |
182 if (glVer >= GR_GL_VER(3,3) || | 184 if (glVer >= GR_GL_VER(3,3) || |
183 GrGLHasExtensionFromString("GL_ARB_timer_query", ext) || | 185 extensions.has("GL_ARB_timer_query") || |
184 GrGLHasExtensionFromString("GL_EXT_timer_query", ext)) { | 186 extensions.has("GL_EXT_timer_query")) { |
185 if (NULL == fGetQueryObjecti64v || | 187 if (NULL == fGetQueryObjecti64v || |
186 NULL == fGetQueryObjectui64v) { | 188 NULL == fGetQueryObjectui64v) { |
187 return false; | 189 return false; |
188 } | 190 } |
189 } | 191 } |
190 if (glVer >= GR_GL_VER(3,3) || | 192 if (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) { |
191 GrGLHasExtensionFromString("GL_ARB_timer_query", ext)) { | |
192 if (NULL == fQueryCounter) { | 193 if (NULL == fQueryCounter) { |
193 return false; | 194 return false; |
194 } | 195 } |
195 } | 196 } |
196 // The below two blocks are checks for functions used with | 197 // The below two blocks are checks for functions used with |
197 // GL_NV_path_rendering. We're not enforcing that they be non-NULL | 198 // GL_NV_path_rendering. We're not enforcing that they be non-NULL |
198 // because they aren't actually called at this time. | 199 // because they aren't actually called at this time. |
199 if (false && | 200 if (false && |
200 (NULL == fMatrixMode || | 201 (NULL == fMatrixMode || |
201 NULL == fLoadIdentity || | 202 NULL == fLoadIdentity || |
202 NULL == fLoadMatrixf)) { | 203 NULL == fLoadMatrixf)) { |
203 return false; | 204 return false; |
204 } | 205 } |
205 if (false && GrGLHasExtensionFromString("GL_NV_path_rendering", ext)) { | 206 if (false && extensions.has("GL_NV_path_rendering")) { |
206 if (NULL == fPathCommands || | 207 if (NULL == fPathCommands || |
207 NULL == fPathCoords || | 208 NULL == fPathCoords || |
208 NULL == fPathSubCommands || | 209 NULL == fPathSubCommands || |
209 NULL == fPathSubCoords || | 210 NULL == fPathSubCoords || |
210 NULL == fPathString || | 211 NULL == fPathString || |
211 NULL == fPathGlyphs || | 212 NULL == fPathGlyphs || |
212 NULL == fPathGlyphRange || | 213 NULL == fPathGlyphRange || |
213 NULL == fWeightPaths || | 214 NULL == fWeightPaths || |
214 NULL == fCopyPath || | 215 NULL == fCopyPath || |
215 NULL == fInterpolatePaths || | 216 NULL == fInterpolatePaths || |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 NULL == fIsPointInStrokePath || | 253 NULL == fIsPointInStrokePath || |
253 NULL == fGetPathLength || | 254 NULL == fGetPathLength || |
254 NULL == fPointAlongPath) { | 255 NULL == fPointAlongPath) { |
255 return false; | 256 return false; |
256 } | 257 } |
257 } | 258 } |
258 } | 259 } |
259 | 260 |
260 // optional function on desktop before 1.3 | 261 // optional function on desktop before 1.3 |
261 if (kDesktop_GrGLBinding != binding || | 262 if (kDesktop_GrGLBinding != binding || |
262 (glVer >= GR_GL_VER(1,3) || | 263 (glVer >= GR_GL_VER(1,3)) || |
263 GrGLHasExtensionFromString("GL_ARB_texture_compression", ext))) { | 264 extensions.has("GL_ARB_texture_compression")) { |
264 if (NULL == fCompressedTexImage2D) { | 265 if (NULL == fCompressedTexImage2D) { |
265 return false; | 266 return false; |
266 } | 267 } |
267 } | 268 } |
268 | 269 |
269 // part of desktop GL, but not ES | 270 // part of desktop GL, but not ES |
270 if (kDesktop_GrGLBinding == binding && | 271 if (kDesktop_GrGLBinding == binding && |
271 (NULL == fLineWidth || | 272 (NULL == fLineWidth || |
272 NULL == fGetTexLevelParameteriv || | 273 NULL == fGetTexLevelParameteriv || |
273 NULL == fDrawBuffer || | 274 NULL == fDrawBuffer || |
274 NULL == fReadBuffer)) { | 275 NULL == fReadBuffer)) { |
275 return false; | 276 return false; |
276 } | 277 } |
277 | 278 |
278 // GL_EXT_texture_storage is part of desktop 4.2 | 279 // GL_EXT_texture_storage is part of desktop 4.2 |
279 // There is a desktop ARB extension and an ES+desktop EXT extension | 280 // There is a desktop ARB extension and an ES+desktop EXT extension |
280 if (kDesktop_GrGLBinding == binding) { | 281 if (kDesktop_GrGLBinding == binding) { |
281 if (glVer >= GR_GL_VER(4,2) || | 282 if (glVer >= GR_GL_VER(4,2) || |
282 GrGLHasExtensionFromString("GL_ARB_texture_storage", ext) || | 283 extensions.has("GL_ARB_texture_storage") || |
283 GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) { | 284 extensions.has("GL_EXT_texture_storage")) { |
284 if (NULL == fTexStorage2D) { | 285 if (NULL == fTexStorage2D) { |
285 return false; | 286 return false; |
286 } | 287 } |
287 } | 288 } |
288 } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) { | 289 } else if (extensions.has("GL_EXT_texture_storage")) { |
289 if (NULL == fTexStorage2D) { | 290 if (NULL == fTexStorage2D) { |
290 return false; | 291 return false; |
291 } | 292 } |
292 } | 293 } |
293 | 294 |
294 // FBO MSAA | 295 // FBO MSAA |
295 if (kDesktop_GrGLBinding == binding) { | 296 if (kDesktop_GrGLBinding == binding) { |
296 // GL 3.0 and the ARB extension have multisample + blit | 297 // GL 3.0 and the ARB extension have multisample + blit |
297 if (glVer >= GR_GL_VER(3,0) || GrGLHasExtensionFromString("GL_ARB_frameb
uffer_object", ext)) { | 298 if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object
")) { |
298 if (NULL == fRenderbufferStorageMultisample || | 299 if (NULL == fRenderbufferStorageMultisample || |
299 NULL == fBlitFramebuffer) { | 300 NULL == fBlitFramebuffer) { |
300 return false; | 301 return false; |
301 } | 302 } |
302 } else { | 303 } else { |
303 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", ext) && | 304 if (extensions.has("GL_EXT_framebuffer_blit") && |
304 NULL == fBlitFramebuffer) { | 305 NULL == fBlitFramebuffer) { |
305 return false; | 306 return false; |
306 } | 307 } |
307 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", ext
) && | 308 if (extensions.has("GL_EXT_framebuffer_multisample") && |
308 NULL == fRenderbufferStorageMultisample) { | 309 NULL == fRenderbufferStorageMultisample) { |
309 return false; | 310 return false; |
310 } | 311 } |
311 } | 312 } |
312 } else { | 313 } else { |
313 if (GrGLHasExtensionFromString("GL_CHROMIUM_framebuffer_multisample", ex
t)) { | 314 if (extensions.has("GL_CHROMIUM_framebuffer_multisample")) { |
314 if (NULL == fRenderbufferStorageMultisample || | 315 if (NULL == fRenderbufferStorageMultisample || |
315 NULL == fBlitFramebuffer) { | 316 NULL == fBlitFramebuffer) { |
316 return false; | 317 return false; |
317 } | 318 } |
318 } | 319 } |
319 if (GrGLHasExtensionFromString("GL_APPLE_framebuffer_multisample", ext))
{ | 320 if (extensions.has("GL_APPLE_framebuffer_multisample")) { |
320 if (NULL == fRenderbufferStorageMultisample || | 321 if (NULL == fRenderbufferStorageMultisample || |
321 NULL == fResolveMultisampleFramebuffer) { | 322 NULL == fResolveMultisampleFramebuffer) { |
322 return false; | 323 return false; |
323 } | 324 } |
324 } | 325 } |
325 } | 326 } |
326 | 327 |
327 // On ES buffer mapping is an extension. On Desktop | 328 // On ES buffer mapping is an extension. On Desktop |
328 // buffer mapping was part of original VBO extension | 329 // buffer mapping was part of original VBO extension |
329 // which we require. | 330 // which we require. |
330 if (kDesktop_GrGLBinding == binding || | 331 if (kDesktop_GrGLBinding == binding || extensions.has("GL_OES_mapbuffer")) { |
331 GrGLHasExtensionFromString("GL_OES_mapbuffer", ext)) { | |
332 if (NULL == fMapBuffer || | 332 if (NULL == fMapBuffer || |
333 NULL == fUnmapBuffer) { | 333 NULL == fUnmapBuffer) { |
334 return false; | 334 return false; |
335 } | 335 } |
336 } | 336 } |
337 | 337 |
338 // Dual source blending | 338 // Dual source blending |
339 if (kDesktop_GrGLBinding == binding && | 339 if (kDesktop_GrGLBinding == binding && |
340 (glVer >= GR_GL_VER(3,3) || | 340 (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_blend_func_extended")
)) { |
341 GrGLHasExtensionFromString("GL_ARB_blend_func_extended", ext))) { | |
342 if (NULL == fBindFragDataLocationIndexed) { | 341 if (NULL == fBindFragDataLocationIndexed) { |
343 return false; | 342 return false; |
344 } | 343 } |
345 } | 344 } |
| 345 |
| 346 if (kDesktop_GrGLBinding == binding && glVer >= GR_GL_VER(3, 0)) { |
| 347 if (NULL == fGetStringi) { |
| 348 return false; |
| 349 } |
| 350 } |
346 | 351 |
347 return true; | 352 return true; |
348 } | 353 } |
OLD | NEW |