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"
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"
25 GLImplementation implementation
;
26 } kGLImplementationNamePairs
[] = {
27 { kGLImplementationDesktopName
, kGLImplementationDesktopGL
},
28 { kGLImplementationOSMesaName
, kGLImplementationOSMesaGL
},
29 #if defined(OS_MACOSX)
30 { kGLImplementationAppleName
, kGLImplementationAppleGL
},
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
) {
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.
54 base::ThreadLocalPointer
<GLApi
>* g_current_gl_context_tls
= NULL
;
55 OSMESAApi
* g_current_osmesa_context
;
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
;
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
;
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
) {
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
) {
127 g_get_proc_address
= proc
;
130 void* GetGLProcAddress(const char* name
) {
131 DCHECK(g_gl_implementation
!= kGLImplementationNone
);
134 for (size_t i
= 0; i
< g_libraries
->size(); ++i
) {
135 void* proc
= base::GetFunctionPointerFromNativeLibrary((*g_libraries
)[i
],
141 if (g_get_proc_address
) {
142 void* proc
= g_get_proc_address(name
);
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
)
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();
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
;
213 gfx::GLVersionInfo::ParseVersionString(
214 version_str
, &major_version
, &minor_version
, &is_es
, &is_es3
);
215 return is_es
|| major_version
< 3;