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 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 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 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 92 void SetGLImplementation(GLImplementation implementation) { 93 g_gl_implementation = implementation; 94 } 95 96 GLImplementation GetGLImplementation() { 97 return g_gl_implementation; 98 } 99 100 bool HasDesktopGLFeatures() { 101 return kGLImplementationDesktopGL == g_gl_implementation || 102 kGLImplementationOSMesaGL == g_gl_implementation || 103 kGLImplementationAppleGL == g_gl_implementation; 104 } 105 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 117 void UnloadGLNativeLibraries() { 118 CleanupNativeLibraries(NULL); 119 } 120 121 void SetGLGetProcAddressProc(GLGetProcAddressProc proc) { 122 DCHECK(proc); 123 g_get_proc_address = proc; 124 } 125 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 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 152 bool HasInitializedNullDrawGLBindings() { 153 return HasInitializedNullDrawGLBindingsGL(); 154 } 155 156 DisableNullDrawGLBindings::DisableNullDrawGLBindings() { 157 initial_enabled_ = SetNullDrawGLBindingsEnabledGL(false); 158 } 159 160 DisableNullDrawGLBindings::~DisableNullDrawGLBindings() { 161 SetNullDrawGLBindingsEnabledGL(initial_enabled_); 162 } 163 164 GLWindowSystemBindingInfo::GLWindowSystemBindingInfo() 165 : direct_rendering(true) {} 166 167 } // namespace gfx 168