blob: e5ca5f698dc21bcdd60a73bc8519afaffb84a58f [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"
15#include "ui/gl/gl_implementation.h"
16#include "ui/gl/gl_switches.h"
[email protected]b9363b22010-06-09 22:06:1517
18namespace gfx {
19namespace {
[email protected]0bec8e22010-06-21 22:20:0220
21// TODO(piman): it should be Desktop GL marshalling from double to float. Today
22// on native GLES, we do float->double->float.
23void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
24 glClearDepthf(static_cast<GLclampf>(depth));
25}
26
27void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
28 GLclampd z_far) {
29 glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
30}
31
[email protected]84479322011-04-18 22:06:2232// Load a library, printing an error message on failure.
[email protected]a246122752011-04-19 01:10:4833base::NativeLibrary LoadLibrary(const FilePath& filename) {
[email protected]84479322011-04-18 22:06:2234 std::string error;
[email protected]a246122752011-04-19 01:10:4835 base::NativeLibrary library = base::LoadNativeLibrary(filename,
[email protected]84479322011-04-18 22:06:2236 &error);
37 if (!library) {
[email protected]46a519fba2012-04-23 00:40:3538 DVLOG(1) << "Failed to load " << filename.MaybeAsASCII() << ": " << error;
[email protected]84479322011-04-18 22:06:2239 return NULL;
40 }
41 return library;
42}
43
[email protected]a246122752011-04-19 01:10:4844base::NativeLibrary LoadLibrary(const char* filename) {
45 return LoadLibrary(FilePath(filename));
46}
47
[email protected]83afcbcc2012-07-27 03:06:2748} // namespace
[email protected]b9363b22010-06-09 22:06:1549
[email protected]0f5e8882011-11-08 22:29:3850void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
[email protected]3c4b7ef2011-11-21 22:24:4951 impls->push_back(kGLImplementationDesktopGL);
[email protected]3c4b7ef2011-11-21 22:24:4952 impls->push_back(kGLImplementationEGLGLES2);
[email protected]70518b12011-11-22 01:39:1253 impls->push_back(kGLImplementationOSMesaGL);
[email protected]0f5e8882011-11-08 22:29:3854}
55
[email protected]b9363b22010-06-09 22:06:1556bool InitializeGLBindings(GLImplementation implementation) {
57 // Prevent reinitialization with a different implementation. Once the gpu
58 // unit tests have initialized with kGLImplementationMock, we don't want to
59 // later switch to another GL implementation.
[email protected]30aa5c1a2010-07-14 20:47:0460 if (GetGLImplementation() != kGLImplementationNone)
[email protected]b9363b22010-06-09 22:06:1561 return true;
62
[email protected]6e318e0e2011-10-14 23:08:2063 // Allow the main thread or another to initialize these bindings
64 // after instituting restrictions on I/O. Going forward they will
65 // likely be used in the browser process on most platforms. The
66 // one-time initialization cost is small, between 2 and 5 ms.
67 base::ThreadRestrictions::ScopedAllowIO allow_io;
68
[email protected]b9363b22010-06-09 22:06:1569 switch (implementation) {
[email protected]30aa5c1a2010-07-14 20:47:0470 case kGLImplementationOSMesaGL: {
[email protected]36a09792010-09-10 02:31:3971 FilePath module_path;
[email protected]d0498742010-09-20 20:27:0172 if (!PathService::Get(base::DIR_MODULE, &module_path)) {
73 LOG(ERROR) << "PathService::Get failed.";
[email protected]30aa5c1a2010-07-14 20:47:0474 return false;
[email protected]d0498742010-09-20 20:27:0175 }
[email protected]30aa5c1a2010-07-14 20:47:0476
[email protected]a246122752011-04-19 01:10:4877 base::NativeLibrary library = LoadLibrary(
78 module_path.Append("libosmesa.so"));
[email protected]84479322011-04-18 22:06:2279 if (!library)
[email protected]b9363b22010-06-09 22:06:1580 return false;
[email protected]0bec8e22010-06-21 22:20:0281
[email protected]30aa5c1a2010-07-14 20:47:0482 GLGetProcAddressProc get_proc_address =
83 reinterpret_cast<GLGetProcAddressProc>(
84 base::GetFunctionPointerFromNativeLibrary(
85 library, "OSMesaGetProcAddress"));
[email protected]1b2707bb2010-10-06 19:37:1686 if (!get_proc_address) {
[email protected]363b20d2011-01-14 22:54:1687 LOG(ERROR) << "OSMesaGetProcAddress not found.";
[email protected]1b2707bb2010-10-06 19:37:1688 base::UnloadNativeLibrary(library);
89 return false;
90 }
[email protected]b9363b22010-06-09 22:06:1591
[email protected]30aa5c1a2010-07-14 20:47:0492 SetGLGetProcAddressProc(get_proc_address);
93 AddGLNativeLibrary(library);
94 SetGLImplementation(kGLImplementationOSMesaGL);
[email protected]b9363b22010-06-09 22:06:1595
[email protected]30aa5c1a2010-07-14 20:47:0496 InitializeGLBindingsGL();
97 InitializeGLBindingsOSMESA();
98 break;
99 }
100 case kGLImplementationDesktopGL: {
[email protected]991c5682012-01-30 13:32:34101 base::NativeLibrary library = NULL;
102 const CommandLine* command_line = CommandLine::ForCurrentProcess();
103
104 if (command_line->HasSwitch(switches::kTestGLLib))
105 library = LoadLibrary(command_line->GetSwitchValueASCII(
106 switches::kTestGLLib).c_str());
107
108 if (!library) {
[email protected]7f4115e2011-10-26 20:09:45109#if defined(OS_OPENBSD)
[email protected]991c5682012-01-30 13:32:34110 library = LoadLibrary("libGL.so");
[email protected]7f4115e2011-10-26 20:09:45111#else
[email protected]991c5682012-01-30 13:32:34112 library = LoadLibrary("libGL.so.1");
[email protected]7f4115e2011-10-26 20:09:45113#endif
[email protected]991c5682012-01-30 13:32:34114 }
115
[email protected]84479322011-04-18 22:06:22116 if (!library)
[email protected]30aa5c1a2010-07-14 20:47:04117 return false;
[email protected]30aa5c1a2010-07-14 20:47:04118
119 GLGetProcAddressProc get_proc_address =
120 reinterpret_cast<GLGetProcAddressProc>(
121 base::GetFunctionPointerFromNativeLibrary(
122 library, "glXGetProcAddress"));
[email protected]1b2707bb2010-10-06 19:37:16123 if (!get_proc_address) {
124 LOG(ERROR) << "glxGetProcAddress not found.";
125 base::UnloadNativeLibrary(library);
126 return false;
127 }
[email protected]30aa5c1a2010-07-14 20:47:04128
129 SetGLGetProcAddressProc(get_proc_address);
130 AddGLNativeLibrary(library);
131 SetGLImplementation(kGLImplementationDesktopGL);
[email protected]b9363b22010-06-09 22:06:15132
133 InitializeGLBindingsGL();
134 InitializeGLBindingsGLX();
135 break;
[email protected]30aa5c1a2010-07-14 20:47:04136 }
137 case kGLImplementationEGLGLES2: {
[email protected]3733a142012-02-08 22:05:08138 base::NativeLibrary gles_library = LoadLibrary("libGLESv2.so.2");
[email protected]84479322011-04-18 22:06:22139 if (!gles_library)
[email protected]1b2707bb2010-10-06 19:37:16140 return false;
[email protected]3733a142012-02-08 22:05:08141 base::NativeLibrary egl_library = LoadLibrary("libEGL.so.1");
[email protected]91ac84f72011-06-22 19:48:02142 if (!egl_library) {
143 base::UnloadNativeLibrary(gles_library);
[email protected]0bec8e22010-06-21 22:20:02144 return false;
[email protected]91ac84f72011-06-22 19:48:02145 }
[email protected]0bec8e22010-06-21 22:20:02146
[email protected]30aa5c1a2010-07-14 20:47:04147 GLGetProcAddressProc get_proc_address =
148 reinterpret_cast<GLGetProcAddressProc>(
149 base::GetFunctionPointerFromNativeLibrary(
150 egl_library, "eglGetProcAddress"));
[email protected]1b2707bb2010-10-06 19:37:16151 if (!get_proc_address) {
152 LOG(ERROR) << "eglGetProcAddress not found.";
[email protected]30aa5c1a2010-07-14 20:47:04153 base::UnloadNativeLibrary(egl_library);
[email protected]1b2707bb2010-10-06 19:37:16154 base::UnloadNativeLibrary(gles_library);
[email protected]0bec8e22010-06-21 22:20:02155 return false;
156 }
157
[email protected]30aa5c1a2010-07-14 20:47:04158 SetGLGetProcAddressProc(get_proc_address);
159 AddGLNativeLibrary(egl_library);
160 AddGLNativeLibrary(gles_library);
161 SetGLImplementation(kGLImplementationEGLGLES2);
[email protected]0bec8e22010-06-21 22:20:02162
163 InitializeGLBindingsGL();
164 InitializeGLBindingsEGL();
165
166 // These two functions take single precision float rather than double
167 // precision float parameters in GLES.
168 ::gfx::g_glClearDepth = MarshalClearDepthToClearDepthf;
169 ::gfx::g_glDepthRange = MarshalDepthRangeToDepthRangef;
170 break;
[email protected]30aa5c1a2010-07-14 20:47:04171 }
172 case kGLImplementationMockGL: {
173 SetGLGetProcAddressProc(GetMockGLProcAddress);
174 SetGLImplementation(kGLImplementationMockGL);
[email protected]b9363b22010-06-09 22:06:15175 InitializeGLBindingsGL();
176 break;
[email protected]30aa5c1a2010-07-14 20:47:04177 }
[email protected]b9363b22010-06-09 22:06:15178 default:
179 return false;
180 }
181
182
183 return true;
184}
185
[email protected]6494823b2011-10-27 18:30:44186bool InitializeGLExtensionBindings(GLImplementation implementation,
187 GLContext* context) {
188 switch (implementation) {
189 case kGLImplementationOSMesaGL:
190 InitializeGLExtensionBindingsGL(context);
191 InitializeGLExtensionBindingsOSMESA(context);
192 break;
193 case kGLImplementationDesktopGL:
194 InitializeGLExtensionBindingsGL(context);
195 InitializeGLExtensionBindingsGLX(context);
196 break;
197 case kGLImplementationEGLGLES2:
198 InitializeGLExtensionBindingsGL(context);
199 InitializeGLExtensionBindingsEGL(context);
200 break;
201 case kGLImplementationMockGL:
202 InitializeGLExtensionBindingsGL(context);
203 break;
204 default:
205 return false;
206 }
207
208 return true;
209}
210
[email protected]218a5a22010-11-04 19:27:49211void InitializeDebugGLBindings() {
212 InitializeDebugGLBindingsEGL();
213 InitializeDebugGLBindingsGL();
214 InitializeDebugGLBindingsGLX();
215 InitializeDebugGLBindingsOSMESA();
216}
217
[email protected]0f5e8882011-11-08 22:29:38218void ClearGLBindings() {
219 ClearGLBindingsEGL();
220 ClearGLBindingsGL();
[email protected]0f5e8882011-11-08 22:29:38221 ClearGLBindingsGLX();
222 ClearGLBindingsOSMESA();
[email protected]0f5e8882011-11-08 22:29:38223 SetGLImplementation(kGLImplementationNone);
224
225 UnloadGLNativeLibraries();
226}
227
[email protected]b9363b22010-06-09 22:06:15228} // namespace gfx