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