OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gl/gl_gl_api_implementation.h" | 5 #include "ui/gl/gl_gl_api_implementation.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/memory/ptr_util.h" |
10 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
11 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
12 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
13 #include "ui/gl/gl_context.h" | 14 #include "ui/gl/gl_context.h" |
14 #include "ui/gl/gl_implementation.h" | 15 #include "ui/gl/gl_implementation.h" |
15 #include "ui/gl/gl_state_restorer.h" | 16 #include "ui/gl/gl_state_restorer.h" |
16 #include "ui/gl/gl_surface.h" | 17 #include "ui/gl/gl_surface.h" |
17 #include "ui/gl/gl_switches.h" | 18 #include "ui/gl/gl_switches.h" |
18 #include "ui/gl/gl_version_info.h" | 19 #include "ui/gl/gl_version_info.h" |
19 | 20 |
20 namespace gl { | 21 namespace gl { |
21 | 22 |
22 // The GL Api being used. This could be g_real_gl or gl_trace_gl | 23 // The GL state for when no context is bound |
23 static GLApi* g_gl = NULL; | 24 static CurrentGL* g_no_context_current_gl = nullptr; |
24 // A GL Api that calls directly into the driver. | 25 |
25 static RealGLApi* g_real_gl = NULL; | 26 // If the null draw bindings are currently enabled. |
26 // A GL Api that does nothing but warn about illegal GL calls without a context | 27 // TODO: Consider adding a new GLApi that no-ops these functions |
27 // current. | 28 static bool g_null_draw_bindings_enabled = false; |
28 static NoContextGLApi* g_no_context_gl = NULL; | 29 |
29 // A GL Api that calls TRACE and then calls another GL api. | 30 // If the GL debug bindings are enabled. |
30 static TraceGLApi* g_trace_gl = NULL; | 31 static bool g_debug_bindings_enabled = false; |
31 // The GL Api being used for stub contexts. If null, g_gl is used instead. | |
32 static GLApi* g_stub_gl = NULL; | |
33 // GL version used when initializing dynamic bindings. | |
34 static GLVersionInfo* g_version_info = NULL; | |
35 | 32 |
36 namespace { | 33 namespace { |
37 | 34 |
38 static inline GLenum GetInternalFormat(GLenum internal_format) { | 35 static inline GLenum GetInternalFormat(const GLVersionInfo* version, |
39 if (!g_version_info->is_es) { | 36 GLenum internal_format) { |
| 37 if (!version->is_es) { |
40 if (internal_format == GL_BGRA_EXT || internal_format == GL_BGRA8_EXT) | 38 if (internal_format == GL_BGRA_EXT || internal_format == GL_BGRA8_EXT) |
41 return GL_RGBA8; | 39 return GL_RGBA8; |
42 } | 40 } |
43 if (g_version_info->is_es3 && g_version_info->is_mesa) { | 41 if (version->is_es3 && version->is_mesa) { |
44 // Mesa bug workaround: Mipmapping does not work when using GL_BGRA_EXT | 42 // Mesa bug workaround: Mipmapping does not work when using GL_BGRA_EXT |
45 if (internal_format == GL_BGRA_EXT) | 43 if (internal_format == GL_BGRA_EXT) |
46 return GL_RGBA; | 44 return GL_RGBA; |
47 } | 45 } |
48 return internal_format; | 46 return internal_format; |
49 } | 47 } |
50 | 48 |
51 // TODO(epenner): Could the above function be merged into this and removed? | 49 // TODO(epenner): Could the above function be merged into this and removed? |
52 static inline GLenum GetTexInternalFormat(GLenum internal_format, | 50 static inline GLenum GetTexInternalFormat(const GLVersionInfo* version, |
| 51 GLenum internal_format, |
53 GLenum format, | 52 GLenum format, |
54 GLenum type) { | 53 GLenum type) { |
55 DCHECK(g_version_info); | 54 GLenum gl_internal_format = GetInternalFormat(version, internal_format); |
56 GLenum gl_internal_format = GetInternalFormat(internal_format); | |
57 | 55 |
58 // g_version_info must be initialized when this function is bound. | 56 // g_version_info must be initialized when this function is bound. |
59 if (g_version_info->is_es3) { | 57 if (version->is_es3) { |
60 if (internal_format == GL_RED_EXT) { | 58 if (internal_format == GL_RED_EXT) { |
61 // GL_EXT_texture_rg case in ES2. | 59 // GL_EXT_texture_rg case in ES2. |
62 switch (type) { | 60 switch (type) { |
63 case GL_UNSIGNED_BYTE: | 61 case GL_UNSIGNED_BYTE: |
64 gl_internal_format = GL_R8_EXT; | 62 gl_internal_format = GL_R8_EXT; |
65 break; | 63 break; |
66 case GL_HALF_FLOAT_OES: | 64 case GL_HALF_FLOAT_OES: |
67 gl_internal_format = GL_R16F_EXT; | 65 gl_internal_format = GL_R16F_EXT; |
68 break; | 66 break; |
69 case GL_FLOAT: | 67 case GL_FLOAT: |
(...skipping 17 matching lines...) Expand all Loading... |
87 gl_internal_format = GL_RG32F_EXT; | 85 gl_internal_format = GL_RG32F_EXT; |
88 break; | 86 break; |
89 default: | 87 default: |
90 NOTREACHED(); | 88 NOTREACHED(); |
91 break; | 89 break; |
92 } | 90 } |
93 return gl_internal_format; | 91 return gl_internal_format; |
94 } | 92 } |
95 } | 93 } |
96 | 94 |
97 if (type == GL_FLOAT && g_version_info->is_angle && g_version_info->is_es && | 95 if (type == GL_FLOAT && version->is_angle && version->is_es && |
98 g_version_info->major_version == 2) { | 96 version->major_version == 2) { |
99 // It's possible that the texture is using a sized internal format, and | 97 // It's possible that the texture is using a sized internal format, and |
100 // ANGLE exposing GLES2 API doesn't support those. | 98 // ANGLE exposing GLES2 API doesn't support those. |
101 // TODO(oetuaho@nvidia.com): Remove these conversions once ANGLE has the | 99 // TODO(oetuaho@nvidia.com): Remove these conversions once ANGLE has the |
102 // support. | 100 // support. |
103 // http://code.google.com/p/angleproject/issues/detail?id=556 | 101 // http://code.google.com/p/angleproject/issues/detail?id=556 |
104 switch (format) { | 102 switch (format) { |
105 case GL_RGBA: | 103 case GL_RGBA: |
106 gl_internal_format = GL_RGBA; | 104 gl_internal_format = GL_RGBA; |
107 break; | 105 break; |
108 case GL_RGB: | 106 case GL_RGB: |
109 gl_internal_format = GL_RGB; | 107 gl_internal_format = GL_RGB; |
110 break; | 108 break; |
111 default: | 109 default: |
112 break; | 110 break; |
113 } | 111 } |
114 } | 112 } |
115 | 113 |
116 if (g_version_info->IsAtLeastGL(2, 1) || | 114 if (version->IsAtLeastGL(2, 1) || version->IsAtLeastGLES(3, 0)) { |
117 g_version_info->IsAtLeastGLES(3, 0)) { | |
118 switch (internal_format) { | 115 switch (internal_format) { |
119 case GL_SRGB_EXT: | 116 case GL_SRGB_EXT: |
120 gl_internal_format = GL_SRGB8; | 117 gl_internal_format = GL_SRGB8; |
121 break; | 118 break; |
122 case GL_SRGB_ALPHA_EXT: | 119 case GL_SRGB_ALPHA_EXT: |
123 gl_internal_format = GL_SRGB8_ALPHA8; | 120 gl_internal_format = GL_SRGB8_ALPHA8; |
124 break; | 121 break; |
125 default: | 122 default: |
126 break; | 123 break; |
127 } | 124 } |
128 } | 125 } |
129 | 126 |
130 if (g_version_info->is_es) | 127 if (version->is_es) |
131 return gl_internal_format; | 128 return gl_internal_format; |
132 | 129 |
133 if (type == GL_FLOAT) { | 130 if (type == GL_FLOAT) { |
134 switch (internal_format) { | 131 switch (internal_format) { |
135 // We need to map all the unsized internal formats from ES2 clients. | 132 // We need to map all the unsized internal formats from ES2 clients. |
136 case GL_RGBA: | 133 case GL_RGBA: |
137 gl_internal_format = GL_RGBA32F_ARB; | 134 gl_internal_format = GL_RGBA32F_ARB; |
138 break; | 135 break; |
139 case GL_RGB: | 136 case GL_RGB: |
140 gl_internal_format = GL_RGB32F_ARB; | 137 gl_internal_format = GL_RGB32F_ARB; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 break; | 185 break; |
189 default: | 186 default: |
190 NOTREACHED(); | 187 NOTREACHED(); |
191 break; | 188 break; |
192 } | 189 } |
193 } | 190 } |
194 | 191 |
195 return gl_internal_format; | 192 return gl_internal_format; |
196 } | 193 } |
197 | 194 |
198 static inline GLenum GetTexFormat(GLenum format) { | 195 static inline GLenum GetTexFormat(const GLVersionInfo* version, GLenum format) { |
199 GLenum gl_format = format; | 196 GLenum gl_format = format; |
200 | 197 |
201 DCHECK(g_version_info); | 198 if (version->IsAtLeastGL(2, 1) || version->IsAtLeastGLES(3, 0)) { |
202 if (g_version_info->IsAtLeastGL(2, 1) || | |
203 g_version_info->IsAtLeastGLES(3, 0)) { | |
204 switch (format) { | 199 switch (format) { |
205 case GL_SRGB_EXT: | 200 case GL_SRGB_EXT: |
206 gl_format = GL_RGB; | 201 gl_format = GL_RGB; |
207 break; | 202 break; |
208 case GL_SRGB_ALPHA_EXT: | 203 case GL_SRGB_ALPHA_EXT: |
209 gl_format = GL_RGBA; | 204 gl_format = GL_RGBA; |
210 break; | 205 break; |
211 default: | 206 default: |
212 break; | 207 break; |
213 } | 208 } |
214 } | 209 } |
215 | 210 |
216 return gl_format; | 211 return gl_format; |
217 } | 212 } |
218 | 213 |
219 static inline GLenum GetTexType(GLenum type) { | 214 static inline GLenum GetTexType(const GLVersionInfo* version, GLenum type) { |
220 if (!g_version_info->is_es) { | 215 if (!version->is_es) { |
221 if (type == GL_HALF_FLOAT_OES) | 216 if (type == GL_HALF_FLOAT_OES) |
222 return GL_HALF_FLOAT_ARB; | 217 return GL_HALF_FLOAT_ARB; |
223 } | 218 } |
224 return type; | 219 return type; |
225 } | 220 } |
226 | 221 |
227 static void GL_BINDING_CALL CustomTexImage2D( | 222 } // anonymous namespace |
228 GLenum target, GLint level, GLint internalformat, | 223 |
229 GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, | 224 void InitializeStaticGLBindingsGL() { |
230 const void* pixels) { | 225 g_current_gl_context_tls = new base::ThreadLocalPointer<CurrentGL>; |
231 GLenum gl_internal_format = GetTexInternalFormat( | 226 g_no_context_current_gl = new CurrentGL; |
232 internalformat, format, type); | 227 g_no_context_current_gl->Api = new NoContextGLApi; |
233 GLenum gl_format = GetTexFormat(format); | |
234 GLenum gl_type = GetTexType(type); | |
235 g_driver_gl.orig_fn.glTexImage2DFn( | |
236 target, level, gl_internal_format, width, height, border, gl_format, | |
237 gl_type, pixels); | |
238 } | 228 } |
239 | 229 |
240 static void GL_BINDING_CALL CustomTexSubImage2D( | 230 void ClearBindingsGL() { |
241 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 231 if (g_no_context_current_gl) { |
242 GLsizei height, GLenum format, GLenum type, const void* pixels) { | 232 delete g_no_context_current_gl->Api; |
243 GLenum gl_format = GetTexFormat(format); | 233 delete g_no_context_current_gl->Driver; |
244 GLenum gl_type = GetTexType(type); | 234 delete g_no_context_current_gl->Version; |
245 g_driver_gl.orig_fn.glTexSubImage2DFn( | 235 delete g_no_context_current_gl; |
246 target, level, xoffset, yoffset, width, height, gl_format, gl_type, | 236 g_no_context_current_gl = nullptr; |
247 pixels); | 237 } |
248 } | |
249 | 238 |
250 static void GL_BINDING_CALL CustomTexStorage2DEXT( | 239 if (g_current_gl_context_tls) { |
251 GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, | 240 delete g_current_gl_context_tls; |
252 GLsizei height) { | 241 g_current_gl_context_tls = nullptr; |
253 GLenum gl_internal_format = GetInternalFormat(internalformat); | |
254 g_driver_gl.orig_fn.glTexStorage2DEXTFn( | |
255 target, levels, gl_internal_format, width, height); | |
256 } | |
257 | |
258 static void GL_BINDING_CALL CustomRenderbufferStorageEXT( | |
259 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { | |
260 GLenum gl_internal_format = GetInternalFormat(internalformat); | |
261 g_driver_gl.orig_fn.glRenderbufferStorageEXTFn( | |
262 target, gl_internal_format, width, height); | |
263 } | |
264 | |
265 // The ANGLE and IMG variants of glRenderbufferStorageMultisample currently do | |
266 // not support BGRA render buffers so only the EXT one is customized. If | |
267 // GL_CHROMIUM_renderbuffer_format_BGRA8888 support is added to ANGLE then the | |
268 // ANGLE version should also be customized. | |
269 static void GL_BINDING_CALL CustomRenderbufferStorageMultisampleEXT( | |
270 GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, | |
271 GLsizei height) { | |
272 GLenum gl_internal_format = GetInternalFormat(internalformat); | |
273 g_driver_gl.orig_fn.glRenderbufferStorageMultisampleEXTFn( | |
274 target, samples, gl_internal_format, width, height); | |
275 } | |
276 | |
277 static void GL_BINDING_CALL | |
278 CustomRenderbufferStorageMultisample(GLenum target, | |
279 GLsizei samples, | |
280 GLenum internalformat, | |
281 GLsizei width, | |
282 GLsizei height) { | |
283 GLenum gl_internal_format = GetInternalFormat(internalformat); | |
284 g_driver_gl.orig_fn.glRenderbufferStorageMultisampleFn( | |
285 target, samples, gl_internal_format, width, height); | |
286 } | |
287 | |
288 } // anonymous namespace | |
289 | |
290 void DriverGL::InitializeCustomDynamicBindings(GLContext* context) { | |
291 InitializeDynamicBindings(context); | |
292 | |
293 DCHECK(orig_fn.glTexImage2DFn == NULL); | |
294 orig_fn.glTexImage2DFn = fn.glTexImage2DFn; | |
295 fn.glTexImage2DFn = | |
296 reinterpret_cast<glTexImage2DProc>(CustomTexImage2D); | |
297 | |
298 DCHECK(orig_fn.glTexSubImage2DFn == NULL); | |
299 orig_fn.glTexSubImage2DFn = fn.glTexSubImage2DFn; | |
300 fn.glTexSubImage2DFn = | |
301 reinterpret_cast<glTexSubImage2DProc>(CustomTexSubImage2D); | |
302 | |
303 DCHECK(orig_fn.glTexStorage2DEXTFn == NULL); | |
304 orig_fn.glTexStorage2DEXTFn = fn.glTexStorage2DEXTFn; | |
305 fn.glTexStorage2DEXTFn = | |
306 reinterpret_cast<glTexStorage2DEXTProc>(CustomTexStorage2DEXT); | |
307 | |
308 DCHECK(orig_fn.glRenderbufferStorageEXTFn == NULL); | |
309 orig_fn.glRenderbufferStorageEXTFn = fn.glRenderbufferStorageEXTFn; | |
310 fn.glRenderbufferStorageEXTFn = | |
311 reinterpret_cast<glRenderbufferStorageEXTProc>( | |
312 CustomRenderbufferStorageEXT); | |
313 | |
314 DCHECK(orig_fn.glRenderbufferStorageMultisampleEXTFn == NULL); | |
315 orig_fn.glRenderbufferStorageMultisampleEXTFn = | |
316 fn.glRenderbufferStorageMultisampleEXTFn; | |
317 fn.glRenderbufferStorageMultisampleEXTFn = | |
318 reinterpret_cast<glRenderbufferStorageMultisampleEXTProc>( | |
319 CustomRenderbufferStorageMultisampleEXT); | |
320 | |
321 DCHECK(orig_fn.glRenderbufferStorageMultisampleFn == NULL); | |
322 orig_fn.glRenderbufferStorageMultisampleFn = | |
323 fn.glRenderbufferStorageMultisampleFn; | |
324 fn.glRenderbufferStorageMultisampleFn = | |
325 reinterpret_cast<glRenderbufferStorageMultisampleProc>( | |
326 CustomRenderbufferStorageMultisample); | |
327 } | |
328 | |
329 static void GL_BINDING_CALL NullDrawClearFn(GLbitfield mask) { | |
330 if (!g_driver_gl.null_draw_bindings_enabled) | |
331 g_driver_gl.orig_fn.glClearFn(mask); | |
332 } | |
333 | |
334 static void GL_BINDING_CALL | |
335 NullDrawDrawArraysFn(GLenum mode, GLint first, GLsizei count) { | |
336 if (!g_driver_gl.null_draw_bindings_enabled) | |
337 g_driver_gl.orig_fn.glDrawArraysFn(mode, first, count); | |
338 } | |
339 | |
340 static void GL_BINDING_CALL NullDrawDrawElementsFn(GLenum mode, | |
341 GLsizei count, | |
342 GLenum type, | |
343 const void* indices) { | |
344 if (!g_driver_gl.null_draw_bindings_enabled) | |
345 g_driver_gl.orig_fn.glDrawElementsFn(mode, count, type, indices); | |
346 } | |
347 | |
348 void DriverGL::InitializeNullDrawBindings() { | |
349 DCHECK(orig_fn.glClearFn == NULL); | |
350 orig_fn.glClearFn = fn.glClearFn; | |
351 fn.glClearFn = NullDrawClearFn; | |
352 | |
353 DCHECK(orig_fn.glDrawArraysFn == NULL); | |
354 orig_fn.glDrawArraysFn = fn.glDrawArraysFn; | |
355 fn.glDrawArraysFn = NullDrawDrawArraysFn; | |
356 | |
357 DCHECK(orig_fn.glDrawElementsFn == NULL); | |
358 orig_fn.glDrawElementsFn = fn.glDrawElementsFn; | |
359 fn.glDrawElementsFn = NullDrawDrawElementsFn; | |
360 | |
361 null_draw_bindings_enabled = true; | |
362 } | |
363 | |
364 bool DriverGL::HasInitializedNullDrawBindings() { | |
365 return orig_fn.glClearFn != NULL && orig_fn.glDrawArraysFn != NULL && | |
366 orig_fn.glDrawElementsFn != NULL; | |
367 } | |
368 | |
369 bool DriverGL::SetNullDrawBindingsEnabled(bool enabled) { | |
370 DCHECK(orig_fn.glClearFn != NULL); | |
371 DCHECK(orig_fn.glDrawArraysFn != NULL); | |
372 DCHECK(orig_fn.glDrawElementsFn != NULL); | |
373 | |
374 bool before = null_draw_bindings_enabled; | |
375 null_draw_bindings_enabled = enabled; | |
376 return before; | |
377 } | |
378 | |
379 void InitializeStaticGLBindingsGL() { | |
380 g_current_gl_context_tls = new base::ThreadLocalPointer<GLApi>; | |
381 g_driver_gl.InitializeStaticBindings(); | |
382 if (!g_real_gl) { | |
383 g_real_gl = new RealGLApi(); | |
384 g_trace_gl = new TraceGLApi(g_real_gl); | |
385 g_no_context_gl = new NoContextGLApi(); | |
386 } | 242 } |
387 g_real_gl->Initialize(&g_driver_gl); | |
388 g_gl = g_real_gl; | |
389 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
390 switches::kEnableGPUServiceTracing)) { | |
391 g_gl = g_trace_gl; | |
392 } | |
393 SetGLToRealGLApi(); | |
394 } | |
395 | |
396 GLApi* GetCurrentGLApi() { | |
397 return g_current_gl_context_tls ? g_current_gl_context_tls->Get() : nullptr; | |
398 } | |
399 | |
400 void SetGLApi(GLApi* api) { | |
401 g_current_gl_context_tls->Set(api); | |
402 } | |
403 | |
404 void SetGLToRealGLApi() { | |
405 SetGLApi(g_gl); | |
406 } | |
407 | |
408 void SetGLToStubGLApi() { | |
409 SetGLApi(g_stub_gl ? g_stub_gl : g_gl); | |
410 } | |
411 | |
412 void SetGLApiToNoContext() { | |
413 SetGLApi(g_no_context_gl); | |
414 } | |
415 | |
416 void SetStubGLApi(GLApi* api) { | |
417 g_stub_gl = api; | |
418 } | |
419 | |
420 const GLVersionInfo* GetGLVersionInfo() { | |
421 return g_version_info; | |
422 } | |
423 | |
424 void InitializeDynamicGLBindingsGL(GLContext* context) { | |
425 if (g_version_info) | |
426 return; | |
427 g_real_gl->InitializeFilteredExtensions(); | |
428 g_driver_gl.InitializeCustomDynamicBindings(context); | |
429 DCHECK(context && context->IsCurrent(NULL) && !g_version_info); | |
430 g_version_info = new GLVersionInfo( | |
431 context->GetGLVersion().c_str(), | |
432 context->GetGLRenderer().c_str(), | |
433 context->GetExtensions().c_str()); | |
434 } | 243 } |
435 | 244 |
436 void InitializeDebugGLBindingsGL() { | 245 void InitializeDebugGLBindingsGL() { |
437 g_driver_gl.InitializeDebugBindings(); | 246 g_debug_bindings_enabled = true; |
438 } | 247 } |
439 | 248 |
440 void InitializeNullDrawGLBindingsGL() { | 249 bool GetDebugGLBindingsInitializedGL() { |
441 g_driver_gl.InitializeNullDrawBindings(); | 250 return g_debug_bindings_enabled; |
442 } | 251 } |
443 | 252 |
444 bool HasInitializedNullDrawGLBindingsGL() { | 253 bool SetNullDrawGLBindingsEnabled(bool enabled) { |
445 return g_driver_gl.HasInitializedNullDrawBindings(); | 254 bool old_value = g_null_draw_bindings_enabled; |
| 255 g_null_draw_bindings_enabled = enabled; |
| 256 return old_value; |
446 } | 257 } |
447 | 258 |
448 bool SetNullDrawGLBindingsEnabledGL(bool enabled) { | 259 bool GetNullDrawBindingsEnabled() { |
449 return g_driver_gl.SetNullDrawBindingsEnabled(enabled); | 260 return g_null_draw_bindings_enabled; |
450 } | 261 } |
451 | 262 |
452 void ClearBindingsGL() { | 263 void SetCurrentGL(CurrentGL* current) { |
453 if (g_real_gl) { | 264 CurrentGL* new_current = current ? current : g_no_context_current_gl; |
454 delete g_real_gl; | 265 g_current_gl_context_tls->Set(new_current); |
455 g_real_gl = NULL; | |
456 } | |
457 if (g_trace_gl) { | |
458 delete g_trace_gl; | |
459 g_trace_gl = NULL; | |
460 } | |
461 if (g_no_context_gl) { | |
462 delete g_no_context_gl; | |
463 g_no_context_gl = NULL; | |
464 } | |
465 g_gl = NULL; | |
466 g_stub_gl = NULL; | |
467 g_driver_gl.ClearBindings(); | |
468 if (g_current_gl_context_tls) { | |
469 delete g_current_gl_context_tls; | |
470 g_current_gl_context_tls = NULL; | |
471 } | |
472 if (g_version_info) { | |
473 delete g_version_info; | |
474 g_version_info = NULL; | |
475 } | |
476 } | 266 } |
477 | 267 |
478 GLApi::GLApi() { | 268 GLApi::GLApi() { |
479 } | 269 } |
480 | 270 |
481 GLApi::~GLApi() { | 271 GLApi::~GLApi() { |
482 if (GetCurrentGLApi() == this) | |
483 SetGLApi(NULL); | |
484 } | 272 } |
485 | 273 |
486 GLApiBase::GLApiBase() | 274 GLApiBase::GLApiBase() |
487 : driver_(NULL) { | 275 : driver_(NULL) { |
488 } | 276 } |
489 | 277 |
490 GLApiBase::~GLApiBase() { | 278 GLApiBase::~GLApiBase() { |
491 } | 279 } |
492 | 280 |
493 void GLApiBase::InitializeBase(DriverGL* driver) { | 281 void GLApiBase::InitializeBase(DriverGL* driver) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
548 DCHECK(filtered_exts_initialized_); | 336 DCHECK(filtered_exts_initialized_); |
549 #endif | 337 #endif |
550 if (index >= filtered_exts_.size()) { | 338 if (index >= filtered_exts_.size()) { |
551 return NULL; | 339 return NULL; |
552 } | 340 } |
553 return reinterpret_cast<const GLubyte*>(filtered_exts_[index].c_str()); | 341 return reinterpret_cast<const GLubyte*>(filtered_exts_[index].c_str()); |
554 } | 342 } |
555 return GLApiBase::glGetStringiFn(name, index); | 343 return GLApiBase::glGetStringiFn(name, index); |
556 } | 344 } |
557 | 345 |
| 346 void RealGLApi::glTexImage2DFn(GLenum target, |
| 347 GLint level, |
| 348 GLint internalformat, |
| 349 GLsizei width, |
| 350 GLsizei height, |
| 351 GLint border, |
| 352 GLenum format, |
| 353 GLenum type, |
| 354 const void* pixels) { |
| 355 GLenum gl_internal_format = |
| 356 GetTexInternalFormat(version_.get(), internalformat, format, type); |
| 357 GLenum gl_format = GetTexFormat(version_.get(), format); |
| 358 GLenum gl_type = GetTexType(version_.get(), type); |
| 359 GLApiBase::glTexImage2DFn(target, level, gl_internal_format, width, height, |
| 360 border, gl_format, gl_type, pixels); |
| 361 } |
| 362 |
| 363 void RealGLApi::glTexSubImage2DFn(GLenum target, |
| 364 GLint level, |
| 365 GLint xoffset, |
| 366 GLint yoffset, |
| 367 GLsizei width, |
| 368 GLsizei height, |
| 369 GLenum format, |
| 370 GLenum type, |
| 371 const void* pixels) { |
| 372 GLenum gl_format = GetTexFormat(version_.get(), format); |
| 373 GLenum gl_type = GetTexType(version_.get(), type); |
| 374 GLApiBase::glTexSubImage2DFn(target, level, xoffset, yoffset, width, height, |
| 375 gl_format, gl_type, pixels); |
| 376 } |
| 377 |
| 378 void RealGLApi::glTexStorage2DEXTFn(GLenum target, |
| 379 GLsizei levels, |
| 380 GLenum internalformat, |
| 381 GLsizei width, |
| 382 GLsizei height) { |
| 383 GLenum gl_internal_format = GetInternalFormat(version_.get(), internalformat); |
| 384 GLApiBase::glTexStorage2DEXTFn(target, levels, gl_internal_format, width, |
| 385 height); |
| 386 } |
| 387 |
| 388 void RealGLApi::glRenderbufferStorageEXTFn(GLenum target, |
| 389 GLenum internalformat, |
| 390 GLsizei width, |
| 391 GLsizei height) { |
| 392 GLenum gl_internal_format = GetInternalFormat(version_.get(), internalformat); |
| 393 GLApiBase::glRenderbufferStorageEXTFn(target, gl_internal_format, width, |
| 394 height); |
| 395 } |
| 396 |
| 397 // The ANGLE and IMG variants of glRenderbufferStorageMultisample currently do |
| 398 // not support BGRA render buffers so only the EXT one is customized. If |
| 399 // GL_CHROMIUM_renderbuffer_format_BGRA8888 support is added to ANGLE then the |
| 400 // ANGLE version should also be customized. |
| 401 void RealGLApi::glRenderbufferStorageMultisampleEXTFn(GLenum target, |
| 402 GLsizei samples, |
| 403 GLenum internalformat, |
| 404 GLsizei width, |
| 405 GLsizei height) { |
| 406 GLenum gl_internal_format = GetInternalFormat(version_.get(), internalformat); |
| 407 GLApiBase::glRenderbufferStorageMultisampleEXTFn( |
| 408 target, samples, gl_internal_format, width, height); |
| 409 } |
| 410 |
| 411 void RealGLApi::glRenderbufferStorageMultisampleFn(GLenum target, |
| 412 GLsizei samples, |
| 413 GLenum internalformat, |
| 414 GLsizei width, |
| 415 GLsizei height) { |
| 416 GLenum gl_internal_format = GetInternalFormat(version_.get(), internalformat); |
| 417 GLApiBase::glRenderbufferStorageMultisampleFn( |
| 418 target, samples, gl_internal_format, width, height); |
| 419 } |
| 420 |
| 421 void RealGLApi::glClearFn(GLbitfield mask) { |
| 422 if (!g_null_draw_bindings_enabled) |
| 423 GLApiBase::glClearFn(mask); |
| 424 } |
| 425 |
| 426 void RealGLApi::glDrawArraysFn(GLenum mode, GLint first, GLsizei count) { |
| 427 if (!g_null_draw_bindings_enabled) |
| 428 GLApiBase::glDrawArraysFn(mode, first, count); |
| 429 } |
| 430 |
| 431 void RealGLApi::glDrawElementsFn(GLenum mode, |
| 432 GLsizei count, |
| 433 GLenum type, |
| 434 const void* indices) { |
| 435 if (!g_null_draw_bindings_enabled) |
| 436 GLApiBase::glDrawElementsFn(mode, count, type, indices); |
| 437 } |
| 438 |
| 439 void RealGLApi::glClearDepthFn(GLclampd depth) { |
| 440 if (driver_->fn.glClearDepthFn) { |
| 441 GLApiBase::glClearDepthFn(depth); |
| 442 } else { |
| 443 DCHECK(driver_->fn.glClearDepthfFn); |
| 444 GLApiBase::glClearDepthfFn(static_cast<GLclampf>(depth)); |
| 445 } |
| 446 } |
| 447 |
| 448 void RealGLApi::glDepthRangeFn(GLclampd z_near, GLclampd z_far) { |
| 449 if (driver_->fn.glDepthRangeFn) { |
| 450 GLApiBase::glDepthRangeFn(z_near, z_far); |
| 451 } else { |
| 452 GLApiBase::glDepthRangefFn(static_cast<GLclampf>(z_near), |
| 453 static_cast<GLclampf>(z_far)); |
| 454 } |
| 455 } |
| 456 |
558 void RealGLApi::InitializeFilteredExtensions() { | 457 void RealGLApi::InitializeFilteredExtensions() { |
559 if (disabled_exts_.size()) { | 458 if (disabled_exts_.size()) { |
560 filtered_exts_.clear(); | 459 filtered_exts_.clear(); |
561 if (WillUseGLGetStringForExtensions()) { | 460 if (WillUseGLGetStringForExtensions(this)) { |
562 filtered_exts_str_ = | 461 filtered_exts_str_ = |
563 FilterGLExtensionList(reinterpret_cast<const char*>( | 462 FilterGLExtensionList(reinterpret_cast<const char*>( |
564 GLApiBase::glGetStringFn(GL_EXTENSIONS)), | 463 GLApiBase::glGetStringFn(GL_EXTENSIONS)), |
565 disabled_exts_); | 464 disabled_exts_); |
566 filtered_exts_ = base::SplitString( | 465 filtered_exts_ = base::SplitString( |
567 filtered_exts_str_, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 466 filtered_exts_str_, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
568 } else { | 467 } else { |
569 GLint num_extensions = 0; | 468 GLint num_extensions = 0; |
570 GLApiBase::glGetIntegervFn(GL_NUM_EXTENSIONS, &num_extensions); | 469 GLApiBase::glGetIntegervFn(GL_NUM_EXTENSIONS, &num_extensions); |
571 for (GLint i = 0; i < num_extensions; ++i) { | 470 for (GLint i = 0; i < num_extensions; ++i) { |
572 const char* gl_extension = reinterpret_cast<const char*>( | 471 const char* gl_extension = reinterpret_cast<const char*>( |
573 GLApiBase::glGetStringiFn(GL_EXTENSIONS, i)); | 472 GLApiBase::glGetStringiFn(GL_EXTENSIONS, i)); |
574 DCHECK(gl_extension != NULL); | 473 DCHECK(gl_extension != NULL); |
575 if (!base::ContainsValue(disabled_exts_, gl_extension)) | 474 if (!base::ContainsValue(disabled_exts_, gl_extension)) |
576 filtered_exts_.push_back(gl_extension); | 475 filtered_exts_.push_back(gl_extension); |
577 } | 476 } |
578 filtered_exts_str_ = base::JoinString(filtered_exts_, " "); | 477 filtered_exts_str_ = base::JoinString(filtered_exts_, " "); |
579 } | 478 } |
580 #if DCHECK_IS_ON() | 479 #if DCHECK_IS_ON() |
581 filtered_exts_initialized_ = true; | 480 filtered_exts_initialized_ = true; |
582 #endif | 481 #endif |
583 } | 482 } |
584 } | 483 } |
585 | 484 |
| 485 void RealGLApi::set_version(std::unique_ptr<GLVersionInfo> version) { |
| 486 version_ = std::move(version); |
| 487 } |
| 488 |
586 TraceGLApi::~TraceGLApi() { | 489 TraceGLApi::~TraceGLApi() { |
587 } | 490 } |
588 | 491 |
| 492 DebugGLApi::DebugGLApi(GLApi* gl_api) : gl_api_(gl_api) {} |
| 493 |
| 494 DebugGLApi::~DebugGLApi() {} |
| 495 |
589 NoContextGLApi::NoContextGLApi() { | 496 NoContextGLApi::NoContextGLApi() { |
590 } | 497 } |
591 | 498 |
592 NoContextGLApi::~NoContextGLApi() { | 499 NoContextGLApi::~NoContextGLApi() { |
593 } | 500 } |
594 | 501 |
595 } // namespace gl | 502 } // namespace gl |
OLD | NEW |