Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Unified Diff: ui/gl/gl_gl_api_implementation.cc

Issue 2629633003: Refactor GL bindings so there is no global GLApi or DriverGL. (Closed)
Patch Set: rebase Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/gl/gl_gl_api_implementation.h ('k') | ui/gl/gl_glx_api_implementation.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gl/gl_gl_api_implementation.cc
diff --git a/ui/gl/gl_gl_api_implementation.cc b/ui/gl/gl_gl_api_implementation.cc
index 265bd31f2bc2b86b83c0a4bd79bc1ceaf372cf25..cc4453ea910464274308768dfb8a9dcc9e77dc71 100644
--- a/ui/gl/gl_gl_api_implementation.cc
+++ b/ui/gl/gl_gl_api_implementation.cc
@@ -7,6 +7,7 @@
#include <vector>
#include "base/command_line.h"
+#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
@@ -19,28 +20,25 @@
namespace gl {
-// The GL Api being used. This could be g_real_gl or gl_trace_gl
-static GLApi* g_gl = NULL;
-// A GL Api that calls directly into the driver.
-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 = NULL;
-// The GL Api being used for stub contexts. If null, g_gl is used instead.
-static GLApi* g_stub_gl = NULL;
-// GL version used when initializing dynamic bindings.
-static GLVersionInfo* g_version_info = NULL;
+// The GL state for when no context is bound
+static CurrentGL* g_no_context_current_gl = nullptr;
+
+// If the null draw bindings are currently enabled.
+// TODO: Consider adding a new GLApi that no-ops these functions
+static bool g_null_draw_bindings_enabled = false;
+
+// If the GL debug bindings are enabled.
+static bool g_debug_bindings_enabled = false;
namespace {
-static inline GLenum GetInternalFormat(GLenum internal_format) {
- if (!g_version_info->is_es) {
+static inline GLenum GetInternalFormat(const GLVersionInfo* version,
+ GLenum internal_format) {
+ if (!version->is_es) {
if (internal_format == GL_BGRA_EXT || internal_format == GL_BGRA8_EXT)
return GL_RGBA8;
}
- if (g_version_info->is_es3 && g_version_info->is_mesa) {
+ if (version->is_es3 && version->is_mesa) {
// Mesa bug workaround: Mipmapping does not work when using GL_BGRA_EXT
if (internal_format == GL_BGRA_EXT)
return GL_RGBA;
@@ -49,14 +47,14 @@ static inline GLenum GetInternalFormat(GLenum internal_format) {
}
// TODO(epenner): Could the above function be merged into this and removed?
-static inline GLenum GetTexInternalFormat(GLenum internal_format,
+static inline GLenum GetTexInternalFormat(const GLVersionInfo* version,
+ GLenum internal_format,
GLenum format,
GLenum type) {
- DCHECK(g_version_info);
- GLenum gl_internal_format = GetInternalFormat(internal_format);
+ GLenum gl_internal_format = GetInternalFormat(version, internal_format);
// g_version_info must be initialized when this function is bound.
- if (g_version_info->is_es3) {
+ if (version->is_es3) {
if (internal_format == GL_RED_EXT) {
// GL_EXT_texture_rg case in ES2.
switch (type) {
@@ -94,8 +92,8 @@ static inline GLenum GetTexInternalFormat(GLenum internal_format,
}
}
- if (type == GL_FLOAT && g_version_info->is_angle && g_version_info->is_es &&
- g_version_info->major_version == 2) {
+ if (type == GL_FLOAT && version->is_angle && version->is_es &&
+ version->major_version == 2) {
// 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
@@ -113,8 +111,7 @@ static inline GLenum GetTexInternalFormat(GLenum internal_format,
}
}
- if (g_version_info->IsAtLeastGL(2, 1) ||
- g_version_info->IsAtLeastGLES(3, 0)) {
+ if (version->IsAtLeastGL(2, 1) || version->IsAtLeastGLES(3, 0)) {
switch (internal_format) {
case GL_SRGB_EXT:
gl_internal_format = GL_SRGB8;
@@ -127,7 +124,7 @@ static inline GLenum GetTexInternalFormat(GLenum internal_format,
}
}
- if (g_version_info->is_es)
+ if (version->is_es)
return gl_internal_format;
if (type == GL_FLOAT) {
@@ -195,12 +192,10 @@ static inline GLenum GetTexInternalFormat(GLenum internal_format,
return gl_internal_format;
}
-static inline GLenum GetTexFormat(GLenum format) {
+static inline GLenum GetTexFormat(const GLVersionInfo* version, GLenum format) {
GLenum gl_format = format;
- DCHECK(g_version_info);
- if (g_version_info->IsAtLeastGL(2, 1) ||
- g_version_info->IsAtLeastGLES(3, 0)) {
+ if (version->IsAtLeastGL(2, 1) || version->IsAtLeastGLES(3, 0)) {
switch (format) {
case GL_SRGB_EXT:
gl_format = GL_RGB;
@@ -216,271 +211,64 @@ static inline GLenum GetTexFormat(GLenum format) {
return gl_format;
}
-static inline GLenum GetTexType(GLenum type) {
- if (!g_version_info->is_es) {
+static inline GLenum GetTexType(const GLVersionInfo* version, GLenum type) {
+ if (!version->is_es) {
if (type == GL_HALF_FLOAT_OES)
return GL_HALF_FLOAT_ARB;
}
return type;
}
-static void GL_BINDING_CALL CustomTexImage2D(
- GLenum target, GLint level, GLint internalformat,
- GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type,
- const void* pixels) {
- GLenum gl_internal_format = GetTexInternalFormat(
- internalformat, format, type);
- GLenum gl_format = GetTexFormat(format);
- GLenum gl_type = GetTexType(type);
- g_driver_gl.orig_fn.glTexImage2DFn(
- target, level, gl_internal_format, width, height, border, gl_format,
- gl_type, pixels);
-}
-
-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_format = GetTexFormat(format);
- GLenum gl_type = GetTexType(type);
- g_driver_gl.orig_fn.glTexSubImage2DFn(
- target, level, xoffset, yoffset, width, height, gl_format, gl_type,
- pixels);
-}
-
-static void GL_BINDING_CALL CustomTexStorage2DEXT(
- GLenum target, GLsizei levels, GLenum internalformat, GLsizei width,
- GLsizei height) {
- GLenum gl_internal_format = GetInternalFormat(internalformat);
- 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);
- g_driver_gl.orig_fn.glRenderbufferStorageEXTFn(
- target, gl_internal_format, width, height);
-}
-
-// The ANGLE and IMG variants of glRenderbufferStorageMultisample currently do
-// not support BGRA render buffers so only the EXT one is customized. If
-// GL_CHROMIUM_renderbuffer_format_BGRA8888 support is added to ANGLE then the
-// ANGLE version should also be customized.
-static void GL_BINDING_CALL CustomRenderbufferStorageMultisampleEXT(
- GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
- GLsizei height) {
- GLenum gl_internal_format = GetInternalFormat(internalformat);
- g_driver_gl.orig_fn.glRenderbufferStorageMultisampleEXTFn(
- target, samples, gl_internal_format, width, height);
-}
-
-static void GL_BINDING_CALL
-CustomRenderbufferStorageMultisample(GLenum target,
- GLsizei samples,
- GLenum internalformat,
- GLsizei width,
- GLsizei height) {
- GLenum gl_internal_format = GetInternalFormat(internalformat);
- g_driver_gl.orig_fn.glRenderbufferStorageMultisampleFn(
- target, samples, gl_internal_format, width, height);
-}
-
} // anonymous namespace
-void DriverGL::InitializeCustomDynamicBindings(GLContext* context) {
- InitializeDynamicBindings(context);
-
- 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);
-
- DCHECK(orig_fn.glRenderbufferStorageMultisampleFn == NULL);
- orig_fn.glRenderbufferStorageMultisampleFn =
- fn.glRenderbufferStorageMultisampleFn;
- fn.glRenderbufferStorageMultisampleFn =
- reinterpret_cast<glRenderbufferStorageMultisampleProc>(
- CustomRenderbufferStorageMultisample);
-}
-
-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.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;
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableGPUServiceTracing)) {
- g_gl = g_trace_gl;
- }
- SetGLToRealGLApi();
-}
-
-GLApi* GetCurrentGLApi() {
- return g_current_gl_context_tls ? g_current_gl_context_tls->Get() : nullptr;
-}
-
-void SetGLApi(GLApi* api) {
- g_current_gl_context_tls->Set(api);
-}
-
-void SetGLToRealGLApi() {
- SetGLApi(g_gl);
-}
-
-void SetGLToStubGLApi() {
- SetGLApi(g_stub_gl ? g_stub_gl : g_gl);
-}
-
-void SetGLApiToNoContext() {
- SetGLApi(g_no_context_gl);
-}
-
-void SetStubGLApi(GLApi* api) {
- g_stub_gl = api;
+ g_current_gl_context_tls = new base::ThreadLocalPointer<CurrentGL>;
+ g_no_context_current_gl = new CurrentGL;
+ g_no_context_current_gl->Api = new NoContextGLApi;
}
-const GLVersionInfo* GetGLVersionInfo() {
- return g_version_info;
-}
+void ClearBindingsGL() {
+ if (g_no_context_current_gl) {
+ delete g_no_context_current_gl->Api;
+ delete g_no_context_current_gl->Driver;
+ delete g_no_context_current_gl->Version;
+ delete g_no_context_current_gl;
+ g_no_context_current_gl = nullptr;
+ }
-void InitializeDynamicGLBindingsGL(GLContext* context) {
- if (g_version_info)
- return;
- g_real_gl->InitializeFilteredExtensions();
- 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(),
- context->GetExtensions().c_str());
+ if (g_current_gl_context_tls) {
+ delete g_current_gl_context_tls;
+ g_current_gl_context_tls = nullptr;
+ }
}
void InitializeDebugGLBindingsGL() {
- g_driver_gl.InitializeDebugBindings();
+ g_debug_bindings_enabled = true;
}
-void InitializeNullDrawGLBindingsGL() {
- g_driver_gl.InitializeNullDrawBindings();
+bool GetDebugGLBindingsInitializedGL() {
+ return g_debug_bindings_enabled;
}
-bool HasInitializedNullDrawGLBindingsGL() {
- return g_driver_gl.HasInitializedNullDrawBindings();
+bool SetNullDrawGLBindingsEnabled(bool enabled) {
+ bool old_value = g_null_draw_bindings_enabled;
+ g_null_draw_bindings_enabled = enabled;
+ return old_value;
}
-bool SetNullDrawGLBindingsEnabledGL(bool enabled) {
- return g_driver_gl.SetNullDrawBindingsEnabled(enabled);
+bool GetNullDrawBindingsEnabled() {
+ return g_null_draw_bindings_enabled;
}
-void ClearBindingsGL() {
- if (g_real_gl) {
- delete g_real_gl;
- g_real_gl = NULL;
- }
- if (g_trace_gl) {
- 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_stub_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;
- }
+void SetCurrentGL(CurrentGL* current) {
+ CurrentGL* new_current = current ? current : g_no_context_current_gl;
+ g_current_gl_context_tls->Set(new_current);
}
GLApi::GLApi() {
}
GLApi::~GLApi() {
- if (GetCurrentGLApi() == this)
- SetGLApi(NULL);
}
GLApiBase::GLApiBase()
@@ -555,10 +343,121 @@ const GLubyte* RealGLApi::glGetStringiFn(GLenum name, GLuint index) {
return GLApiBase::glGetStringiFn(name, index);
}
+void RealGLApi::glTexImage2DFn(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void* pixels) {
+ GLenum gl_internal_format =
+ GetTexInternalFormat(version_.get(), internalformat, format, type);
+ GLenum gl_format = GetTexFormat(version_.get(), format);
+ GLenum gl_type = GetTexType(version_.get(), type);
+ GLApiBase::glTexImage2DFn(target, level, gl_internal_format, width, height,
+ border, gl_format, gl_type, pixels);
+}
+
+void RealGLApi::glTexSubImage2DFn(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void* pixels) {
+ GLenum gl_format = GetTexFormat(version_.get(), format);
+ GLenum gl_type = GetTexType(version_.get(), type);
+ GLApiBase::glTexSubImage2DFn(target, level, xoffset, yoffset, width, height,
+ gl_format, gl_type, pixels);
+}
+
+void RealGLApi::glTexStorage2DEXTFn(GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height) {
+ GLenum gl_internal_format = GetInternalFormat(version_.get(), internalformat);
+ GLApiBase::glTexStorage2DEXTFn(target, levels, gl_internal_format, width,
+ height);
+}
+
+void RealGLApi::glRenderbufferStorageEXTFn(GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height) {
+ GLenum gl_internal_format = GetInternalFormat(version_.get(), internalformat);
+ GLApiBase::glRenderbufferStorageEXTFn(target, gl_internal_format, width,
+ height);
+}
+
+// The ANGLE and IMG variants of glRenderbufferStorageMultisample currently do
+// not support BGRA render buffers so only the EXT one is customized. If
+// GL_CHROMIUM_renderbuffer_format_BGRA8888 support is added to ANGLE then the
+// ANGLE version should also be customized.
+void RealGLApi::glRenderbufferStorageMultisampleEXTFn(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height) {
+ GLenum gl_internal_format = GetInternalFormat(version_.get(), internalformat);
+ GLApiBase::glRenderbufferStorageMultisampleEXTFn(
+ target, samples, gl_internal_format, width, height);
+}
+
+void RealGLApi::glRenderbufferStorageMultisampleFn(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height) {
+ GLenum gl_internal_format = GetInternalFormat(version_.get(), internalformat);
+ GLApiBase::glRenderbufferStorageMultisampleFn(
+ target, samples, gl_internal_format, width, height);
+}
+
+void RealGLApi::glClearFn(GLbitfield mask) {
+ if (!g_null_draw_bindings_enabled)
+ GLApiBase::glClearFn(mask);
+}
+
+void RealGLApi::glDrawArraysFn(GLenum mode, GLint first, GLsizei count) {
+ if (!g_null_draw_bindings_enabled)
+ GLApiBase::glDrawArraysFn(mode, first, count);
+}
+
+void RealGLApi::glDrawElementsFn(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void* indices) {
+ if (!g_null_draw_bindings_enabled)
+ GLApiBase::glDrawElementsFn(mode, count, type, indices);
+}
+
+void RealGLApi::glClearDepthFn(GLclampd depth) {
+ if (driver_->fn.glClearDepthFn) {
+ GLApiBase::glClearDepthFn(depth);
+ } else {
+ DCHECK(driver_->fn.glClearDepthfFn);
+ GLApiBase::glClearDepthfFn(static_cast<GLclampf>(depth));
+ }
+}
+
+void RealGLApi::glDepthRangeFn(GLclampd z_near, GLclampd z_far) {
+ if (driver_->fn.glDepthRangeFn) {
+ GLApiBase::glDepthRangeFn(z_near, z_far);
+ } else {
+ GLApiBase::glDepthRangefFn(static_cast<GLclampf>(z_near),
+ static_cast<GLclampf>(z_far));
+ }
+}
+
void RealGLApi::InitializeFilteredExtensions() {
if (disabled_exts_.size()) {
filtered_exts_.clear();
- if (WillUseGLGetStringForExtensions()) {
+ if (WillUseGLGetStringForExtensions(this)) {
filtered_exts_str_ =
FilterGLExtensionList(reinterpret_cast<const char*>(
GLApiBase::glGetStringFn(GL_EXTENSIONS)),
@@ -583,9 +482,17 @@ void RealGLApi::InitializeFilteredExtensions() {
}
}
+void RealGLApi::set_version(std::unique_ptr<GLVersionInfo> version) {
+ version_ = std::move(version);
+}
+
TraceGLApi::~TraceGLApi() {
}
+DebugGLApi::DebugGLApi(GLApi* gl_api) : gl_api_(gl_api) {}
+
+DebugGLApi::~DebugGLApi() {}
+
NoContextGLApi::NoContextGLApi() {
}
« no previous file with comments | « ui/gl/gl_gl_api_implementation.h ('k') | ui/gl/gl_glx_api_implementation.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698