Move static GL binding initialization to //ui/gl/init.
Static GL binding initialization needs to call out to the Ozone
platform. Move this initialization code from //ui/gl to //ui/gl/init as
part of larger effort to break //ui/gl dep on //ui/ozone. Also move
InitializationDebugGLBindings() and ClearGLBindings() in a similar
fashion as they are closely linked to static initialization.
Unfortunately, dynamic GL binding initialization can't be moved
//ui/gl/init. It would be nice to have all the initialization code in
one target but dynamic GL binding initialization is used by GLContext.
The existing InitializationStaticGLBindings() functions had grown to be
very large for some platforms. Where appropriate the code for each
implementation has been extracted into it's own method to improve
readability.
The PRESUBMIT.py script is modified slightly here. The existing static
GL initialization uses ScopedAllowIO on some platforms. This function is
banned so moving the code triggers presubmit errors. The GPU main thread
can't continue until initialization is finished anyways so moving
blocking code to a different thread isn't helpful. Add new exemptions to
PRESUBMIT.py.
This is a resubmission of r402259. The original patch was reverted after
it broke the win Chrome branded build. The include directory for
swiftshader was missing, this CL now modifies BUILD.gn and *.gyp files
appropriately.
BUG=611142
CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_optional_gpu_tests_rel;tryserver.chromium.mac:mac_optional_gpu_tests_rel;tryserver.chromium.win:win_optional_gpu_tests_rel
Review-Url: https://codereview.chromium.org/2103123002
Cr-Commit-Position: refs/heads/master@{#403714}
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 1a3c40c..8a7c75b 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -187,10 +187,13 @@
r"^net[\\\/]url_request[\\\/]test_url_fetcher_factory\.cc$",
r"^remoting[\\\/]host[\\\/]security_key[\\\/]"
"gnubby_auth_handler_linux\.cc$",
- r"^ui[\\\/]ozone[\\\/]platform[\\\/]drm[\\\/]host[\\\/]"
- "drm_display_host_manager\.cc$",
r"^ui[\\\/]base[\\\/]material_design[\\\/]"
"material_design_controller\.cc$",
+ r"^ui[\\\/]gl[\\\/]init[\\\/]gl_initializer_mac\.cc$",
+ r"^ui[\\\/]gl[\\\/]init[\\\/]gl_initializer_win\.cc$",
+ r"^ui[\\\/]gl[\\\/]init[\\\/]gl_initializer_x11\.cc$",
+ r"^ui[\\\/]ozone[\\\/]platform[\\\/]drm[\\\/]host[\\\/]"
+ "drm_display_host_manager\.cc$",
),
),
(
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index eb27a5c3..10014934 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -26,6 +26,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_mock.h"
+#include "ui/gl/init/gl_factory.h"
#include "ui/gl/test/gl_surface_test_support.h"
using ::gl::MockGLInterface;
@@ -573,7 +574,7 @@
engine_.reset();
::gl::MockGLInterface::SetGLInterface(NULL);
gl_.reset();
- gl::ClearGLBindings();
+ gl::init::ClearGLBindings();
}
void GLES2DecoderTestBase::TearDown() {
diff --git a/gpu/command_buffer/service/gpu_service_test.cc b/gpu/command_buffer/service/gpu_service_test.cc
index c671cd7..753a8af3 100644
--- a/gpu/command_buffer/service/gpu_service_test.cc
+++ b/gpu/command_buffer/service/gpu_service_test.cc
@@ -10,6 +10,7 @@
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_mock.h"
#include "ui/gl/gl_surface_stub.h"
+#include "ui/gl/init/gl_factory.h"
#include "ui/gl/test/gl_surface_test_support.h"
namespace gpu {
@@ -50,7 +51,7 @@
surface_ = nullptr;
::gl::MockGLInterface::SetGLInterface(NULL);
gl_.reset();
- gl::ClearGLBindings();
+ gl::init::ClearGLBindings();
ran_teardown_ = true;
testing::Test::TearDown();
diff --git a/gpu/config/gpu_info_collector_unittest.cc b/gpu/config/gpu_info_collector_unittest.cc
index 1ecdae3b..c0847196 100644
--- a/gpu/config/gpu_info_collector_unittest.cc
+++ b/gpu/config/gpu_info_collector_unittest.cc
@@ -14,6 +14,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_mock.h"
+#include "ui/gl/init/gl_factory.h"
#include "ui/gl/test/gl_surface_test_support.h"
using ::gl::MockGLInterface;
@@ -167,7 +168,7 @@
void TearDown() override {
::gl::MockGLInterface::SetGLInterface(NULL);
gl_.reset();
- gl::ClearGLBindings();
+ gl::init::ClearGLBindings();
testing::Test::TearDown();
}
diff --git a/gpu/ipc/service/gpu_channel_unittest.cc b/gpu/ipc/service/gpu_channel_unittest.cc
index 4f5c447e..4ac67f67 100644
--- a/gpu/ipc/service/gpu_channel_unittest.cc
+++ b/gpu/ipc/service/gpu_channel_unittest.cc
@@ -14,6 +14,7 @@
#include "ui/gl/gl_context_stub_with_extensions.h"
#include "ui/gl/gl_mock.h"
#include "ui/gl/gl_surface_stub.h"
+#include "ui/gl/init/gl_factory.h"
#include "ui/gl/test/gl_surface_test_support.h"
namespace gpu {
@@ -135,7 +136,7 @@
stub_context_ = nullptr;
stub_surface_ = nullptr;
gl::MockGLInterface::SetGLInterface(nullptr);
- gl::ClearGLBindings();
+ gl::init::ClearGLBindings();
gl_interface_ = nullptr;
}
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn
index 5da44d496..69b94d2 100644
--- a/ui/gl/BUILD.gn
+++ b/ui/gl/BUILD.gn
@@ -127,10 +127,7 @@
configs += [ "//build/config:precompiled_headers" ]
defines = [ "GL_IMPLEMENTATION" ]
- include_dirs = [
- "//third_party/swiftshader/include",
- "//third_party/mesa/src/include",
- ]
+ include_dirs = [ "//third_party/mesa/src/include" ]
all_dependent_configs = [ ":gl_config" ]
diff --git a/ui/gl/angle_platform_impl.h b/ui/gl/angle_platform_impl.h
index 5a0ade6..99c59a6c 100644
--- a/ui/gl/angle_platform_impl.h
+++ b/ui/gl/angle_platform_impl.h
@@ -8,13 +8,15 @@
// Implements the ANGLE platform interface, for functionality like
// histograms and trace profiling.
+#include "base/compiler_specific.h"
#include "base/macros.h"
#include "third_party/angle/include/platform/Platform.h"
+#include "ui/gl/gl_export.h"
namespace gl {
// Derives the base ANGLE platform and provides implementations
-class ANGLEPlatformImpl : public angle::Platform {
+class GL_EXPORT ANGLEPlatformImpl : NON_EXPORTED_BASE(public angle::Platform) {
public:
ANGLEPlatformImpl();
~ANGLEPlatformImpl() override;
diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp
index 86cb594..aee1bab 100644
--- a/ui/gl/gl.gyp
+++ b/ui/gl/gl.gyp
@@ -26,7 +26,6 @@
'GL_IMPLEMENTATION',
],
'include_dirs': [
- '<(DEPTH)/third_party/swiftshader/include',
'<(DEPTH)/third_party/khronos',
],
'export_dependent_settings': [
diff --git a/ui/gl/gl_egl_api_implementation.cc b/ui/gl/gl_egl_api_implementation.cc
index 2a81a17..22e8f6b 100644
--- a/ui/gl/gl_egl_api_implementation.cc
+++ b/ui/gl/gl_egl_api_implementation.cc
@@ -12,6 +12,19 @@
namespace gl {
+namespace {
+
+void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
+ glClearDepthf(static_cast<GLclampf>(depth));
+}
+
+void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
+ GLclampd z_far) {
+ glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
+}
+
+} // namespace
+
RealEGLApi* g_real_egl;
void InitializeStaticGLBindingsEGL() {
@@ -22,6 +35,11 @@
g_real_egl->Initialize(&g_driver_egl);
g_current_egl_context = g_real_egl;
g_driver_egl.InitializeExtensionBindings();
+
+ // These two functions take single precision float rather than double
+ // precision float parameters in GLES.
+ ::gl::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf;
+ ::gl::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef;
}
void InitializeDebugGLBindingsEGL() {
diff --git a/ui/gl/gl_egl_api_implementation.h b/ui/gl/gl_egl_api_implementation.h
index 4f9c5f8..365feea 100644
--- a/ui/gl/gl_egl_api_implementation.h
+++ b/ui/gl/gl_egl_api_implementation.h
@@ -20,9 +20,9 @@
class GLContext;
struct GLWindowSystemBindingInfo;
-void InitializeStaticGLBindingsEGL();
-void InitializeDebugGLBindingsEGL();
-void ClearGLBindingsEGL();
+GL_EXPORT void InitializeStaticGLBindingsEGL();
+GL_EXPORT void InitializeDebugGLBindingsEGL();
+GL_EXPORT void ClearGLBindingsEGL();
bool GetGLWindowSystemBindingInfoEGL(GLWindowSystemBindingInfo* info);
class GL_EXPORT EGLApiBase : public EGLApi {
diff --git a/ui/gl/gl_gl_api_implementation.h b/ui/gl/gl_gl_api_implementation.h
index 4d8ee3f..a74e043 100644
--- a/ui/gl/gl_gl_api_implementation.h
+++ b/ui/gl/gl_gl_api_implementation.h
@@ -25,14 +25,14 @@
class GLSurface;
struct GLVersionInfo;
-void InitializeStaticGLBindingsGL();
+GL_EXPORT void InitializeStaticGLBindingsGL();
void InitializeDynamicGLBindingsGL(GLContext* context);
-void InitializeDebugGLBindingsGL();
+GL_EXPORT void InitializeDebugGLBindingsGL();
void InitializeNullDrawGLBindingsGL();
// TODO(danakj): Remove this when all test suites are using null-draw.
bool HasInitializedNullDrawGLBindingsGL();
bool SetNullDrawGLBindingsEnabledGL(bool enabled);
-void ClearGLBindingsGL();
+GL_EXPORT void ClearGLBindingsGL();
void SetGLToRealGLApi();
void SetGLApi(GLApi* api);
void SetGLApiToNoContext();
diff --git a/ui/gl/gl_glx_api_implementation.h b/ui/gl/gl_glx_api_implementation.h
index ebd80fac..67fa1a1 100644
--- a/ui/gl/gl_glx_api_implementation.h
+++ b/ui/gl/gl_glx_api_implementation.h
@@ -19,9 +19,9 @@
class GLContext;
struct GLWindowSystemBindingInfo;
-void InitializeStaticGLBindingsGLX();
-void InitializeDebugGLBindingsGLX();
-void ClearGLBindingsGLX();
+GL_EXPORT void InitializeStaticGLBindingsGLX();
+GL_EXPORT void InitializeDebugGLBindingsGLX();
+GL_EXPORT void ClearGLBindingsGLX();
bool GetGLWindowSystemBindingInfoGLX(GLWindowSystemBindingInfo* info);
class GL_EXPORT GLXApiBase : public GLXApi {
diff --git a/ui/gl/gl_implementation.h b/ui/gl/gl_implementation.h
index 7b41771..53e9600 100644
--- a/ui/gl/gl_implementation.h
+++ b/ui/gl/gl_implementation.h
@@ -46,17 +46,11 @@
typedef void* (*GLGetProcAddressProc)(const char* name);
#endif
-// Initialize a particular GL implementation.
-GL_EXPORT bool InitializeStaticGLBindings(GLImplementation implementation);
-
// Initialize function bindings that depend on the context for a GL
// implementation.
GL_EXPORT bool InitializeDynamicGLBindings(GLImplementation implementation,
GLContext* context);
-// Initialize Debug logging wrappers for GL bindings.
-GL_EXPORT void InitializeDebugGLBindings();
-
// Initialize stub methods for drawing operations in the GL bindings. The
// null draw bindings default to enabled, so that draw operations do nothing.
GL_EXPORT void InitializeNullDrawGLBindings();
@@ -82,8 +76,6 @@
bool initial_enabled_;
};
-GL_EXPORT void ClearGLBindings();
-
// Set the current GL implementation.
GL_EXPORT void SetGLImplementation(GLImplementation implementation);
@@ -101,10 +93,10 @@
GL_EXPORT const char* GetGLImplementationName(GLImplementation implementation);
// Add a native library to those searched for GL entry points.
-void AddGLNativeLibrary(base::NativeLibrary library);
+GL_EXPORT void AddGLNativeLibrary(base::NativeLibrary library);
// Unloads all native libraries.
-void UnloadGLNativeLibraries();
+GL_EXPORT void UnloadGLNativeLibraries();
// Set an additional function that will be called to find GL entry points.
// Exported so that tests may set the function used in the mock implementation.
@@ -117,7 +109,7 @@
// and when querying functions from the EGL library supplied by Android, it may
// return a function that prints a log message about the function being
// unsupported.
-void* GetGLProcAddress(const char* name);
+GL_EXPORT void* GetGLProcAddress(const char* name);
// Return information about the GL window system binding implementation (e.g.,
// EGL, GLX, WGL). Returns true if the information was retrieved successfully.
@@ -137,9 +129,10 @@
GL_EXPORT bool WillUseGLGetStringForExtensions();
// Helpers to load a library and log error on failure.
-base::NativeLibrary LoadLibraryAndPrintError(
+GL_EXPORT base::NativeLibrary LoadLibraryAndPrintError(
const base::FilePath::CharType* filename);
-base::NativeLibrary LoadLibraryAndPrintError(const base::FilePath& filename);
+GL_EXPORT base::NativeLibrary LoadLibraryAndPrintError(
+ const base::FilePath& filename);
} // namespace gl
diff --git a/ui/gl/gl_implementation_android.cc b/ui/gl/gl_implementation_android.cc
index 60baaa26..0ca23f8 100644
--- a/ui/gl/gl_implementation_android.cc
+++ b/ui/gl/gl_implementation_android.cc
@@ -2,98 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/base_paths.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
+#include "ui/gl/gl_implementation.h"
+
#include "base/logging.h"
-#include "base/native_library.h"
-#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context_stub_with_extensions.h"
#include "ui/gl/gl_egl_api_implementation.h"
#include "ui/gl/gl_gl_api_implementation.h"
-#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_implementation_osmesa.h"
#include "ui/gl/gl_osmesa_api_implementation.h"
namespace gl {
-namespace {
-
-void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
- glClearDepthf(static_cast<GLclampf>(depth));
-}
-
-void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
- GLclampd z_far) {
- glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
-}
-
-} // namespace
-
void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
impls->push_back(kGLImplementationEGLGLES2);
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());
-
- switch (implementation) {
- case kGLImplementationEGLGLES2: {
- base::NativeLibrary gles_library =
- LoadLibraryAndPrintError("libGLESv2.so");
- if (!gles_library)
- return false;
- base::NativeLibrary egl_library = LoadLibraryAndPrintError("libEGL.so");
- if (!egl_library) {
- base::UnloadNativeLibrary(gles_library);
- return false;
- }
-
- GLGetProcAddressProc get_proc_address =
- reinterpret_cast<GLGetProcAddressProc>(
- base::GetFunctionPointerFromNativeLibrary(
- egl_library, "eglGetProcAddress"));
- if (!get_proc_address) {
- LOG(ERROR) << "eglGetProcAddress not found.";
- base::UnloadNativeLibrary(egl_library);
- base::UnloadNativeLibrary(gles_library);
- return false;
- }
-
- SetGLGetProcAddressProc(get_proc_address);
- AddGLNativeLibrary(egl_library);
- AddGLNativeLibrary(gles_library);
- SetGLImplementation(kGLImplementationEGLGLES2);
-
- InitializeStaticGLBindingsGL();
- InitializeStaticGLBindingsEGL();
-
- // These two functions take single precision float rather than double
- // precision float parameters in GLES.
- ::gl::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf;
- ::gl::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef;
- break;
- }
- case kGLImplementationOSMesaGL:
- InitializeStaticGLBindingsOSMesaGL();
- break;
- case kGLImplementationMockGL: {
- SetGLImplementation(kGLImplementationMockGL);
- InitializeStaticGLBindingsGL();
- break;
- }
- default:
- NOTIMPLEMENTED() << "InitializeStaticGLBindings on Android";
- return false;
- }
-
- return true;
-}
-
bool InitializeDynamicGLBindings(GLImplementation implementation,
GLContext* context) {
switch (implementation) {
@@ -107,8 +31,9 @@
new GLContextStubWithExtensions());
mock_context->SetGLVersionString("opengl es 3.0");
InitializeDynamicGLBindingsGL(mock_context.get());
- } else
+ } else {
InitializeDynamicGLBindingsGL(context);
+ }
break;
default:
NOTREACHED() << "InitializeDynamicGLBindings on Android";
@@ -118,21 +43,6 @@
return true;
}
-void InitializeDebugGLBindings() {
- InitializeDebugGLBindingsEGL();
- InitializeDebugGLBindingsGL();
- InitializeDebugGLBindingsOSMESA();
-}
-
-void ClearGLBindings() {
- ClearGLBindingsEGL();
- ClearGLBindingsGL();
- ClearGLBindingsOSMESA();
- SetGLImplementation(kGLImplementationNone);
-
- UnloadGLNativeLibraries();
-}
-
bool GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo* info) {
switch (GetGLImplementation()) {
case kGLImplementationEGLGLES2:
diff --git a/ui/gl/gl_implementation_mac.cc b/ui/gl/gl_implementation_mac.cc
index 60cb12a..25b0297 100644
--- a/ui/gl/gl_implementation_mac.cc
+++ b/ui/gl/gl_implementation_mac.cc
@@ -2,25 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/base_paths.h"
+#include "ui/gl/gl_implementation.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(
@@ -32,88 +22,6 @@
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,
GLContext* context) {
switch (implementation) {
@@ -129,8 +37,9 @@
new GLContextStubWithExtensions());
mock_context->SetGLVersionString("3.0");
InitializeDynamicGLBindingsGL(mock_context.get());
- } else
+ } else {
InitializeDynamicGLBindingsGL(context);
+ }
break;
default:
return false;
@@ -139,19 +48,6 @@
return true;
}
-void InitializeDebugGLBindings() {
- InitializeDebugGLBindingsGL();
- InitializeDebugGLBindingsOSMESA();
-}
-
-void ClearGLBindings() {
- ClearGLBindingsGL();
- ClearGLBindingsOSMESA();
- SetGLImplementation(kGLImplementationNone);
-
- UnloadGLNativeLibraries();
-}
-
bool GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo* info) {
return false;
}
diff --git a/ui/gl/gl_implementation_osmesa.h b/ui/gl/gl_implementation_osmesa.h
index c4bc839..ba08e3f 100644
--- a/ui/gl/gl_implementation_osmesa.h
+++ b/ui/gl/gl_implementation_osmesa.h
@@ -2,16 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_GL_GL_IMPLEMENTATION_OSMESA_
-#define UI_GL_GL_IMPLEMENTATION_OSMESA_
+#ifndef UI_GL_GL_IMPLEMENTATION_OSMESA_H_
+#define UI_GL_GL_IMPLEMENTATION_OSMESA_H_
#include "base/files/file_path.h"
#include "base/native_library.h"
+#include "ui/gl/gl_export.h"
namespace gl {
-bool InitializeStaticGLBindingsOSMesaGL();
+GL_EXPORT bool InitializeStaticGLBindingsOSMesaGL();
} // namespace gl
-#endif // UI_GL_GL_IMPLEMENTATION_OSMESA_
+#endif // UI_GL_GL_IMPLEMENTATION_OSMESA_H_
diff --git a/ui/gl/gl_implementation_ozone.cc b/ui/gl/gl_implementation_ozone.cc
index 67812bb..2564c1a 100644
--- a/ui/gl/gl_implementation_ozone.cc
+++ b/ui/gl/gl_implementation_ozone.cc
@@ -2,76 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/bind.h"
-#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_implementation.h"
+
#include "ui/gl/gl_context_stub_with_extensions.h"
#include "ui/gl/gl_egl_api_implementation.h"
#include "ui/gl/gl_gl_api_implementation.h"
-#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_implementation_osmesa.h"
#include "ui/gl/gl_osmesa_api_implementation.h"
-#include "ui/ozone/public/ozone_platform.h"
-#include "ui/ozone/public/surface_factory_ozone.h"
namespace gl {
-namespace {
-
-void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
- glClearDepthf(static_cast<GLclampf>(depth));
-}
-
-void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
- GLclampd z_far) {
- glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
-}
-
-} // namespace
-
void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
impls->push_back(kGLImplementationEGLGLES2);
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());
- ui::OzonePlatform::InitializeForGPU();
-
- switch (implementation) {
- case kGLImplementationOSMesaGL:
- return InitializeStaticGLBindingsOSMesaGL();
- case kGLImplementationEGLGLES2:
- if (!ui::OzonePlatform::GetInstance()
- ->GetSurfaceFactoryOzone()
- ->LoadEGLGLES2Bindings(base::Bind(&AddGLNativeLibrary),
- base::Bind(&SetGLGetProcAddressProc)))
- return false;
- SetGLImplementation(kGLImplementationEGLGLES2);
- InitializeStaticGLBindingsGL();
- InitializeStaticGLBindingsEGL();
-
- // These two functions take single precision float rather than double
- // precision float parameters in GLES.
- ::gl::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf;
- ::gl::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef;
- break;
- case kGLImplementationMockGL: {
- SetGLImplementation(kGLImplementationMockGL);
- InitializeStaticGLBindingsGL();
- break;
- }
- default:
- NOTIMPLEMENTED()
- << "Unsupported GL type for Ozone surface implementation";
- return false;
- }
-
- return true;
-}
-
bool InitializeDynamicGLBindings(GLImplementation implementation,
GLContext* context) {
switch (implementation) {
@@ -96,20 +41,6 @@
return true;
}
-void InitializeDebugGLBindings() {
- InitializeDebugGLBindingsEGL();
- InitializeDebugGLBindingsGL();
- InitializeDebugGLBindingsOSMESA();
-}
-
-void ClearGLBindings() {
- ClearGLBindingsEGL();
- ClearGLBindingsGL();
- ClearGLBindingsOSMESA();
- SetGLImplementation(kGLImplementationNone);
- UnloadGLNativeLibraries();
-}
-
bool GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo* info) {
switch (GetGLImplementation()) {
case kGLImplementationEGLGLES2:
diff --git a/ui/gl/gl_implementation_win.cc b/ui/gl/gl_implementation_win.cc
index 4b1db596..9a470c9 100644
--- a/ui/gl/gl_implementation_win.cc
+++ b/ui/gl/gl_implementation_win.cc
@@ -2,300 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <vector>
+#include "ui/gl/gl_implementation.h"
-#include "base/at_exit.h"
-#include "base/base_paths.h"
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/native_library.h"
-#include "base/path_service.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/thread_restrictions.h"
-#include "base/trace_event/trace_event.h"
-#include "base/win/windows_version.h"
-// TODO(jmadill): Apply to all platforms eventually
-#include "ui/gl/angle_platform_impl.h"
-#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context_stub_with_extensions.h"
#include "ui/gl/gl_egl_api_implementation.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_wgl.h"
#include "ui/gl/gl_wgl_api_implementation.h"
-#if defined(ENABLE_SWIFTSHADER)
-#include "software_renderer.h"
-#endif
-
namespace gl {
-namespace {
-
-const wchar_t kD3DCompiler[] = L"D3DCompiler_47.dll";
-
-void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
- glClearDepthf(static_cast<GLclampf>(depth));
-}
-
-void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
- GLclampd z_far) {
- glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
-}
-
-bool LoadD3DXLibrary(const base::FilePath& module_path,
- const base::FilePath::StringType& name) {
- base::NativeLibrary library =
- base::LoadNativeLibrary(base::FilePath(name), NULL);
- if (!library) {
- library = base::LoadNativeLibrary(module_path.Append(name), NULL);
- if (!library) {
- DVLOG(1) << name << " not found.";
- return false;
- }
- }
- return true;
-}
-
-// TODO(jmadill): Apply to all platforms eventually
-base::LazyInstance<ANGLEPlatformImpl> g_angle_platform_impl =
- LAZY_INSTANCE_INITIALIZER;
-
-ANGLEPlatformShutdownFunc g_angle_platform_shutdown = nullptr;
-
-} // namespace
-
void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
impls->push_back(kGLImplementationEGLGLES2);
impls->push_back(kGLImplementationDesktopGL);
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: {
- base::FilePath module_path;
- PathService::Get(base::DIR_MODULE, &module_path);
- base::NativeLibrary library = base::LoadNativeLibrary(
- module_path.Append(L"osmesa.dll"), NULL);
- if (!library) {
- PathService::Get(base::DIR_EXE, &module_path);
- library = base::LoadNativeLibrary(
- module_path.Append(L"osmesa.dll"), NULL);
- if (!library) {
- DVLOG(1) << "osmesa.dll not found";
- return false;
- }
- }
-
- GLGetProcAddressProc get_proc_address =
- reinterpret_cast<GLGetProcAddressProc>(
- base::GetFunctionPointerFromNativeLibrary(
- library, "OSMesaGetProcAddress"));
- if (!get_proc_address) {
- DLOG(ERROR) << "OSMesaGetProcAddress not found.";
- base::UnloadNativeLibrary(library);
- return false;
- }
-
- SetGLGetProcAddressProc(get_proc_address);
- AddGLNativeLibrary(library);
- SetGLImplementation(kGLImplementationOSMesaGL);
-
- InitializeStaticGLBindingsGL();
- InitializeStaticGLBindingsOSMESA();
- break;
- }
- case kGLImplementationEGLGLES2: {
- base::FilePath module_path;
- if (!PathService::Get(base::DIR_MODULE, &module_path))
- return false;
-
- // Attempt to load the D3DX shader compiler using the default search path
- // and if that fails, using an absolute path. This is to ensure these DLLs
- // are loaded before ANGLE is loaded in case they are not in the default
- // search path.
- LoadD3DXLibrary(module_path, kD3DCompiler);
-
- base::FilePath gles_path;
- const base::CommandLine* command_line =
- base::CommandLine::ForCurrentProcess();
- bool using_swift_shader =
- command_line->GetSwitchValueASCII(switches::kUseGL) ==
- kGLImplementationSwiftShaderName;
- if (using_swift_shader) {
- if (!command_line->HasSwitch(switches::kSwiftShaderPath))
- return false;
- gles_path =
- command_line->GetSwitchValuePath(switches::kSwiftShaderPath);
- // Preload library
- LoadLibrary(L"ddraw.dll");
- } else {
- gles_path = module_path;
- }
-
- // Load libglesv2.dll before libegl.dll because the latter is dependent on
- // the former and if there is another version of libglesv2.dll in the dll
- // search path, it will get loaded instead.
- base::NativeLibrary gles_library = base::LoadNativeLibrary(
- gles_path.Append(L"libglesv2.dll"), NULL);
- if (!gles_library) {
- DVLOG(1) << "libglesv2.dll not found";
- return false;
- }
-
- // When using EGL, first try eglGetProcAddress and then Windows
- // GetProcAddress on both the EGL and GLES2 DLLs.
- base::NativeLibrary egl_library = base::LoadNativeLibrary(
- gles_path.Append(L"libegl.dll"), NULL);
- if (!egl_library) {
- DVLOG(1) << "libegl.dll not found.";
- base::UnloadNativeLibrary(gles_library);
- return false;
- }
-
-#if defined(ENABLE_SWIFTSHADER)
- if (using_swift_shader) {
- SetupSoftwareRenderer(gles_library);
- }
-#endif
-
- if (!using_swift_shader) {
- // Init ANGLE platform here, before we call GetPlatformDisplay().
- // TODO(jmadill): Apply to all platforms eventually
- ANGLEPlatformInitializeFunc angle_platform_init =
- reinterpret_cast<ANGLEPlatformInitializeFunc>(
- base::GetFunctionPointerFromNativeLibrary(
- gles_library,
- "ANGLEPlatformInitialize"));
- if (angle_platform_init) {
- angle_platform_init(&g_angle_platform_impl.Get());
-
- g_angle_platform_shutdown =
- reinterpret_cast<ANGLEPlatformShutdownFunc>(
- base::GetFunctionPointerFromNativeLibrary(
- gles_library,
- "ANGLEPlatformShutdown"));
- }
- }
-
- GLGetProcAddressProc get_proc_address =
- reinterpret_cast<GLGetProcAddressProc>(
- base::GetFunctionPointerFromNativeLibrary(
- egl_library, "eglGetProcAddress"));
- if (!get_proc_address) {
- LOG(ERROR) << "eglGetProcAddress not found.";
- base::UnloadNativeLibrary(egl_library);
- base::UnloadNativeLibrary(gles_library);
- return false;
- }
-
- SetGLGetProcAddressProc(get_proc_address);
- AddGLNativeLibrary(egl_library);
- AddGLNativeLibrary(gles_library);
- SetGLImplementation(kGLImplementationEGLGLES2);
-
- InitializeStaticGLBindingsGL();
- InitializeStaticGLBindingsEGL();
-
- // These two functions take single precision float rather than double
- // precision float parameters in GLES.
- ::gl::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf;
- ::gl::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef;
- break;
- }
- case kGLImplementationDesktopGL: {
- base::NativeLibrary library = base::LoadNativeLibrary(
- base::FilePath(L"opengl32.dll"), NULL);
- if (!library) {
- DVLOG(1) << "opengl32.dll not found";
- return false;
- }
-
- GLGetProcAddressProc get_proc_address =
- reinterpret_cast<GLGetProcAddressProc>(
- base::GetFunctionPointerFromNativeLibrary(
- library, "wglGetProcAddress"));
- if (!get_proc_address) {
- LOG(ERROR) << "wglGetProcAddress not found.";
- base::UnloadNativeLibrary(library);
- return false;
- }
-
- SetGLGetProcAddressProc(get_proc_address);
- AddGLNativeLibrary(library);
- SetGLImplementation(kGLImplementationDesktopGL);
-
- // Initialize GL surface and get some functions needed for the context
- // creation below.
- if (!GLSurfaceWGL::InitializeOneOff()) {
- LOG(ERROR) << "GLSurfaceWGL::InitializeOneOff failed.";
- return false;
- }
- wglCreateContextProc wglCreateContextFn =
- reinterpret_cast<wglCreateContextProc>(
- GetGLProcAddress("wglCreateContext"));
- wglDeleteContextProc wglDeleteContextFn =
- reinterpret_cast<wglDeleteContextProc>(
- GetGLProcAddress("wglDeleteContext"));
- wglMakeCurrentProc wglMakeCurrentFn =
- reinterpret_cast<wglMakeCurrentProc>(
- GetGLProcAddress("wglMakeCurrent"));
-
- // Create a temporary GL context to bind to entry points. This is needed
- // because wglGetProcAddress is specified to return NULL for all queries
- // if a context is not current in MSDN documentation, and the static
- // bindings may contain functions that need to be queried with
- // wglGetProcAddress. OpenGL wiki further warns that other error values
- // than NULL could also be returned from wglGetProcAddress on some
- // implementations, so we need to clear the WGL bindings and reinitialize
- // them after the context creation.
- HGLRC gl_context = wglCreateContextFn(GLSurfaceWGL::GetDisplayDC());
- if (!gl_context) {
- LOG(ERROR) << "Failed to create temporary context.";
- return false;
- }
- if (!wglMakeCurrentFn(GLSurfaceWGL::GetDisplayDC(), gl_context)) {
- LOG(ERROR) << "Failed to make temporary GL context current.";
- wglDeleteContextFn(gl_context);
- return false;
- }
-
- InitializeStaticGLBindingsGL();
- InitializeStaticGLBindingsWGL();
-
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(gl_context);
-
- break;
- }
- case kGLImplementationMockGL: {
- SetGLImplementation(kGLImplementationMockGL);
- InitializeStaticGLBindingsGL();
- break;
- }
- default:
- return false;
- }
-
- return true;
-}
-
bool InitializeDynamicGLBindings(GLImplementation implementation,
GLContext* context) {
switch (implementation) {
@@ -310,8 +32,9 @@
new GLContextStubWithExtensions());
mock_context->SetGLVersionString("3.0");
InitializeDynamicGLBindingsGL(mock_context.get());
- } else
+ } else {
InitializeDynamicGLBindingsGL(context);
+ }
break;
default:
return false;
@@ -320,27 +43,6 @@
return true;
}
-void InitializeDebugGLBindings() {
- InitializeDebugGLBindingsEGL();
- InitializeDebugGLBindingsGL();
- InitializeDebugGLBindingsOSMESA();
- InitializeDebugGLBindingsWGL();
-}
-
-void ClearGLBindings() {
- // TODO(jmadill): Apply to all platforms eventually
- if (g_angle_platform_shutdown) {
- g_angle_platform_shutdown();
- }
-
- ClearGLBindingsEGL();
- ClearGLBindingsGL();
- ClearGLBindingsOSMESA();
- ClearGLBindingsWGL();
- SetGLImplementation(kGLImplementationNone);
- UnloadGLNativeLibraries();
-}
-
bool GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo* info) {
switch (GetGLImplementation()) {
case kGLImplementationDesktopGL:
diff --git a/ui/gl/gl_implementation_x11.cc b/ui/gl/gl_implementation_x11.cc
index 776bb2d4..de19d716 100644
--- a/ui/gl/gl_implementation_x11.cc
+++ b/ui/gl/gl_implementation_x11.cc
@@ -2,50 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <vector>
+#include "ui/gl/gl_implementation.h"
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/path_service.h"
-#include "base/threading/thread_restrictions.h"
-#include "build/build_config.h"
-#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context_stub_with_extensions.h"
#include "ui/gl/gl_egl_api_implementation.h"
#include "ui/gl/gl_gl_api_implementation.h"
#include "ui/gl/gl_glx_api_implementation.h"
-#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_implementation_osmesa.h"
#include "ui/gl/gl_osmesa_api_implementation.h"
-#include "ui/gl/gl_switches.h"
namespace gl {
-namespace {
-
-// TODO(piman): it should be Desktop GL marshalling from double to float. Today
-// on native GLES, we do float->double->float.
-void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
- glClearDepthf(static_cast<GLclampf>(depth));
-}
-
-void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
- GLclampd z_far) {
- glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
-}
-
-#if defined(OS_OPENBSD)
-const char kGLLibraryName[] = "libGL.so";
-#else
-const char kGLLibraryName[] = "libGL.so.1";
-#endif
-
-const char kGLESv2LibraryName[] = "libGLESv2.so.2";
-const char kEGLLibraryName[] = "libEGL.so.1";
-
-const char kGLESv2ANGLELibraryName[] = "libGLESv2.so";
-const char kEGLANGLELibraryName[] = "libEGL.so";
-
-} // namespace
void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
impls->push_back(kGLImplementationDesktopGL);
@@ -53,123 +19,11 @@
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:
- return InitializeStaticGLBindingsOSMesaGL();
- case kGLImplementationDesktopGL: {
- base::NativeLibrary library = NULL;
- const base::CommandLine* command_line =
- base::CommandLine::ForCurrentProcess();
-
- if (command_line->HasSwitch(switches::kTestGLLib))
- library = LoadLibraryAndPrintError(
- command_line->GetSwitchValueASCII(switches::kTestGLLib).c_str());
-
- if (!library) {
- library = LoadLibraryAndPrintError(kGLLibraryName);
- }
-
- if (!library)
- return false;
-
- GLGetProcAddressProc get_proc_address =
- reinterpret_cast<GLGetProcAddressProc>(
- base::GetFunctionPointerFromNativeLibrary(
- library, "glXGetProcAddress"));
- if (!get_proc_address) {
- LOG(ERROR) << "glxGetProcAddress not found.";
- base::UnloadNativeLibrary(library);
- return false;
- }
-
- SetGLGetProcAddressProc(get_proc_address);
- AddGLNativeLibrary(library);
- SetGLImplementation(kGLImplementationDesktopGL);
-
- InitializeStaticGLBindingsGL();
- InitializeStaticGLBindingsGLX();
- break;
- }
- case kGLImplementationEGLGLES2: {
- base::FilePath glesv2_path(kGLESv2LibraryName);
- base::FilePath egl_path(kEGLLibraryName);
-
- const base::CommandLine* command_line =
- base::CommandLine::ForCurrentProcess();
- if (command_line->GetSwitchValueASCII(switches::kUseGL) ==
- kGLImplementationANGLEName) {
- base::FilePath module_path;
- if (!PathService::Get(base::DIR_MODULE, &module_path))
- return false;
-
- glesv2_path = module_path.Append(kGLESv2ANGLELibraryName);
- egl_path = module_path.Append(kEGLANGLELibraryName);
- }
-
- base::NativeLibrary gles_library = LoadLibraryAndPrintError(glesv2_path);
- if (!gles_library)
- return false;
- base::NativeLibrary egl_library = LoadLibraryAndPrintError(egl_path);
- if (!egl_library) {
- base::UnloadNativeLibrary(gles_library);
- return false;
- }
-
- GLGetProcAddressProc get_proc_address =
- reinterpret_cast<GLGetProcAddressProc>(
- base::GetFunctionPointerFromNativeLibrary(
- egl_library, "eglGetProcAddress"));
- if (!get_proc_address) {
- LOG(ERROR) << "eglGetProcAddress not found.";
- base::UnloadNativeLibrary(egl_library);
- base::UnloadNativeLibrary(gles_library);
- return false;
- }
-
- SetGLGetProcAddressProc(get_proc_address);
- AddGLNativeLibrary(egl_library);
- AddGLNativeLibrary(gles_library);
- SetGLImplementation(kGLImplementationEGLGLES2);
-
- InitializeStaticGLBindingsGL();
- InitializeStaticGLBindingsEGL();
-
- // These two functions take single precision float rather than double
- // precision float parameters in GLES.
- ::gl::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf;
- ::gl::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef;
- break;
- }
- case kGLImplementationMockGL: {
- SetGLImplementation(kGLImplementationMockGL);
- InitializeStaticGLBindingsGL();
- break;
- }
- default:
- return false;
- }
-
-
- return true;
-}
-
bool InitializeDynamicGLBindings(GLImplementation implementation,
GLContext* context) {
switch (implementation) {
case kGLImplementationOSMesaGL:
- case kGLImplementationDesktopGL:
+ case kGLImplementationDesktopGL:
case kGLImplementationEGLGLES2:
InitializeDynamicGLBindingsGL(context);
break;
@@ -179,8 +33,9 @@
new GLContextStubWithExtensions());
mock_context->SetGLVersionString("3.0");
InitializeDynamicGLBindingsGL(mock_context.get());
- } else
+ } else {
InitializeDynamicGLBindingsGL(context);
+ }
break;
default:
return false;
@@ -189,23 +44,6 @@
return true;
}
-void InitializeDebugGLBindings() {
- InitializeDebugGLBindingsEGL();
- InitializeDebugGLBindingsGL();
- InitializeDebugGLBindingsGLX();
- InitializeDebugGLBindingsOSMESA();
-}
-
-void ClearGLBindings() {
- ClearGLBindingsEGL();
- ClearGLBindingsGL();
- ClearGLBindingsGLX();
- ClearGLBindingsOSMESA();
- SetGLImplementation(kGLImplementationNone);
-
- UnloadGLNativeLibraries();
-}
-
bool GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo* info) {
switch (GetGLImplementation()) {
case kGLImplementationDesktopGL:
diff --git a/ui/gl/gl_osmesa_api_implementation.h b/ui/gl/gl_osmesa_api_implementation.h
index 049db0b..cbda433 100644
--- a/ui/gl/gl_osmesa_api_implementation.h
+++ b/ui/gl/gl_osmesa_api_implementation.h
@@ -13,9 +13,9 @@
class GLContext;
-void InitializeStaticGLBindingsOSMESA();
-void InitializeDebugGLBindingsOSMESA();
-void ClearGLBindingsOSMESA();
+GL_EXPORT void InitializeStaticGLBindingsOSMESA();
+GL_EXPORT void InitializeDebugGLBindingsOSMESA();
+GL_EXPORT void ClearGLBindingsOSMESA();
class GL_EXPORT OSMESAApiBase : public OSMESAApi {
public:
diff --git a/ui/gl/gl_wgl_api_implementation.h b/ui/gl/gl_wgl_api_implementation.h
index ffaaff57..d18da03 100644
--- a/ui/gl/gl_wgl_api_implementation.h
+++ b/ui/gl/gl_wgl_api_implementation.h
@@ -19,9 +19,9 @@
class GLContext;
struct GLWindowSystemBindingInfo;
-void InitializeStaticGLBindingsWGL();
-void InitializeDebugGLBindingsWGL();
-void ClearGLBindingsWGL();
+GL_EXPORT void InitializeStaticGLBindingsWGL();
+GL_EXPORT void InitializeDebugGLBindingsWGL();
+GL_EXPORT void ClearGLBindingsWGL();
bool GetGLWindowSystemBindingInfoWGL(GLWindowSystemBindingInfo* info);
class GL_EXPORT WGLApiBase : public WGLApi {
diff --git a/ui/gl/gpu_timing_unittest.cc b/ui/gl/gpu_timing_unittest.cc
index 8876816..18e2622 100644
--- a/ui/gl/gpu_timing_unittest.cc
+++ b/ui/gl/gpu_timing_unittest.cc
@@ -16,6 +16,7 @@
#include "ui/gl/gl_surface_stub.h"
#include "ui/gl/gpu_preference.h"
#include "ui/gl/gpu_timing_fake.h"
+#include "ui/gl/init/gl_factory.h"
#include "ui/gl/test/gl_surface_test_support.h"
namespace gl {
@@ -38,7 +39,7 @@
surface_ = nullptr;
if (setup_) {
MockGLInterface::SetGLInterface(NULL);
- ClearGLBindings();
+ init::ClearGLBindings();
}
setup_ = false;
cpu_time_bounded_ = false;
diff --git a/ui/gl/init/BUILD.gn b/ui/gl/init/BUILD.gn
index 2a0eb6d..6786159 100644
--- a/ui/gl/init/BUILD.gn
+++ b/ui/gl/init/BUILD.gn
@@ -18,6 +18,8 @@
]
defines = [ "GL_INIT_IMPLEMENTATION" ]
+ include_dirs = [ "//third_party/swiftshader/include" ]
+
deps = [
"//base",
"//ui/gfx",
diff --git a/ui/gl/init/gl_factory.cc b/ui/gl/init/gl_factory.cc
index bab99ea..85332096 100644
--- a/ui/gl/init/gl_factory.cc
+++ b/ui/gl/init/gl_factory.cc
@@ -83,5 +83,12 @@
return initialized;
}
+void ClearGLBindings() {
+ ClearGLBindingsPlatform();
+
+ SetGLImplementation(kGLImplementationNone);
+ UnloadGLNativeLibraries();
+}
+
} // namespace init
} // namespace gl
diff --git a/ui/gl/init/gl_factory.h b/ui/gl/init/gl_factory.h
index ed11462..1164601 100644
--- a/ui/gl/init/gl_factory.h
+++ b/ui/gl/init/gl_factory.h
@@ -20,30 +20,33 @@
namespace init {
-// Initialize GL bindings.
+// Initializes GL bindings.
GL_INIT_EXPORT bool InitializeGLOneOff();
-// Initialize GL bindings using the provided parameters. This might be required
+// Initializes GL bindings using the provided parameters. This might be required
// for use in tests, otherwise use InitializeGLOneOff() instead.
GL_INIT_EXPORT bool InitializeGLOneOffImplementation(GLImplementation impl,
bool fallback_to_osmesa,
bool gpu_service_logging,
bool disable_gl_drawing);
-// Create a GL context that is compatible with the given surface. |share_group|,
-// if non-NULL, is a group of contexts which the internally created OpenGL
-// context shares textures and other resources.
+// Clears GL bindings and resets GL implementation.
+GL_INIT_EXPORT void ClearGLBindings();
+
+// Creates a GL context that is compatible with the given surface.
+// |share_group|, if non-NULL, is a group of contexts which the internally
+// created OpenGL context shares textures and other resources.
GL_INIT_EXPORT scoped_refptr<GLContext> CreateGLContext(
GLShareGroup* share_group,
GLSurface* compatible_surface,
GpuPreference gpu_preference);
-// Create a GL surface that renders directly to a view.
+// Creates a GL surface that renders directly to a view.
GL_INIT_EXPORT scoped_refptr<GLSurface> CreateViewGLSurface(
gfx::AcceleratedWidget window);
#if defined(USE_OZONE)
-// Create a GL surface that renders directly into a window with surfaceless
+// Creates a GL surface that renders directly into a window with surfaceless
// semantics - there is no default framebuffer and the primary surface must
// be presented as an overlay. If surfaceless mode is not supported or
// enabled it will return a null pointer.
@@ -51,7 +54,7 @@
gfx::AcceleratedWidget window);
#endif // defined(USE_OZONE)
-// Create a GL surface used for offscreen rendering.
+// Creates a GL surface used for offscreen rendering.
GL_INIT_EXPORT scoped_refptr<GLSurface> CreateOffscreenGLSurface(
const gfx::Size& size);
diff --git a/ui/gl/init/gl_init.gyp b/ui/gl/init/gl_init.gyp
index bd67c2c8..b9cd506 100644
--- a/ui/gl/init/gl_init.gyp
+++ b/ui/gl/init/gl_init.gyp
@@ -20,6 +20,9 @@
'defines': [
'GL_INIT_IMPLEMENTATION',
],
+ 'include_dirs': [
+ '<(DEPTH)/third_party/swiftshader/include',
+ ],
'sources': [
'gl_initializer.h',
'gl_initializer_android.cc',
diff --git a/ui/gl/init/gl_initializer.h b/ui/gl/init/gl_initializer.h
index de057f5..b50adbf 100644
--- a/ui/gl/init/gl_initializer.h
+++ b/ui/gl/init/gl_initializer.h
@@ -5,15 +5,26 @@
#ifndef UI_GL_INIT_GL_INITIALIZER_H_
#define UI_GL_INIT_GL_INITIALIZER_H_
+#include "ui/gl/gl_implementation.h"
+
namespace gl {
namespace init {
// Performs platform dependent one-off GL initialization, calling into the
// appropriate GLSurface code to initialize it. To perform one-off GL
// initialization you should use InitializeGLOneOff() or for tests possibly
-// InitializeGLOneOffImplementation() instead of this.
+// InitializeGLOneOffImplementation() instead.
bool InitializeGLOneOffPlatform();
+// Initializes a particular GL implementation.
+bool InitializeStaticGLBindings(GLImplementation implementation);
+
+// Initializes debug logging wrappers for GL bindings.
+void InitializeDebugGLBindings();
+
+// Clears GL bindings for all implementations supported by platform.
+void ClearGLBindingsPlatform();
+
} // namespace init
} // namespace gl
diff --git a/ui/gl/init/gl_initializer_android.cc b/ui/gl/init/gl_initializer_android.cc
index 7d7a88e38..9091fc0 100644
--- a/ui/gl/init/gl_initializer_android.cc
+++ b/ui/gl/init/gl_initializer_android.cc
@@ -4,13 +4,57 @@
#include "ui/gl/init/gl_initializer.h"
+#include "base/base_paths.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
#include "base/logging.h"
-#include "ui/gl/gl_implementation.h"
+#include "base/native_library.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_egl_api_implementation.h"
+#include "ui/gl/gl_gl_api_implementation.h"
+#include "ui/gl/gl_implementation_osmesa.h"
+#include "ui/gl/gl_osmesa_api_implementation.h"
#include "ui/gl/gl_surface_egl.h"
namespace gl {
namespace init {
+namespace {
+
+bool InitializeStaticEGLInternal() {
+ base::NativeLibrary gles_library = LoadLibraryAndPrintError("libGLESv2.so");
+ if (!gles_library)
+ return false;
+ base::NativeLibrary egl_library = LoadLibraryAndPrintError("libEGL.so");
+ if (!egl_library) {
+ base::UnloadNativeLibrary(gles_library);
+ return false;
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(egl_library,
+ "eglGetProcAddress"));
+ if (!get_proc_address) {
+ LOG(ERROR) << "eglGetProcAddress not found.";
+ base::UnloadNativeLibrary(egl_library);
+ base::UnloadNativeLibrary(gles_library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(egl_library);
+ AddGLNativeLibrary(gles_library);
+ SetGLImplementation(kGLImplementationEGLGLES2);
+
+ InitializeStaticGLBindingsGL();
+ InitializeStaticGLBindingsEGL();
+
+ return true;
+}
+
+} // namespace
+
bool InitializeGLOneOffPlatform() {
switch (GetGLImplementation()) {
case kGLImplementationEGLGLES2:
@@ -24,5 +68,39 @@
}
}
+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());
+
+ switch (implementation) {
+ case kGLImplementationEGLGLES2:
+ return InitializeStaticEGLInternal();
+ case kGLImplementationOSMesaGL:
+ return InitializeStaticGLBindingsOSMesaGL();
+ case kGLImplementationMockGL:
+ SetGLImplementation(kGLImplementationMockGL);
+ InitializeStaticGLBindingsGL();
+ return true;
+ default:
+ NOTREACHED();
+ }
+
+ return false;
+}
+
+void InitializeDebugGLBindings() {
+ InitializeDebugGLBindingsEGL();
+ InitializeDebugGLBindingsGL();
+ InitializeDebugGLBindingsOSMESA();
+}
+
+void ClearGLBindingsPlatform() {
+ ClearGLBindingsEGL();
+ ClearGLBindingsGL();
+ ClearGLBindingsOSMESA();
+}
+
} // namespace init
} // namespace gl
diff --git a/ui/gl/init/gl_initializer_mac.cc b/ui/gl/init/gl_initializer_mac.cc
index d62a47c5b..fb07b80 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 {
+const char kOpenGLFrameworkPath[] =
+ "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL";
+
bool InitializeOneOffForSandbox() {
static bool initialized = false;
if (initialized)
@@ -57,6 +68,64 @@
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 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
diff --git a/ui/gl/init/gl_initializer_ozone.cc b/ui/gl/init/gl_initializer_ozone.cc
index acaaf82..d53f344 100644
--- a/ui/gl/init/gl_initializer_ozone.cc
+++ b/ui/gl/init/gl_initializer_ozone.cc
@@ -4,13 +4,40 @@
#include "ui/gl/init/gl_initializer.h"
+#include "base/bind.h"
#include "base/logging.h"
-#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_egl_api_implementation.h"
+#include "ui/gl/gl_gl_api_implementation.h"
+#include "ui/gl/gl_implementation_osmesa.h"
+#include "ui/gl/gl_osmesa_api_implementation.h"
#include "ui/gl/gl_surface_egl.h"
+#include "ui/ozone/public/ozone_platform.h"
+#include "ui/ozone/public/surface_factory_ozone.h"
namespace gl {
namespace init {
+namespace {
+
+bool InitializeStaticEGLInternal() {
+ auto surface_factory =
+ ui::OzonePlatform::GetInstance()->GetSurfaceFactoryOzone();
+ if (!surface_factory->LoadEGLGLES2Bindings(
+ base::Bind(&AddGLNativeLibrary),
+ base::Bind(&SetGLGetProcAddressProc))) {
+ return false;
+ }
+
+ SetGLImplementation(kGLImplementationEGLGLES2);
+ InitializeStaticGLBindingsGL();
+ InitializeStaticGLBindingsEGL();
+
+ return true;
+}
+
+} // namespace
+
bool InitializeGLOneOffPlatform() {
switch (GetGLImplementation()) {
case kGLImplementationEGLGLES2:
@@ -27,5 +54,40 @@
}
}
+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());
+ ui::OzonePlatform::InitializeForGPU();
+
+ switch (implementation) {
+ case kGLImplementationOSMesaGL:
+ return InitializeStaticGLBindingsOSMesaGL();
+ case kGLImplementationEGLGLES2:
+ return InitializeStaticEGLInternal();
+ case kGLImplementationMockGL:
+ SetGLImplementation(kGLImplementationMockGL);
+ InitializeStaticGLBindingsGL();
+ return true;
+ default:
+ NOTREACHED();
+ }
+
+ return false;
+}
+
+void InitializeDebugGLBindings() {
+ InitializeDebugGLBindingsEGL();
+ InitializeDebugGLBindingsGL();
+ InitializeDebugGLBindingsOSMESA();
+}
+
+void ClearGLBindingsPlatform() {
+ ClearGLBindingsEGL();
+ ClearGLBindingsGL();
+ ClearGLBindingsOSMESA();
+}
+
} // namespace init
} // namespace gl
diff --git a/ui/gl/init/gl_initializer_win.cc b/ui/gl/init/gl_initializer_win.cc
index d862aa2..4a01505 100644
--- a/ui/gl/init/gl_initializer_win.cc
+++ b/ui/gl/init/gl_initializer_win.cc
@@ -4,15 +4,254 @@
#include "ui/gl/init/gl_initializer.h"
+#include "base/at_exit.h"
+#include "base/base_paths.h"
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/lazy_instance.h"
#include "base/logging.h"
-#include "ui/gl/gl_implementation.h"
+#include "base/native_library.h"
+#include "base/path_service.h"
+#include "base/strings/stringprintf.h"
+#include "base/threading/thread_restrictions.h"
+#include "base/trace_event/trace_event.h"
+#include "base/win/windows_version.h"
+// TODO(jmadill): Apply to all platforms eventually
+#include "ui/gl/angle_platform_impl.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_egl_api_implementation.h"
+#include "ui/gl/gl_gl_api_implementation.h"
+#include "ui/gl/gl_osmesa_api_implementation.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/gl_surface_wgl.h"
+#include "ui/gl/gl_wgl_api_implementation.h"
#include "ui/gl/vsync_provider_win.h"
+#if defined(ENABLE_SWIFTSHADER)
+#include "software_renderer.h"
+#endif
+
namespace gl {
namespace init {
+namespace {
+
+const wchar_t kD3DCompiler[] = L"D3DCompiler_47.dll";
+
+// TODO(jmadill): Apply to all platforms eventually
+base::LazyInstance<ANGLEPlatformImpl> g_angle_platform_impl =
+ LAZY_INSTANCE_INITIALIZER;
+
+ANGLEPlatformShutdownFunc g_angle_platform_shutdown = nullptr;
+
+bool LoadD3DXLibrary(const base::FilePath& module_path,
+ const base::FilePath::StringType& name) {
+ base::NativeLibrary library =
+ base::LoadNativeLibrary(base::FilePath(name), nullptr);
+ if (!library) {
+ library = base::LoadNativeLibrary(module_path.Append(name), nullptr);
+ if (!library) {
+ DVLOG(1) << name << " not found.";
+ return false;
+ }
+ }
+ return true;
+}
+
+bool InitializeStaticOSMesaInternal() {
+ base::FilePath module_path;
+ PathService::Get(base::DIR_MODULE, &module_path);
+ base::NativeLibrary library =
+ base::LoadNativeLibrary(module_path.Append(L"osmesa.dll"), nullptr);
+ if (!library) {
+ PathService::Get(base::DIR_EXE, &module_path);
+ library =
+ base::LoadNativeLibrary(module_path.Append(L"osmesa.dll"), nullptr);
+ if (!library) {
+ DVLOG(1) << "osmesa.dll not found";
+ return false;
+ }
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(library,
+ "OSMesaGetProcAddress"));
+ if (!get_proc_address) {
+ DLOG(ERROR) << "OSMesaGetProcAddress not found.";
+ base::UnloadNativeLibrary(library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(library);
+ SetGLImplementation(kGLImplementationOSMesaGL);
+
+ InitializeStaticGLBindingsGL();
+ InitializeStaticGLBindingsOSMESA();
+
+ return true;
+}
+
+bool InitializeStaticEGLInternal() {
+ base::FilePath module_path;
+ if (!PathService::Get(base::DIR_MODULE, &module_path))
+ return false;
+
+ // Attempt to load the D3DX shader compiler using the default search path
+ // and if that fails, using an absolute path. This is to ensure these DLLs
+ // are loaded before ANGLE is loaded in case they are not in the default
+ // search path.
+ LoadD3DXLibrary(module_path, kD3DCompiler);
+
+ base::FilePath gles_path;
+ const base::CommandLine* command_line =
+ base::CommandLine::ForCurrentProcess();
+ bool using_swift_shader =
+ command_line->GetSwitchValueASCII(switches::kUseGL) ==
+ kGLImplementationSwiftShaderName;
+ if (using_swift_shader) {
+ if (!command_line->HasSwitch(switches::kSwiftShaderPath))
+ return false;
+ gles_path = command_line->GetSwitchValuePath(switches::kSwiftShaderPath);
+ // Preload library
+ LoadLibrary(L"ddraw.dll");
+ } else {
+ gles_path = module_path;
+ }
+
+ // Load libglesv2.dll before libegl.dll because the latter is dependent on
+ // the former and if there is another version of libglesv2.dll in the dll
+ // search path, it will get loaded instead.
+ base::NativeLibrary gles_library =
+ base::LoadNativeLibrary(gles_path.Append(L"libglesv2.dll"), nullptr);
+ if (!gles_library) {
+ DVLOG(1) << "libglesv2.dll not found";
+ return false;
+ }
+
+ // When using EGL, first try eglGetProcAddress and then Windows
+ // GetProcAddress on both the EGL and GLES2 DLLs.
+ base::NativeLibrary egl_library =
+ base::LoadNativeLibrary(gles_path.Append(L"libegl.dll"), nullptr);
+ if (!egl_library) {
+ DVLOG(1) << "libegl.dll not found.";
+ base::UnloadNativeLibrary(gles_library);
+ return false;
+ }
+
+#if defined(ENABLE_SWIFTSHADER)
+ if (using_swift_shader) {
+ SetupSoftwareRenderer(gles_library);
+ }
+#endif
+
+ if (!using_swift_shader) {
+ // Init ANGLE platform here, before we call GetPlatformDisplay().
+ // TODO(jmadill): Apply to all platforms eventually
+ ANGLEPlatformInitializeFunc angle_platform_init =
+ reinterpret_cast<ANGLEPlatformInitializeFunc>(
+ base::GetFunctionPointerFromNativeLibrary(
+ gles_library, "ANGLEPlatformInitialize"));
+ if (angle_platform_init) {
+ angle_platform_init(&g_angle_platform_impl.Get());
+
+ g_angle_platform_shutdown = reinterpret_cast<ANGLEPlatformShutdownFunc>(
+ base::GetFunctionPointerFromNativeLibrary(gles_library,
+ "ANGLEPlatformShutdown"));
+ }
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(egl_library,
+ "eglGetProcAddress"));
+ if (!get_proc_address) {
+ LOG(ERROR) << "eglGetProcAddress not found.";
+ base::UnloadNativeLibrary(egl_library);
+ base::UnloadNativeLibrary(gles_library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(egl_library);
+ AddGLNativeLibrary(gles_library);
+ SetGLImplementation(kGLImplementationEGLGLES2);
+
+ InitializeStaticGLBindingsGL();
+ InitializeStaticGLBindingsEGL();
+
+ return true;
+}
+
+bool InitializeStaticWGLInternal() {
+ base::NativeLibrary library =
+ base::LoadNativeLibrary(base::FilePath(L"opengl32.dll"), nullptr);
+ if (!library) {
+ DVLOG(1) << "opengl32.dll not found";
+ return false;
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(library,
+ "wglGetProcAddress"));
+ if (!get_proc_address) {
+ LOG(ERROR) << "wglGetProcAddress not found.";
+ base::UnloadNativeLibrary(library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(library);
+ SetGLImplementation(kGLImplementationDesktopGL);
+
+ // Initialize GL surface and get some functions needed for the context
+ // creation below.
+ if (!GLSurfaceWGL::InitializeOneOff()) {
+ LOG(ERROR) << "GLSurfaceWGL::InitializeOneOff failed.";
+ return false;
+ }
+ wglCreateContextProc wglCreateContextFn =
+ reinterpret_cast<wglCreateContextProc>(
+ GetGLProcAddress("wglCreateContext"));
+ wglDeleteContextProc wglDeleteContextFn =
+ reinterpret_cast<wglDeleteContextProc>(
+ GetGLProcAddress("wglDeleteContext"));
+ wglMakeCurrentProc wglMakeCurrentFn =
+ reinterpret_cast<wglMakeCurrentProc>(GetGLProcAddress("wglMakeCurrent"));
+
+ // Create a temporary GL context to bind to entry points. This is needed
+ // because wglGetProcAddress is specified to return nullptr for all queries
+ // if a context is not current in MSDN documentation, and the static
+ // bindings may contain functions that need to be queried with
+ // wglGetProcAddress. OpenGL wiki further warns that other error values
+ // than nullptr could also be returned from wglGetProcAddress on some
+ // implementations, so we need to clear the WGL bindings and reinitialize
+ // them after the context creation.
+ HGLRC gl_context = wglCreateContextFn(GLSurfaceWGL::GetDisplayDC());
+ if (!gl_context) {
+ LOG(ERROR) << "Failed to create temporary context.";
+ return false;
+ }
+ if (!wglMakeCurrentFn(GLSurfaceWGL::GetDisplayDC(), gl_context)) {
+ LOG(ERROR) << "Failed to make temporary GL context current.";
+ wglDeleteContextFn(gl_context);
+ return false;
+ }
+
+ InitializeStaticGLBindingsGL();
+ InitializeStaticGLBindingsWGL();
+
+ wglMakeCurrent(nullptr, nullptr);
+ wglDeleteContext(gl_context);
+
+ return true;
+}
+
+} // namespace
+
bool InitializeGLOneOffPlatform() {
VSyncProviderWin::InitializeOneOff();
@@ -38,5 +277,54 @@
return true;
}
+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 kGLImplementationEGLGLES2:
+ return InitializeStaticEGLInternal();
+ case kGLImplementationDesktopGL:
+ return InitializeStaticWGLInternal();
+ case kGLImplementationMockGL:
+ SetGLImplementation(kGLImplementationMockGL);
+ InitializeStaticGLBindingsGL();
+ return true;
+ default:
+ NOTREACHED();
+ }
+
+ return false;
+}
+
+void InitializeDebugGLBindings() {
+ InitializeDebugGLBindingsEGL();
+ InitializeDebugGLBindingsGL();
+ InitializeDebugGLBindingsOSMESA();
+ InitializeDebugGLBindingsWGL();
+}
+
+void ClearGLBindingsPlatform() {
+ // TODO(jmadill): Apply to all platforms eventually
+ if (g_angle_platform_shutdown) {
+ g_angle_platform_shutdown();
+ }
+
+ ClearGLBindingsEGL();
+ ClearGLBindingsGL();
+ ClearGLBindingsOSMESA();
+ ClearGLBindingsWGL();
+}
+
} // namespace init
} // namespace gl
diff --git a/ui/gl/init/gl_initializer_x11.cc b/ui/gl/init/gl_initializer_x11.cc
index e6dc492..088230a 100644
--- a/ui/gl/init/gl_initializer_x11.cc
+++ b/ui/gl/init/gl_initializer_x11.cc
@@ -4,15 +4,124 @@
#include "ui/gl/init/gl_initializer.h"
+#include "base/command_line.h"
#include "base/logging.h"
-#include "ui/gl/gl_implementation.h"
+#include "base/path_service.h"
+#include "base/threading/thread_restrictions.h"
+#include "build/build_config.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_egl_api_implementation.h"
+#include "ui/gl/gl_gl_api_implementation.h"
+#include "ui/gl/gl_glx_api_implementation.h"
+#include "ui/gl/gl_implementation_osmesa.h"
+#include "ui/gl/gl_osmesa_api_implementation.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/gl_surface_glx.h"
#include "ui/gl/gl_surface_osmesa_x11.h"
+#include "ui/gl/gl_switches.h"
namespace gl {
namespace init {
+namespace {
+
+#if defined(OS_OPENBSD)
+const char kGLLibraryName[] = "libGL.so";
+#else
+const char kGLLibraryName[] = "libGL.so.1";
+#endif
+
+const char kGLESv2LibraryName[] = "libGLESv2.so.2";
+const char kEGLLibraryName[] = "libEGL.so.1";
+
+const char kGLESv2ANGLELibraryName[] = "libGLESv2.so";
+const char kEGLANGLELibraryName[] = "libEGL.so";
+
+bool InitializeStaticGLXInternal() {
+ base::NativeLibrary library = NULL;
+ const base::CommandLine* command_line =
+ base::CommandLine::ForCurrentProcess();
+
+ if (command_line->HasSwitch(switches::kTestGLLib))
+ library = LoadLibraryAndPrintError(
+ command_line->GetSwitchValueASCII(switches::kTestGLLib).c_str());
+
+ if (!library) {
+ library = LoadLibraryAndPrintError(kGLLibraryName);
+ }
+
+ if (!library)
+ return false;
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(library,
+ "glXGetProcAddress"));
+ if (!get_proc_address) {
+ LOG(ERROR) << "glxGetProcAddress not found.";
+ base::UnloadNativeLibrary(library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(library);
+ SetGLImplementation(kGLImplementationDesktopGL);
+
+ InitializeStaticGLBindingsGL();
+ InitializeStaticGLBindingsGLX();
+
+ return true;
+}
+
+bool InitializeStaticEGLInternal() {
+ base::FilePath glesv2_path(kGLESv2LibraryName);
+ base::FilePath egl_path(kEGLLibraryName);
+
+ const base::CommandLine* command_line =
+ base::CommandLine::ForCurrentProcess();
+ if (command_line->GetSwitchValueASCII(switches::kUseGL) ==
+ kGLImplementationANGLEName) {
+ base::FilePath module_path;
+ if (!PathService::Get(base::DIR_MODULE, &module_path))
+ return false;
+
+ glesv2_path = module_path.Append(kGLESv2ANGLELibraryName);
+ egl_path = module_path.Append(kEGLANGLELibraryName);
+ }
+
+ base::NativeLibrary gles_library = LoadLibraryAndPrintError(glesv2_path);
+ if (!gles_library)
+ return false;
+ base::NativeLibrary egl_library = LoadLibraryAndPrintError(egl_path);
+ if (!egl_library) {
+ base::UnloadNativeLibrary(gles_library);
+ return false;
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(egl_library,
+ "eglGetProcAddress"));
+ if (!get_proc_address) {
+ LOG(ERROR) << "eglGetProcAddress not found.";
+ base::UnloadNativeLibrary(egl_library);
+ base::UnloadNativeLibrary(gles_library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(egl_library);
+ AddGLNativeLibrary(gles_library);
+ SetGLImplementation(kGLImplementationEGLGLES2);
+
+ InitializeStaticGLBindingsGL();
+ InitializeStaticGLBindingsEGL();
+
+ return true;
+}
+
+} // namespace
+
bool InitializeGLOneOffPlatform() {
switch (GetGLImplementation()) {
case kGLImplementationDesktopGL:
@@ -38,5 +147,49 @@
}
}
+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 InitializeStaticGLBindingsOSMesaGL();
+ case kGLImplementationDesktopGL:
+ return InitializeStaticGLXInternal();
+ case kGLImplementationEGLGLES2:
+ return InitializeStaticEGLInternal();
+ case kGLImplementationMockGL:
+ SetGLImplementation(kGLImplementationMockGL);
+ InitializeStaticGLBindingsGL();
+ return true;
+ default:
+ NOTREACHED();
+ }
+
+ return false;
+}
+
+void InitializeDebugGLBindings() {
+ InitializeDebugGLBindingsEGL();
+ InitializeDebugGLBindingsGL();
+ InitializeDebugGLBindingsGLX();
+ InitializeDebugGLBindingsOSMESA();
+}
+
+void ClearGLBindingsPlatform() {
+ ClearGLBindingsEGL();
+ ClearGLBindingsGL();
+ ClearGLBindingsGLX();
+ ClearGLBindingsOSMESA();
+}
+
} // namespace init
} // namespace gl
diff --git a/ui/gl/test/gl_image_test_support.cc b/ui/gl/test/gl_image_test_support.cc
index 460f48a..be049be1 100644
--- a/ui/gl/test/gl_image_test_support.cc
+++ b/ui/gl/test/gl_image_test_support.cc
@@ -7,6 +7,7 @@
#include <vector>
#include "ui/gl/gl_implementation.h"
+#include "ui/gl/init/gl_factory.h"
#include "ui/gl/test/gl_surface_test_support.h"
#if defined(USE_OZONE)
@@ -32,7 +33,7 @@
// static
void GLImageTestSupport::CleanupGL() {
- ClearGLBindings();
+ init::ClearGLBindings();
}
// static
diff --git a/ui/gl/test/gl_surface_test_support.cc b/ui/gl/test/gl_surface_test_support.cc
index d868715..92d05bd4 100644
--- a/ui/gl/test/gl_surface_test_support.cc
+++ b/ui/gl/test/gl_surface_test_support.cc
@@ -72,7 +72,7 @@
// This method may be called multiple times in the same process to set up
// bindings in different ways.
- ClearGLBindings();
+ init::ClearGLBindings();
bool gpu_service_logging = false;
bool disable_gl_drawing = false;