blob: b8a724649f8c0cfe91e10586718d78e7695acd8a [file] [log] [blame]
[email protected]991c5682012-01-30 13:32:341// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]b9363b22010-06-09 22:06:152// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]0bec8e22010-06-21 22:20:025#include <vector>
[email protected]b9363b22010-06-09 22:06:156
[email protected]30aa5c1a2010-07-14 20:47:047#include "base/command_line.h"
[email protected]30aa5c1a2010-07-14 20:47:048#include "base/logging.h"
[email protected]6e318e0e2011-10-14 23:08:209#include "base/threading/thread_restrictions.h"
[email protected]c9e2cbbb2012-05-12 21:17:2710#include "ui/gl/gl_bindings.h"
[email protected]a37d7ff2014-01-17 21:31:0011#include "ui/gl/gl_context_stub_with_extensions.h"
[email protected]b97c9082012-10-25 17:21:3812#include "ui/gl/gl_egl_api_implementation.h"
13#include "ui/gl/gl_gl_api_implementation.h"
14#include "ui/gl/gl_glx_api_implementation.h"
[email protected]c9e2cbbb2012-05-12 21:17:2715#include "ui/gl/gl_implementation.h"
[email protected]abeda1f2014-02-21 17:08:3416#include "ui/gl/gl_implementation_osmesa.h"
[email protected]b97c9082012-10-25 17:21:3817#include "ui/gl/gl_osmesa_api_implementation.h"
[email protected]c9e2cbbb2012-05-12 21:17:2718#include "ui/gl/gl_switches.h"
[email protected]b9363b22010-06-09 22:06:1519
20namespace gfx {
21namespace {
[email protected]0bec8e22010-06-21 22:20:0222
23// TODO(piman): it should be Desktop GL marshalling from double to float. Today
24// on native GLES, we do float->double->float.
25void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
26 glClearDepthf(static_cast<GLclampf>(depth));
27}
28
29void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
30 GLclampd z_far) {
31 glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
32}
33
[email protected]d7c29422014-03-11 06:08:5734#if defined(OS_OPENBSD)
35const char kGLLibraryName[] = "libGL.so";
36#else
37const char kGLLibraryName[] = "libGL.so.1";
38#endif
39
40const char kGLESv2LibraryName[] = "libGLESv2.so.2";
41const char kEGLLibraryName[] = "libEGL.so.1";
42
[email protected]83afcbcc2012-07-27 03:06:2743} // namespace
[email protected]b9363b22010-06-09 22:06:1544
[email protected]0f5e8882011-11-08 22:29:3845void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
[email protected]3c4b7ef2011-11-21 22:24:4946 impls->push_back(kGLImplementationDesktopGL);
[email protected]3c4b7ef2011-11-21 22:24:4947 impls->push_back(kGLImplementationEGLGLES2);
[email protected]70518b12011-11-22 01:39:1248 impls->push_back(kGLImplementationOSMesaGL);
[email protected]0f5e8882011-11-08 22:29:3849}
50
[email protected]a37d7ff2014-01-17 21:31:0051bool InitializeStaticGLBindings(GLImplementation implementation) {
[email protected]b9363b22010-06-09 22:06:1552 // Prevent reinitialization with a different implementation. Once the gpu
53 // unit tests have initialized with kGLImplementationMock, we don't want to
54 // later switch to another GL implementation.
[email protected]af7c5d92014-02-03 19:53:1555 DCHECK_EQ(kGLImplementationNone, GetGLImplementation());
[email protected]b9363b22010-06-09 22:06:1556
[email protected]6e318e0e2011-10-14 23:08:2057 // Allow the main thread or another to initialize these bindings
58 // after instituting restrictions on I/O. Going forward they will
59 // likely be used in the browser process on most platforms. The
60 // one-time initialization cost is small, between 2 and 5 ms.
61 base::ThreadRestrictions::ScopedAllowIO allow_io;
62
[email protected]b9363b22010-06-09 22:06:1563 switch (implementation) {
[email protected]31e8a4f2013-06-29 01:13:2764 case kGLImplementationOSMesaGL:
[email protected]a37d7ff2014-01-17 21:31:0065 return InitializeStaticGLBindingsOSMesaGL();
marcheu1856f5d52015-04-04 01:42:5366 case kGLImplementationDesktopGL: {
[email protected]991c5682012-01-30 13:32:3467 base::NativeLibrary library = NULL;
avi6b10fd02014-12-23 05:51:2368 const base::CommandLine* command_line =
69 base::CommandLine::ForCurrentProcess();
[email protected]991c5682012-01-30 13:32:3470
71 if (command_line->HasSwitch(switches::kTestGLLib))
[email protected]6bfbfe22014-05-01 21:54:3772 library = LoadLibraryAndPrintError(
73 command_line->GetSwitchValueASCII(switches::kTestGLLib).c_str());
[email protected]991c5682012-01-30 13:32:3474
75 if (!library) {
[email protected]6bfbfe22014-05-01 21:54:3776 library = LoadLibraryAndPrintError(kGLLibraryName);
[email protected]991c5682012-01-30 13:32:3477 }
78
[email protected]6bfbfe22014-05-01 21:54:3779 if (!library)
[email protected]30aa5c1a2010-07-14 20:47:0480 return false;
[email protected]30aa5c1a2010-07-14 20:47:0481
82 GLGetProcAddressProc get_proc_address =
83 reinterpret_cast<GLGetProcAddressProc>(
84 base::GetFunctionPointerFromNativeLibrary(
85 library, "glXGetProcAddress"));
[email protected]1b2707bb2010-10-06 19:37:1686 if (!get_proc_address) {
87 LOG(ERROR) << "glxGetProcAddress not found.";
88 base::UnloadNativeLibrary(library);
89 return false;
90 }
[email protected]30aa5c1a2010-07-14 20:47:0491
92 SetGLGetProcAddressProc(get_proc_address);
93 AddGLNativeLibrary(library);
marcheu1856f5d52015-04-04 01:42:5394 SetGLImplementation(kGLImplementationDesktopGL);
[email protected]b9363b22010-06-09 22:06:1595
[email protected]a37d7ff2014-01-17 21:31:0096 InitializeStaticGLBindingsGL();
97 InitializeStaticGLBindingsGLX();
[email protected]b9363b22010-06-09 22:06:1598 break;
[email protected]30aa5c1a2010-07-14 20:47:0499 }
100 case kGLImplementationEGLGLES2: {
[email protected]6bfbfe22014-05-01 21:54:37101 base::NativeLibrary gles_library =
102 LoadLibraryAndPrintError(kGLESv2LibraryName);
103 if (!gles_library)
[email protected]1b2707bb2010-10-06 19:37:16104 return false;
[email protected]6bfbfe22014-05-01 21:54:37105 base::NativeLibrary egl_library =
106 LoadLibraryAndPrintError(kEGLLibraryName);
[email protected]91ac84f72011-06-22 19:48:02107 if (!egl_library) {
108 base::UnloadNativeLibrary(gles_library);
[email protected]0bec8e22010-06-21 22:20:02109 return false;
[email protected]91ac84f72011-06-22 19:48:02110 }
[email protected]0bec8e22010-06-21 22:20:02111
[email protected]30aa5c1a2010-07-14 20:47:04112 GLGetProcAddressProc get_proc_address =
113 reinterpret_cast<GLGetProcAddressProc>(
114 base::GetFunctionPointerFromNativeLibrary(
115 egl_library, "eglGetProcAddress"));
[email protected]1b2707bb2010-10-06 19:37:16116 if (!get_proc_address) {
117 LOG(ERROR) << "eglGetProcAddress not found.";
[email protected]30aa5c1a2010-07-14 20:47:04118 base::UnloadNativeLibrary(egl_library);
[email protected]1b2707bb2010-10-06 19:37:16119 base::UnloadNativeLibrary(gles_library);
[email protected]0bec8e22010-06-21 22:20:02120 return false;
121 }
122
[email protected]30aa5c1a2010-07-14 20:47:04123 SetGLGetProcAddressProc(get_proc_address);
124 AddGLNativeLibrary(egl_library);
125 AddGLNativeLibrary(gles_library);
126 SetGLImplementation(kGLImplementationEGLGLES2);
[email protected]0bec8e22010-06-21 22:20:02127
[email protected]a37d7ff2014-01-17 21:31:00128 InitializeStaticGLBindingsGL();
129 InitializeStaticGLBindingsEGL();
[email protected]0bec8e22010-06-21 22:20:02130
131 // These two functions take single precision float rather than double
132 // precision float parameters in GLES.
[email protected]b97c9082012-10-25 17:21:38133 ::gfx::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf;
134 ::gfx::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef;
[email protected]0bec8e22010-06-21 22:20:02135 break;
[email protected]30aa5c1a2010-07-14 20:47:04136 }
137 case kGLImplementationMockGL: {
[email protected]30aa5c1a2010-07-14 20:47:04138 SetGLImplementation(kGLImplementationMockGL);
[email protected]a37d7ff2014-01-17 21:31:00139 InitializeStaticGLBindingsGL();
[email protected]b9363b22010-06-09 22:06:15140 break;
[email protected]30aa5c1a2010-07-14 20:47:04141 }
[email protected]b9363b22010-06-09 22:06:15142 default:
143 return false;
144 }
145
146
147 return true;
148}
149
[email protected]a37d7ff2014-01-17 21:31:00150bool InitializeDynamicGLBindings(GLImplementation implementation,
[email protected]6494823b2011-10-27 18:30:44151 GLContext* context) {
152 switch (implementation) {
153 case kGLImplementationOSMesaGL:
marcheu1856f5d52015-04-04 01:42:53154 case kGLImplementationDesktopGL:
[email protected]6494823b2011-10-27 18:30:44155 case kGLImplementationEGLGLES2:
[email protected]a37d7ff2014-01-17 21:31:00156 InitializeDynamicGLBindingsGL(context);
[email protected]6494823b2011-10-27 18:30:44157 break;
158 case kGLImplementationMockGL:
[email protected]a37d7ff2014-01-17 21:31:00159 if (!context) {
160 scoped_refptr<GLContextStubWithExtensions> mock_context(
161 new GLContextStubWithExtensions());
162 mock_context->SetGLVersionString("3.0");
163 InitializeDynamicGLBindingsGL(mock_context.get());
164 } else
165 InitializeDynamicGLBindingsGL(context);
[email protected]6494823b2011-10-27 18:30:44166 break;
167 default:
168 return false;
169 }
170
171 return true;
172}
173
[email protected]218a5a22010-11-04 19:27:49174void InitializeDebugGLBindings() {
175 InitializeDebugGLBindingsEGL();
176 InitializeDebugGLBindingsGL();
177 InitializeDebugGLBindingsGLX();
178 InitializeDebugGLBindingsOSMESA();
179}
180
[email protected]0f5e8882011-11-08 22:29:38181void ClearGLBindings() {
182 ClearGLBindingsEGL();
183 ClearGLBindingsGL();
[email protected]0f5e8882011-11-08 22:29:38184 ClearGLBindingsGLX();
185 ClearGLBindingsOSMESA();
[email protected]0f5e8882011-11-08 22:29:38186 SetGLImplementation(kGLImplementationNone);
187
188 UnloadGLNativeLibraries();
189}
190
[email protected]45895032013-05-30 17:06:43191bool GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo* info) {
192 switch (GetGLImplementation()) {
193 case kGLImplementationDesktopGL:
[email protected]45895032013-05-30 17:06:43194 return GetGLWindowSystemBindingInfoGLX(info);
195 case kGLImplementationEGLGLES2:
196 return GetGLWindowSystemBindingInfoEGL(info);
197 default:
198 return false;
199 }
200 return false;
201}
202
[email protected]b9363b22010-06-09 22:06:15203} // namespace gfx