Index: ui/gl/init/gl_initializer_mac.cc |
diff --git a/ui/gl/init/gl_initializer_mac.cc b/ui/gl/init/gl_initializer_mac.cc |
index d62a47c5b1e40b64fb55bb2c95e6513ebb65fa8e..fb07b803fa58be94e13bf944a40a90a1f18a874b 100644 |
--- a/ui/gl/init/gl_initializer_mac.cc |
+++ b/ui/gl/init/gl_initializer_mac.cc |
@@ -8,9 +8,17 @@ |
#include <vector> |
+#include "base/base_paths.h" |
+#include "base/files/file_path.h" |
#include "base/logging.h" |
+#include "base/mac/foundation_util.h" |
+#include "base/native_library.h" |
+#include "base/path_service.h" |
+#include "base/threading/thread_restrictions.h" |
#include "ui/gl/gl_bindings.h" |
+#include "ui/gl/gl_gl_api_implementation.h" |
#include "ui/gl/gl_implementation.h" |
+#include "ui/gl/gl_osmesa_api_implementation.h" |
#include "ui/gl/gl_surface.h" |
#include "ui/gl/gpu_switching_manager.h" |
@@ -19,6 +27,9 @@ namespace init { |
namespace { |
+const char kOpenGLFrameworkPath[] = |
+ "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"; |
+ |
bool InitializeOneOffForSandbox() { |
static bool initialized = false; |
if (initialized) |
@@ -57,6 +68,64 @@ bool InitializeOneOffForSandbox() { |
return true; |
} |
+bool InitializeStaticOSMesaInternal() { |
+ // osmesa.so is located in the build directory. This code path is only |
+ // valid in a developer build environment. |
+ base::FilePath exe_path; |
+ if (!PathService::Get(base::FILE_EXE, &exe_path)) { |
+ LOG(ERROR) << "PathService::Get failed."; |
+ return false; |
+ } |
+ base::FilePath bundle_path = base::mac::GetAppBundlePath(exe_path); |
+ // Some unit test targets depend on osmesa but aren't built as app |
+ // bundles. In that case, the .so is next to the executable. |
+ if (bundle_path.empty()) |
+ bundle_path = exe_path; |
+ base::FilePath build_dir_path = bundle_path.DirName(); |
+ base::FilePath osmesa_path = build_dir_path.Append("osmesa.so"); |
+ |
+ // When using OSMesa, just use OSMesaGetProcAddress to find entry points. |
+ base::NativeLibrary library = base::LoadNativeLibrary(osmesa_path, NULL); |
+ if (!library) { |
+ LOG(ERROR) << "osmesa.so not found at " << osmesa_path.value(); |
+ return false; |
+ } |
+ |
+ GLGetProcAddressProc get_proc_address = |
+ reinterpret_cast<GLGetProcAddressProc>( |
+ base::GetFunctionPointerFromNativeLibrary(library, |
+ "OSMesaGetProcAddress")); |
+ if (!get_proc_address) { |
+ LOG(ERROR) << "OSMesaGetProcAddress not found."; |
+ base::UnloadNativeLibrary(library); |
+ return false; |
+ } |
+ |
+ SetGLGetProcAddressProc(get_proc_address); |
+ AddGLNativeLibrary(library); |
+ SetGLImplementation(kGLImplementationOSMesaGL); |
+ |
+ InitializeStaticGLBindingsGL(); |
+ InitializeStaticGLBindingsOSMESA(); |
+ |
+ return true; |
+} |
+ |
+bool InitializeStaticCGLInternal(GLImplementation implementation) { |
+ base::NativeLibrary library = |
+ base::LoadNativeLibrary(base::FilePath(kOpenGLFrameworkPath), nullptr); |
+ if (!library) { |
+ LOG(ERROR) << "OpenGL framework not found"; |
+ return false; |
+ } |
+ |
+ AddGLNativeLibrary(library); |
+ SetGLImplementation(implementation); |
+ |
+ InitializeStaticGLBindingsGL(); |
+ return true; |
+} |
+ |
} // namespace |
bool InitializeGLOneOffPlatform() { |
@@ -74,5 +143,45 @@ bool InitializeGLOneOffPlatform() { |
} |
} |
+bool InitializeStaticGLBindings(GLImplementation implementation) { |
+ // Prevent reinitialization with a different implementation. Once the gpu |
+ // unit tests have initialized with kGLImplementationMock, we don't want to |
+ // later switch to another GL implementation. |
+ DCHECK_EQ(kGLImplementationNone, GetGLImplementation()); |
+ |
+ // Allow the main thread or another to initialize these bindings |
+ // after instituting restrictions on I/O. Going forward they will |
+ // likely be used in the browser process on most platforms. The |
+ // one-time initialization cost is small, between 2 and 5 ms. |
+ base::ThreadRestrictions::ScopedAllowIO allow_io; |
+ |
+ switch (implementation) { |
+ case kGLImplementationOSMesaGL: |
+ return InitializeStaticOSMesaInternal(); |
+ case kGLImplementationDesktopGL: |
+ case kGLImplementationDesktopGLCoreProfile: |
+ case kGLImplementationAppleGL: |
+ return InitializeStaticCGLInternal(implementation); |
+ case kGLImplementationMockGL: |
+ SetGLImplementation(kGLImplementationMockGL); |
+ InitializeStaticGLBindingsGL(); |
+ return true; |
+ default: |
+ NOTREACHED(); |
+ } |
+ |
+ return false; |
+} |
+ |
+void InitializeDebugGLBindings() { |
+ InitializeDebugGLBindingsGL(); |
+ InitializeDebugGLBindingsOSMESA(); |
+} |
+ |
+void ClearGLBindingsPlatform() { |
+ ClearGLBindingsGL(); |
+ ClearGLBindingsOSMESA(); |
+} |
+ |
} // namespace init |
} // namespace gl |