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.
4
5 #include "ui/gl/gl_implementation.h"
6
7 #include <algorithm>
8 #include <string>
9
10 #include "base/at_exit.h"
11 #include "base/command_line.h"
12 #include "base/logging.h"
13 #include "ui/gl/gl_bindings.h"
14 #include "ui/gl/gl_gl_api_implementation.h"
15
16 namespace gfx {
17
18 namespace {
19
20 const struct {
21 const char* name;
22 GLImplementation implementation;
23 } kGLImplementationNamePairs[] = {
24 { kGLImplementationDesktopName, kGLImplementationDesktopGL },
25 { kGLImplementationOSMesaName, kGLImplementationOSMesaGL },
26 #if defined(OS_MACOSX)
27 { kGLImplementationAppleName, kGLImplementationAppleGL },
28 #endif
29 { kGLImplementationEGLName, kGLImplementationEGLGLES2 },
30 { kGLImplementationMockName, kGLImplementationMockGL }
31 };
32
33 typedef std::vector<base::NativeLibrary> LibraryArray;
34
35 GLImplementation g_gl_implementation = kGLImplementationNone;
36 LibraryArray* g_libraries;
37 GLGetProcAddressProc g_get_proc_address;
38
CleanupNativeLibraries(void * unused)39 void CleanupNativeLibraries(void* unused) {
40 if (g_libraries) {
41 // We do not call base::UnloadNativeLibrary() for these libraries as
42 // unloading libGL without closing X display is not allowed. See
43 // crbug.com/250813 for details.
44 delete g_libraries;
45 g_libraries = NULL;
46 }
47 }
48
49 }
50
51 base::ThreadLocalPointer<GLApi>* g_current_gl_context_tls = NULL;
52 OSMESAApi* g_current_osmesa_context;
53
54 #if defined(OS_WIN)
55
56 EGLApi* g_current_egl_context;
57 WGLApi* g_current_wgl_context;
58
59 #elif defined(USE_X11)
60
61 EGLApi* g_current_egl_context;
62 GLXApi* g_current_glx_context;
63
64 #elif defined(USE_OZONE)
65
66 EGLApi* g_current_egl_context;
67
68 #elif defined(OS_ANDROID)
69
70 EGLApi* g_current_egl_context;
71
72 #endif
73
GetNamedGLImplementation(const std::string & name)74 GLImplementation GetNamedGLImplementation(const std::string& name) {
75 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGLImplementationNamePairs); ++i) {
76 if (name == kGLImplementationNamePairs[i].name)
77 return kGLImplementationNamePairs[i].implementation;
78 }
79
80 return kGLImplementationNone;
81 }
82
GetGLImplementationName(GLImplementation implementation)83 const char* GetGLImplementationName(GLImplementation implementation) {
84 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGLImplementationNamePairs); ++i) {
85 if (implementation == kGLImplementationNamePairs[i].implementation)
86 return kGLImplementationNamePairs[i].name;
87 }
88
89 return "unknown";
90 }
91
SetGLImplementation(GLImplementation implementation)92 void SetGLImplementation(GLImplementation implementation) {
93 g_gl_implementation = implementation;
94 }
95
GetGLImplementation()96 GLImplementation GetGLImplementation() {
97 return g_gl_implementation;
98 }
99
HasDesktopGLFeatures()100 bool HasDesktopGLFeatures() {
101 return kGLImplementationDesktopGL == g_gl_implementation ||
102 kGLImplementationOSMesaGL == g_gl_implementation ||
103 kGLImplementationAppleGL == g_gl_implementation;
104 }
105
AddGLNativeLibrary(base::NativeLibrary library)106 void AddGLNativeLibrary(base::NativeLibrary library) {
107 DCHECK(library);
108
109 if (!g_libraries) {
110 g_libraries = new LibraryArray;
111 base::AtExitManager::RegisterCallback(CleanupNativeLibraries, NULL);
112 }
113
114 g_libraries->push_back(library);
115 }
116
UnloadGLNativeLibraries()117 void UnloadGLNativeLibraries() {
118 CleanupNativeLibraries(NULL);
119 }
120
SetGLGetProcAddressProc(GLGetProcAddressProc proc)121 void SetGLGetProcAddressProc(GLGetProcAddressProc proc) {
122 DCHECK(proc);
123 g_get_proc_address = proc;
124 }
125
GetGLProcAddress(const char * name)126 void* GetGLProcAddress(const char* name) {
127 DCHECK(g_gl_implementation != kGLImplementationNone);
128
129 if (g_libraries) {
130 for (size_t i = 0; i < g_libraries->size(); ++i) {
131 void* proc = base::GetFunctionPointerFromNativeLibrary((*g_libraries)[i],
132 name);
133 if (proc)
134 return proc;
135 }
136 }
137 if (g_get_proc_address) {
138 void* proc = g_get_proc_address(name);
139 if (proc)
140 return proc;
141 }
142
143 return NULL;
144 }
145
InitializeNullDrawGLBindings()146 void InitializeNullDrawGLBindings() {
147 // This is platform independent, so it does not need to live in a platform
148 // specific implementation file.
149 InitializeNullDrawGLBindingsGL();
150 }
151
HasInitializedNullDrawGLBindings()152 bool HasInitializedNullDrawGLBindings() {
153 return HasInitializedNullDrawGLBindingsGL();
154 }
155
DisableNullDrawGLBindings()156 DisableNullDrawGLBindings::DisableNullDrawGLBindings() {
157 initial_enabled_ = SetNullDrawGLBindingsEnabledGL(false);
158 }
159
~DisableNullDrawGLBindings()160 DisableNullDrawGLBindings::~DisableNullDrawGLBindings() {
161 SetNullDrawGLBindingsEnabledGL(initial_enabled_);
162 }
163
GLWindowSystemBindingInfo()164 GLWindowSystemBindingInfo::GLWindowSystemBindingInfo()
165 : direct_rendering(true) {}
166
167 } // namespace gfx
168