Index: ui/gl/gl_implementation_mac.cc |
diff --git a/ui/gl/gl_implementation_mac.cc b/ui/gl/gl_implementation_mac.cc |
index 25b0297d8f036533d0f4f7b8d4fb7e324ed5e852..60cb12ac99435566625a138f2ea266ba44a1fd28 100644 |
--- a/ui/gl/gl_implementation_mac.cc |
+++ b/ui/gl/gl_implementation_mac.cc |
@@ -2,15 +2,25 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "ui/gl/gl_implementation.h" |
- |
+#include "base/base_paths.h" |
#include "base/command_line.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_context_stub_with_extensions.h" |
#include "ui/gl/gl_gl_api_implementation.h" |
+#include "ui/gl/gl_implementation.h" |
#include "ui/gl/gl_osmesa_api_implementation.h" |
namespace gl { |
+namespace { |
+const char kOpenGLFrameworkPath[] = |
+ "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"; |
+} // namespace |
void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) { |
if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
@@ -20,6 +30,88 @@ |
impls->push_back(kGLImplementationDesktopGL); |
impls->push_back(kGLImplementationAppleGL); |
impls->push_back(kGLImplementationOSMesaGL); |
+} |
+ |
+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: { |
+ // 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(); |
+ break; |
+ } |
+ case kGLImplementationDesktopGL: |
+ case kGLImplementationDesktopGLCoreProfile: |
+ case kGLImplementationAppleGL: { |
+ base::NativeLibrary library = base::LoadNativeLibrary( |
+ base::FilePath(kOpenGLFrameworkPath), NULL); |
+ if (!library) { |
+ LOG(ERROR) << "OpenGL framework not found"; |
+ return false; |
+ } |
+ |
+ AddGLNativeLibrary(library); |
+ SetGLImplementation(implementation); |
+ |
+ InitializeStaticGLBindingsGL(); |
+ break; |
+ } |
+ case kGLImplementationMockGL: { |
+ SetGLImplementation(kGLImplementationMockGL); |
+ InitializeStaticGLBindingsGL(); |
+ break; |
+ } |
+ default: |
+ return false; |
+ } |
+ |
+ return true; |
} |
bool InitializeDynamicGLBindings(GLImplementation implementation, |
@@ -37,9 +129,8 @@ |
new GLContextStubWithExtensions()); |
mock_context->SetGLVersionString("3.0"); |
InitializeDynamicGLBindingsGL(mock_context.get()); |
- } else { |
+ } else |
InitializeDynamicGLBindingsGL(context); |
- } |
break; |
default: |
return false; |
@@ -48,6 +139,19 @@ |
return true; |
} |
+void InitializeDebugGLBindings() { |
+ InitializeDebugGLBindingsGL(); |
+ InitializeDebugGLBindingsOSMESA(); |
+} |
+ |
+void ClearGLBindings() { |
+ ClearGLBindingsGL(); |
+ ClearGLBindingsOSMESA(); |
+ SetGLImplementation(kGLImplementationNone); |
+ |
+ UnloadGLNativeLibraries(); |
+} |
+ |
bool GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo* info) { |
return false; |
} |