summaryrefslogtreecommitdiffstats
path: root/chromium/ui/gl/gl_gl_api_implementation.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/gl/gl_gl_api_implementation.cc')
-rw-r--r--chromium/ui/gl/gl_gl_api_implementation.cc199
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