| 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 |