Fix overlays on Mac OS when running on Core Profile.
[chromium-blink-merge.git] / ui / gl / gl_implementation.cc
blob522386a113b6ae95baaff4a1847311b7bad878bb
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
3 // found in the LICENSE file.
5 #include "ui/gl/gl_implementation.h"
7 #include <algorithm>
8 #include <string>
10 #include "base/at_exit.h"
11 #include "base/command_line.h"
12 #include "base/logging.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h"
15 #include "ui/gl/gl_bindings.h"
16 #include "ui/gl/gl_gl_api_implementation.h"
17 #include "ui/gl/gl_version_info.h"
19 namespace gfx {
21 namespace {
23 const struct {
24 const char* name;
25 GLImplementation implementation;
26 } kGLImplementationNamePairs[] = {
27 { kGLImplementationDesktopName, kGLImplementationDesktopGL },
28 { kGLImplementationOSMesaName, kGLImplementationOSMesaGL },
29 #if defined(OS_MACOSX)
30 { kGLImplementationAppleName, kGLImplementationAppleGL },
31 #endif
32 { kGLImplementationEGLName, kGLImplementationEGLGLES2 },
33 { kGLImplementationMockName, kGLImplementationMockGL }
36 typedef std::vector<base::NativeLibrary> LibraryArray;
38 GLImplementation g_gl_implementation = kGLImplementationNone;
39 LibraryArray* g_libraries;
40 GLGetProcAddressProc g_get_proc_address;
42 void CleanupNativeLibraries(void* unused) {
43 if (g_libraries) {
44 // We do not call base::UnloadNativeLibrary() for these libraries as
45 // unloading libGL without closing X display is not allowed. See
46 // crbug.com/250813 for details.
47 delete g_libraries;
48 g_libraries = NULL;
54 base::ThreadLocalPointer<GLApi>* g_current_gl_context_tls = NULL;
55 OSMESAApi* g_current_osmesa_context;
57 #if defined(OS_WIN)
59 EGLApi* g_current_egl_context;
60 WGLApi* g_current_wgl_context;
62 #elif defined(USE_X11)
64 EGLApi* g_current_egl_context;
65 GLXApi* g_current_glx_context;
67 #elif defined(USE_OZONE)
69 EGLApi* g_current_egl_context;
71 #elif defined(OS_ANDROID)
73 EGLApi* g_current_egl_context;
75 #endif
77 GLImplementation GetNamedGLImplementation(const std::string& name) {
78 for (size_t i = 0; i < arraysize(kGLImplementationNamePairs); ++i) {
79 if (name == kGLImplementationNamePairs[i].name)
80 return kGLImplementationNamePairs[i].implementation;
83 return kGLImplementationNone;
86 const char* GetGLImplementationName(GLImplementation implementation) {
87 for (size_t i = 0; i < arraysize(kGLImplementationNamePairs); ++i) {
88 if (implementation == kGLImplementationNamePairs[i].implementation)
89 return kGLImplementationNamePairs[i].name;
92 return "unknown";
95 void SetGLImplementation(GLImplementation implementation) {
96 g_gl_implementation = implementation;
99 GLImplementation GetGLImplementation() {
100 return g_gl_implementation;
103 bool HasDesktopGLFeatures() {
104 return kGLImplementationDesktopGL == g_gl_implementation ||
105 kGLImplementationDesktopGLCoreProfile == g_gl_implementation ||
106 kGLImplementationOSMesaGL == g_gl_implementation ||
107 kGLImplementationAppleGL == g_gl_implementation;
110 void AddGLNativeLibrary(base::NativeLibrary library) {
111 DCHECK(library);
113 if (!g_libraries) {
114 g_libraries = new LibraryArray;
115 base::AtExitManager::RegisterCallback(CleanupNativeLibraries, NULL);
118 g_libraries->push_back(library);
121 void UnloadGLNativeLibraries() {
122 CleanupNativeLibraries(NULL);
125 void SetGLGetProcAddressProc(GLGetProcAddressProc proc) {
126 DCHECK(proc);
127 g_get_proc_address = proc;
130 void* GetGLProcAddress(const char* name) {
131 DCHECK(g_gl_implementation != kGLImplementationNone);
133 if (g_libraries) {
134 for (size_t i = 0; i < g_libraries->size(); ++i) {
135 void* proc = base::GetFunctionPointerFromNativeLibrary((*g_libraries)[i],
136 name);
137 if (proc)
138 return proc;
141 if (g_get_proc_address) {
142 void* proc = g_get_proc_address(name);
143 if (proc)
144 return proc;
147 return NULL;
150 void InitializeNullDrawGLBindings() {
151 // This is platform independent, so it does not need to live in a platform
152 // specific implementation file.
153 InitializeNullDrawGLBindingsGL();
156 bool HasInitializedNullDrawGLBindings() {
157 return HasInitializedNullDrawGLBindingsGL();
160 std::string FilterGLExtensionList(
161 const char* extensions,
162 const std::vector<std::string>& disabled_extensions) {
163 if (extensions == NULL)
164 return "";
166 std::vector<std::string> extension_vec;
167 base::SplitString(extensions, ' ', &extension_vec);
169 auto is_disabled = [&disabled_extensions](const std::string& ext) {
170 return std::find(disabled_extensions.begin(), disabled_extensions.end(),
171 ext) != disabled_extensions.end();
173 extension_vec.erase(
174 std::remove_if(extension_vec.begin(), extension_vec.end(), is_disabled),
175 extension_vec.end());
177 return base::JoinString(extension_vec, " ");
180 DisableNullDrawGLBindings::DisableNullDrawGLBindings() {
181 initial_enabled_ = SetNullDrawGLBindingsEnabledGL(false);
184 DisableNullDrawGLBindings::~DisableNullDrawGLBindings() {
185 SetNullDrawGLBindingsEnabledGL(initial_enabled_);
188 GLWindowSystemBindingInfo::GLWindowSystemBindingInfo()
189 : direct_rendering(true) {}
191 std::string GetGLExtensionsFromCurrentContext() {
192 if (WillUseGLGetStringForExtensions()) {
193 return reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
196 std::vector<std::string> exts;
197 GLint num_extensions = 0;
198 glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
199 for (GLint i = 0; i < num_extensions; ++i) {
200 const char* extension = reinterpret_cast<const char*>(
201 glGetStringi(GL_EXTENSIONS, i));
202 DCHECK(extension != NULL);
203 exts.push_back(extension);
205 return base::JoinString(exts, " ");
208 bool WillUseGLGetStringForExtensions() {
209 const char* version_str =
210 reinterpret_cast<const char*>(glGetString(GL_VERSION));
211 unsigned major_version, minor_version;
212 bool is_es, is_es3;
213 gfx::GLVersionInfo::ParseVersionString(
214 version_str, &major_version, &minor_version, &is_es, &is_es3);
215 return is_es || major_version < 3;
218 } // namespace gfx