diff options
Diffstat (limited to 'chromium/ui/gl/gl_gl_api_implementation.cc')
-rw-r--r-- | chromium/ui/gl/gl_gl_api_implementation.cc | 199 |
1 files changed, 173 insertions, 26 deletions
diff --git a/chromium/ui/gl/gl_gl_api_implementation.cc b/chromium/ui/gl/gl_gl_api_implementation.cc index eade3cedaf5..2973388a276 100644 --- a/chromium/ui/gl/gl_gl_api_implementation.cc +++ b/chromium/ui/gl/gl_gl_api_implementation.cc @@ -14,15 +14,21 @@ #include "ui/gl/gl_state_restorer.h" #include "ui/gl/gl_surface.h" #include "ui/gl/gl_switches.h" +#include "ui/gl/gl_version_info.h" namespace gfx { // The GL Api being used. This could be g_real_gl or gl_trace_gl -static GLApi* g_gl; +static GLApi* g_gl = NULL; // A GL Api that calls directly into the driver. -static RealGLApi* g_real_gl; +static RealGLApi* g_real_gl = NULL; +// A GL Api that does nothing but warn about illegal GL calls without a context +// current. +static NoContextGLApi* g_no_context_gl = NULL; // A GL Api that calls TRACE and then calls another GL api. -static TraceGLApi* g_trace_gl; +static TraceGLApi* g_trace_gl = NULL; +// GL version used when initializing dynamic bindings. +static GLVersionInfo* g_version_info = NULL; namespace { @@ -40,7 +46,28 @@ static inline GLenum GetTexInternalFormat(GLenum internal_format, GLenum type) { GLenum gl_internal_format = GetInternalFormat(internal_format); - if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) + // g_version_info must be initialized when this function is bound. + DCHECK(gfx::g_version_info); + if (type == GL_FLOAT && gfx::g_version_info->is_angle && + gfx::g_version_info->is_es2) { + // It's possible that the texture is using a sized internal format, and + // ANGLE exposing GLES2 API doesn't support those. + // TODO(oetuaho@nvidia.com): Remove these conversions once ANGLE has the + // support. + // http://code.google.com/p/angleproject/issues/detail?id=556 + switch (format) { + case GL_RGBA: + gl_internal_format = GL_RGBA; + break; + case GL_RGB: + gl_internal_format = GL_RGB; + break; + default: + break; + } + } + + if (gfx::g_version_info->is_es) return gl_internal_format; if (type == GL_FLOAT) { @@ -104,7 +131,7 @@ static void GL_BINDING_CALL CustomTexImage2D( GLenum gl_internal_format = GetTexInternalFormat( internalformat, format, type); GLenum gl_type = GetTexType(type); - return g_driver_gl.orig_fn.glTexImage2DFn( + g_driver_gl.orig_fn.glTexImage2DFn( target, level, gl_internal_format, width, height, border, format, gl_type, pixels); } @@ -113,7 +140,7 @@ static void GL_BINDING_CALL CustomTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) { GLenum gl_type = GetTexType(type); - return g_driver_gl.orig_fn.glTexSubImage2DFn( + g_driver_gl.orig_fn.glTexSubImage2DFn( target, level, xoffset, yoffset, width, height, format, gl_type, pixels); } @@ -121,14 +148,14 @@ static void GL_BINDING_CALL CustomTexStorage2DEXT( GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { GLenum gl_internal_format = GetInternalFormat(internalformat); - return g_driver_gl.orig_fn.glTexStorage2DEXTFn( + g_driver_gl.orig_fn.glTexStorage2DEXTFn( target, levels, gl_internal_format, width, height); } static void GL_BINDING_CALL CustomRenderbufferStorageEXT( GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { GLenum gl_internal_format = GetInternalFormat(internalformat); - return g_driver_gl.orig_fn.glRenderbufferStorageEXTFn( + g_driver_gl.orig_fn.glRenderbufferStorageEXTFn( target, gl_internal_format, width, height); } @@ -140,39 +167,101 @@ static void GL_BINDING_CALL CustomRenderbufferStorageMultisampleEXT( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { GLenum gl_internal_format = GetInternalFormat(internalformat); - return g_driver_gl.orig_fn.glRenderbufferStorageMultisampleEXTFn( + g_driver_gl.orig_fn.glRenderbufferStorageMultisampleEXTFn( target, samples, gl_internal_format, width, height); } } // anonymous namespace -void DriverGL::Initialize() { - InitializeBindings(); -} +void DriverGL::InitializeCustomDynamicBindings(GLContext* context) { + InitializeDynamicBindings(context); -void DriverGL::InitializeExtensions(GLContext* context) { - InitializeExtensionBindings(context); - orig_fn = fn; + DCHECK(orig_fn.glTexImage2DFn == NULL); + orig_fn.glTexImage2DFn = fn.glTexImage2DFn; fn.glTexImage2DFn = reinterpret_cast<glTexImage2DProc>(CustomTexImage2D); + + DCHECK(orig_fn.glTexSubImage2DFn == NULL); + orig_fn.glTexSubImage2DFn = fn.glTexSubImage2DFn; fn.glTexSubImage2DFn = reinterpret_cast<glTexSubImage2DProc>(CustomTexSubImage2D); + + DCHECK(orig_fn.glTexStorage2DEXTFn == NULL); + orig_fn.glTexStorage2DEXTFn = fn.glTexStorage2DEXTFn; fn.glTexStorage2DEXTFn = reinterpret_cast<glTexStorage2DEXTProc>(CustomTexStorage2DEXT); + + DCHECK(orig_fn.glRenderbufferStorageEXTFn == NULL); + orig_fn.glRenderbufferStorageEXTFn = fn.glRenderbufferStorageEXTFn; fn.glRenderbufferStorageEXTFn = reinterpret_cast<glRenderbufferStorageEXTProc>( CustomRenderbufferStorageEXT); + + DCHECK(orig_fn.glRenderbufferStorageMultisampleEXTFn == NULL); + orig_fn.glRenderbufferStorageMultisampleEXTFn = + fn.glRenderbufferStorageMultisampleEXTFn; fn.glRenderbufferStorageMultisampleEXTFn = reinterpret_cast<glRenderbufferStorageMultisampleEXTProc>( CustomRenderbufferStorageMultisampleEXT); } -void InitializeGLBindingsGL() { +static void GL_BINDING_CALL NullDrawClearFn(GLbitfield mask) { + if (!g_driver_gl.null_draw_bindings_enabled) + g_driver_gl.orig_fn.glClearFn(mask); +} + +static void GL_BINDING_CALL +NullDrawDrawArraysFn(GLenum mode, GLint first, GLsizei count) { + if (!g_driver_gl.null_draw_bindings_enabled) + g_driver_gl.orig_fn.glDrawArraysFn(mode, first, count); +} + +static void GL_BINDING_CALL NullDrawDrawElementsFn(GLenum mode, + GLsizei count, + GLenum type, + const void* indices) { + if (!g_driver_gl.null_draw_bindings_enabled) + g_driver_gl.orig_fn.glDrawElementsFn(mode, count, type, indices); +} + +void DriverGL::InitializeNullDrawBindings() { + DCHECK(orig_fn.glClearFn == NULL); + orig_fn.glClearFn = fn.glClearFn; + fn.glClearFn = NullDrawClearFn; + + DCHECK(orig_fn.glDrawArraysFn == NULL); + orig_fn.glDrawArraysFn = fn.glDrawArraysFn; + fn.glDrawArraysFn = NullDrawDrawArraysFn; + + DCHECK(orig_fn.glDrawElementsFn == NULL); + orig_fn.glDrawElementsFn = fn.glDrawElementsFn; + fn.glDrawElementsFn = NullDrawDrawElementsFn; + + null_draw_bindings_enabled = true; +} + +bool DriverGL::HasInitializedNullDrawBindings() { + return orig_fn.glClearFn != NULL && orig_fn.glDrawArraysFn != NULL && + orig_fn.glDrawElementsFn != NULL; +} + +bool DriverGL::SetNullDrawBindingsEnabled(bool enabled) { + DCHECK(orig_fn.glClearFn != NULL); + DCHECK(orig_fn.glDrawArraysFn != NULL); + DCHECK(orig_fn.glDrawElementsFn != NULL); + + bool before = null_draw_bindings_enabled; + null_draw_bindings_enabled = enabled; + return before; +} + +void InitializeStaticGLBindingsGL() { g_current_gl_context_tls = new base::ThreadLocalPointer<GLApi>; - g_driver_gl.Initialize(); + g_driver_gl.InitializeStaticBindings(); if (!g_real_gl) { g_real_gl = new RealGLApi(); g_trace_gl = new TraceGLApi(g_real_gl); + g_no_context_gl = new NoContextGLApi(); } g_real_gl->Initialize(&g_driver_gl); g_gl = g_real_gl; @@ -195,14 +284,33 @@ void SetGLToRealGLApi() { SetGLApi(g_gl); } -void InitializeGLExtensionBindingsGL(GLContext* context) { - g_driver_gl.InitializeExtensions(context); +void SetGLApiToNoContext() { + SetGLApi(g_no_context_gl); +} + +void InitializeDynamicGLBindingsGL(GLContext* context) { + g_driver_gl.InitializeCustomDynamicBindings(context); + DCHECK(context && context->IsCurrent(NULL) && !g_version_info); + g_version_info = new GLVersionInfo(context->GetGLVersion().c_str(), + context->GetGLRenderer().c_str()); } void InitializeDebugGLBindingsGL() { g_driver_gl.InitializeDebugBindings(); } +void InitializeNullDrawGLBindingsGL() { + g_driver_gl.InitializeNullDrawBindings(); +} + +bool HasInitializedNullDrawGLBindingsGL() { + return g_driver_gl.HasInitializedNullDrawBindings(); +} + +bool SetNullDrawGLBindingsEnabledGL(bool enabled) { + return g_driver_gl.SetNullDrawBindingsEnabled(enabled); +} + void ClearGLBindingsGL() { if (g_real_gl) { delete g_real_gl; @@ -212,12 +320,20 @@ void ClearGLBindingsGL() { delete g_trace_gl; g_trace_gl = NULL; } + if (g_no_context_gl) { + delete g_no_context_gl; + g_no_context_gl = NULL; + } g_gl = NULL; g_driver_gl.ClearBindings(); if (g_current_gl_context_tls) { delete g_current_gl_context_tls; g_current_gl_context_tls = NULL; } + if (g_version_info) { + delete g_version_info; + g_version_info = NULL; + } } GLApi::GLApi() { @@ -239,6 +355,11 @@ void GLApiBase::InitializeBase(DriverGL* driver) { driver_ = driver; } +void GLApiBase::SignalFlush() { + DCHECK(GLContext::GetCurrent()); + GLContext::GetCurrent()->OnFlush(); +} + RealGLApi::RealGLApi() { } @@ -249,9 +370,25 @@ void RealGLApi::Initialize(DriverGL* driver) { InitializeBase(driver); } +void RealGLApi::glFlushFn() { + GLApiBase::glFlushFn(); + GLApiBase::SignalFlush(); +} + +void RealGLApi::glFinishFn() { + GLApiBase::glFinishFn(); + GLApiBase::SignalFlush(); +} + TraceGLApi::~TraceGLApi() { } +NoContextGLApi::NoContextGLApi() { +} + +NoContextGLApi::~NoContextGLApi() { +} + VirtualGLApi::VirtualGLApi() : real_context_(NULL), current_context_(NULL) { @@ -305,17 +442,17 @@ bool VirtualGLApi::MakeCurrent(GLContext* virtual_context, GLSurface* surface) { // new context. DCHECK_EQ(glGetErrorFn(), static_cast<GLenum>(GL_NO_ERROR)); - current_context_ = virtual_context; // Set all state that is different from the real state - // NOTE: !!! This is a temporary implementation that just restores all - // state to let us test that it works. - // TODO: ASAP, change this to something that only restores the state - // needed for individual GL calls. GLApi* temp = GetCurrentGLApi(); SetGLToRealGLApi(); - if (virtual_context->GetGLStateRestorer()->IsInitialized()) - virtual_context->GetGLStateRestorer()->RestoreState(); + if (virtual_context->GetGLStateRestorer()->IsInitialized()) { + virtual_context->GetGLStateRestorer()->RestoreState( + (current_context_ && !switched_contexts) + ? current_context_->GetGLStateRestorer() + : NULL); + } SetGLApi(temp); + current_context_ = virtual_context; } SetGLApi(this); @@ -341,4 +478,14 @@ const GLubyte* VirtualGLApi::glGetStringFn(GLenum name) { } } +void VirtualGLApi::glFlushFn() { + GLApiBase::glFlushFn(); + GLApiBase::SignalFlush(); +} + +void VirtualGLApi::glFinishFn() { + GLApiBase::glFinishFn(); + GLApiBase::SignalFlush(); +} + } // namespace gfx |