blob: dc81fbc8598a68a4924532e40784517dbec8290d [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/base_paths.h"
8#include "base/command_line.h"
9#include "base/file_path.h"
10#include "base/logging.h"
11#include "base/native_library.h"
12#include "base/path_service.h"
[email protected]6e318e0e2011-10-14 23:08:2013#include "base/threading/thread_restrictions.h"
[email protected]c9e2cbbb2012-05-12 21:17:2714#include "ui/gl/gl_bindings.h"
[email protected]b97c9082012-10-25 17:21:3815#include "ui/gl/gl_egl_api_implementation.h"
16#include "ui/gl/gl_gl_api_implementation.h"
17#include "ui/gl/gl_glx_api_implementation.h"
[email protected]c9e2cbbb2012-05-12 21:17:2718#include "ui/gl/gl_implementation.h"
[email protected]b97c9082012-10-25 17:21:3819#include "ui/gl/gl_osmesa_api_implementation.h"
[email protected]c9e2cbbb2012-05-12 21:17:2720#include "ui/gl/gl_switches.h"
[email protected]b9363b22010-06-09 22:06:1521
22namespace gfx {
23namespace {
[email protected]0bec8e22010-06-21 22:20:0224
25// TODO(piman): it should be Desktop GL marshalling from double to float. Today
26// on native GLES, we do float->double->float.
27void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
28 glClearDepthf(static_cast<GLclampf>(depth));
29}
30
31void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
32 GLclampd z_far) {
33 glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
34}
35
[email protected]84479322011-04-18 22:06:2236// Load a library, printing an error message on failure.
[email protected]a246122752011-04-19 01:10:4837base::NativeLibrary LoadLibrary(const FilePath& filename) {
[email protected]84479322011-04-18 22:06:2238 std::string error;
[email protected]a246122752011-04-19 01:10:4839 base::NativeLibrary library = base::LoadNativeLibrary(filename,
[email protected]84479322011-04-18 22:06:2240 &error);
41 if (!library) {
[email protected]46a519fba2012-04-23 00:40:3542 DVLOG(1) << "Failed to load " << filename.MaybeAsASCII() << ": " << error;
[email protected]84479322011-04-18 22:06:2243 return NULL;
44 }
45 return library;
46}
47
[email protected]a246122752011-04-19 01:10:4848base::NativeLibrary LoadLibrary(const char* filename) {
49 return LoadLibrary(FilePath(filename));
50}
51
[email protected]83afcbcc2012-07-27 03:06:2752} // namespace
[email protected]b9363b22010-06-09 22:06:1553
[email protected]0f5e8882011-11-08 22:29:3854void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
[email protected]3c4b7ef2011-11-21 22:24:4955 impls->push_back(kGLImplementationDesktopGL);
[email protected]3c4b7ef2011-11-21 22:24:4956 impls->push_back(kGLImplementationEGLGLES2);
[email protected]70518b12011-11-22 01:39:1257 impls->push_back(kGLImplementationOSMesaGL);
[email protected]0f5e8882011-11-08 22:29:3858}
59
[email protected]b9363b22010-06-09 22:06:1560bool InitializeGLBindings(GLImplementation implementation) {
61 // Prevent reinitialization with a different implementation. Once the gpu
62 // unit tests have initialized with kGLImplementationMock, we don't want to
63 // later switch to another GL implementation.
[email protected]30aa5c1a2010-07-14 20:47:0464 if (GetGLImplementation() != kGLImplementationNone)
[email protected]b9363b22010-06-09 22:06:1565 return true;
66
[email protected]6e318e0e2011-10-14 23:08:2067 // Allow the main thread or another to initialize these bindings
68 // after instituting restrictions on I/O. Going forward they will
69 // likely be used in the browser process on most platforms. The
70 // one-time initialization cost is small, between 2 and 5 ms.
71 base::ThreadRestrictions::ScopedAllowIO allow_io;
72
[email protected]b9363b22010-06-09 22:06:1573 switch (implementation) {
[email protected]30aa5c1a2010-07-14 20:47:0474 case kGLImplementationOSMesaGL: {
[email protected]36a09792010-09-10 02:31:3975 FilePath module_path;
[email protected]d0498742010-09-20 20:27:0176 if (!PathService::Get(base::DIR_MODULE, &module_path)) {
77 LOG(ERROR) << "PathService::Get failed.";
[email protected]30aa5c1a2010-07-14 20:47:0478 return false;
[email protected]d0498742010-09-20 20:27:0179 }
[email protected]30aa5c1a2010-07-14 20:47:0480
[email protected]a246122752011-04-19 01:10:4881 base::NativeLibrary library = LoadLibrary(
82 module_path.Append("libosmesa.so"));
[email protected]84479322011-04-18 22:06:2283 if (!library)
[email protected]b9363b22010-06-09 22:06:1584 return false;
[email protected]0bec8e22010-06-21 22:20:0285
[email protected]30aa5c1a2010-07-14 20:47:0486 GLGetProcAddressProc get_proc_address =
87 reinterpret_cast<GLGetProcAddressProc>(
88 base::GetFunctionPointerFromNativeLibrary(
89 library, "OSMesaGetProcAddress"));
[email protected]1b2707bb2010-10-06 19:37:1690 if (!get_proc_address) {
[email protected]363b20d2011-01-14 22:54:1691 LOG(ERROR) << "OSMesaGetProcAddress not found.";
[email protected]1b2707bb2010-10-06 19:37:1692 base::UnloadNativeLibrary(library);
93 return false;
94 }
[email protected]b9363b22010-06-09 22:06:1595
[email protected]30aa5c1a2010-07-14 20:47:0496 SetGLGetProcAddressProc(get_proc_address);
97 AddGLNativeLibrary(library);
98 SetGLImplementation(kGLImplementationOSMesaGL);
[email protected]b9363b22010-06-09 22:06:1599
[email protected]30aa5c1a2010-07-14 20:47:04100 InitializeGLBindingsGL();
101 InitializeGLBindingsOSMESA();
102 break;
103 }
104 case kGLImplementationDesktopGL: {
[email protected]991c5682012-01-30 13:32:34105 base::NativeLibrary library = NULL;
106 const CommandLine* command_line = CommandLine::ForCurrentProcess();
107
108 if (command_line->HasSwitch(switches::kTestGLLib))
109 library = LoadLibrary(command_line->GetSwitchValueASCII(
110 switches::kTestGLLib).c_str());
111
112 if (!library) {
[email protected]7f4115e2011-10-26 20:09:45113#if defined(OS_OPENBSD)
[email protected]991c5682012-01-30 13:32:34114 library = LoadLibrary("libGL.so");
[email protected]7f4115e2011-10-26 20:09:45115#else
[email protected]991c5682012-01-30 13:32:34116 library = LoadLibrary("libGL.so.1");
[email protected]7f4115e2011-10-26 20:09:45117#endif
[email protected]991c5682012-01-30 13:32:34118 }
119
[email protected]84479322011-04-18 22:06:22120 if (!library)
[email protected]30aa5c1a2010-07-14 20:47:04121 return false;
[email protected]30aa5c1a2010-07-14 20:47:04122
123 GLGetProcAddressProc get_proc_address =
124 reinterpret_cast<GLGetProcAddressProc>(
125 base::GetFunctionPointerFromNativeLibrary(
126 library, "glXGetProcAddress"));
[email protected]1b2707bb2010-10-06 19:37:16127 if (!get_proc_address) {
128 LOG(ERROR) << "glxGetProcAddress not found.";
129 base::UnloadNativeLibrary(library);
130 return false;
131 }
[email protected]30aa5c1a2010-07-14 20:47:04132
133 SetGLGetProcAddressProc(get_proc_address);
134 AddGLNativeLibrary(library);
135 SetGLImplementation(kGLImplementationDesktopGL);
[email protected]b9363b22010-06-09 22:06:15136
137 InitializeGLBindingsGL();
138 InitializeGLBindingsGLX();
139 break;
[email protected]30aa5c1a2010-07-14 20:47:04140 }
141 case kGLImplementationEGLGLES2: {
[email protected]3733a142012-02-08 22:05:08142 base::NativeLibrary gles_library = LoadLibrary("libGLESv2.so.2");
[email protected]84479322011-04-18 22:06:22143 if (!gles_library)
[email protected]1b2707bb2010-10-06 19:37:16144 return false;
[email protected]3733a142012-02-08 22:05:08145 base::NativeLibrary egl_library = LoadLibrary("libEGL.so.1");
[email protected]91ac84f72011-06-22 19:48:02146 if (!egl_library) {
147 base::UnloadNativeLibrary(gles_library);
[email protected]0bec8e22010-06-21 22:20:02148 return false;
[email protected]91ac84f72011-06-22 19:48:02149 }
[email protected]0bec8e22010-06-21 22:20:02150
[email protected]30aa5c1a2010-07-14 20:47:04151 GLGetProcAddressProc get_proc_address =
152 reinterpret_cast<GLGetProcAddressProc>(
153 base::GetFunctionPointerFromNativeLibrary(
154 egl_library, "eglGetProcAddress"));
[email protected]1b2707bb2010-10-06 19:37:16155 if (!get_proc_address) {
156 LOG(ERROR) << "eglGetProcAddress not found.";
[email protected]30aa5c1a2010-07-14 20:47:04157 base::UnloadNativeLibrary(egl_library);
[email protected]1b2707bb2010-10-06 19:37:16158 base::UnloadNativeLibrary(gles_library);
[email protected]0bec8e22010-06-21 22:20:02159 return false;
160 }
161
[email protected]30aa5c1a2010-07-14 20:47:04162 SetGLGetProcAddressProc(get_proc_address);
163 AddGLNativeLibrary(egl_library);
164 AddGLNativeLibrary(gles_library);
165 SetGLImplementation(kGLImplementationEGLGLES2);
[email protected]0bec8e22010-06-21 22:20:02166
167 InitializeGLBindingsGL();
168 InitializeGLBindingsEGL();
169
170 // These two functions take single precision float rather than double
171 // precision float parameters in GLES.
[email protected]b97c9082012-10-25 17:21:38172 ::gfx::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf;
173 ::gfx::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef;
[email protected]0bec8e22010-06-21 22:20:02174 break;
[email protected]30aa5c1a2010-07-14 20:47:04175 }
176 case kGLImplementationMockGL: {
177 SetGLGetProcAddressProc(GetMockGLProcAddress);
178 SetGLImplementation(kGLImplementationMockGL);
[email protected]b9363b22010-06-09 22:06:15179 InitializeGLBindingsGL();
180 break;
[email protected]30aa5c1a2010-07-14 20:47:04181 }
[email protected]b9363b22010-06-09 22:06:15182 default:
183 return false;
184 }
185
186
187 return true;
188}
189
[email protected]6494823b2011-10-27 18:30:44190bool InitializeGLExtensionBindings(GLImplementation implementation,
191 GLContext* context) {
192 switch (implementation) {
193 case kGLImplementationOSMesaGL:
194 InitializeGLExtensionBindingsGL(context);
195 InitializeGLExtensionBindingsOSMESA(context);
196 break;
197 case kGLImplementationDesktopGL:
198 InitializeGLExtensionBindingsGL(context);
199 InitializeGLExtensionBindingsGLX(context);
200 break;
201 case kGLImplementationEGLGLES2:
202 InitializeGLExtensionBindingsGL(context);
203 InitializeGLExtensionBindingsEGL(context);
204 break;
205 case kGLImplementationMockGL:
206 InitializeGLExtensionBindingsGL(context);
207 break;
208 default:
209 return false;
210 }
211
212 return true;
213}
214
[email protected]218a5a22010-11-04 19:27:49215void InitializeDebugGLBindings() {
216 InitializeDebugGLBindingsEGL();
217 InitializeDebugGLBindingsGL();
218 InitializeDebugGLBindingsGLX();
219 InitializeDebugGLBindingsOSMESA();
220}
221
[email protected]0f5e8882011-11-08 22:29:38222void ClearGLBindings() {
223 ClearGLBindingsEGL();
224 ClearGLBindingsGL();
[email protected]0f5e8882011-11-08 22:29:38225 ClearGLBindingsGLX();
226 ClearGLBindingsOSMESA();
[email protected]0f5e8882011-11-08 22:29:38227 SetGLImplementation(kGLImplementationNone);
228
229 UnloadGLNativeLibraries();
230}
231
[email protected]b9363b22010-06-09 22:06:15232} // namespace gfx