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 38 void CleanupNativeLibraries(void* unused) { 39 if (g_libraries) { 40 for (LibraryArray::iterator it = g_libraries->begin(); 41 it != g_libraries->end(); ++it) { 42 base::UnloadNativeLibrary(*it); 43 } 44 delete g_libraries; 45 g_libraries = NULL; 46 } 47 } 48 49 bool ExportsCoreFunctionsFromGetProcAddress(GLImplementation implementation) { 50 switch (GetGLImplementation()) { 51 case kGLImplementationDesktopGL: 52 case kGLImplementationOSMesaGL: 53 case kGLImplementationAppleGL: 54 case kGLImplementationMockGL: 55 return true; 56 case kGLImplementationEGLGLES2: 57 return false; 58 default: 59 NOTREACHED(); 60 return true; 61 } 62 } 63 64 } 65 66 base::ThreadLocalPointer<GLApi>* g_current_gl_context_tls = NULL; 67 OSMESAApi* g_current_osmesa_context; 68 69 #if defined(OS_WIN) 70 71 EGLApi* g_current_egl_context; 72 WGLApi* g_current_wgl_context; 73 74 #elif defined(USE_X11) 75 76 EGLApi* g_current_egl_context; 77 GLXApi* g_current_glx_context; 78 79 #elif defined(USE_OZONE) 80 81 EGLApi* g_current_egl_context; 82 83 #elif defined(OS_ANDROID) 84 85 EGLApi* g_current_egl_context; 86 87 #endif 88 89 GLImplementation GetNamedGLImplementation(const std::string& name) { 90 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGLImplementationNamePairs); ++i) { 91 if (name == kGLImplementationNamePairs[i].name) 92 return kGLImplementationNamePairs[i].implementation; 93 } 94 95 return kGLImplementationNone; 96 } 97 98 const char* GetGLImplementationName(GLImplementation implementation) { 99 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGLImplementationNamePairs); ++i) { 100 if (implementation == kGLImplementationNamePairs[i].implementation) 101 return kGLImplementationNamePairs[i].name; 102 } 103 104 return "unknown"; 105 } 106 107 void SetGLImplementation(GLImplementation implementation) { 108 g_gl_implementation = implementation; 109 } 110 111 GLImplementation GetGLImplementation() { 112 return g_gl_implementation; 113 } 114 115 bool HasDesktopGLFeatures() { 116 return kGLImplementationDesktopGL == g_gl_implementation || 117 kGLImplementationOSMesaGL == g_gl_implementation || 118 kGLImplementationAppleGL == g_gl_implementation; 119 } 120 121 void AddGLNativeLibrary(base::NativeLibrary library) { 122 DCHECK(library); 123 124 if (!g_libraries) { 125 g_libraries = new LibraryArray; 126 base::AtExitManager::RegisterCallback(CleanupNativeLibraries, NULL); 127 } 128 129 g_libraries->push_back(library); 130 } 131 132 void UnloadGLNativeLibraries() { 133 CleanupNativeLibraries(NULL); 134 } 135 136 void SetGLGetProcAddressProc(GLGetProcAddressProc proc) { 137 DCHECK(proc); 138 g_get_proc_address = proc; 139 } 140 141 void* GetGLCoreProcAddress(const char* name) { 142 DCHECK(g_gl_implementation != kGLImplementationNone); 143 144 if (g_libraries) { 145 for (size_t i = 0; i < g_libraries->size(); ++i) { 146 void* proc = base::GetFunctionPointerFromNativeLibrary((*g_libraries)[i], 147 name); 148 if (proc) 149 return proc; 150 } 151 } 152 if (ExportsCoreFunctionsFromGetProcAddress(g_gl_implementation) && 153 g_get_proc_address) { 154 void* proc = g_get_proc_address(name); 155 if (proc) 156 return proc; 157 } 158 159 return NULL; 160 } 161 162 void* GetGLProcAddress(const char* name) { 163 DCHECK(g_gl_implementation != kGLImplementationNone); 164 165 void* proc = GetGLCoreProcAddress(name); 166 if (!proc && g_get_proc_address) { 167 proc = g_get_proc_address(name); 168 if (proc) 169 return proc; 170 } 171 172 return proc; 173 } 174 175 } // namespace gfx 176