[email protected] | 991c568 | 2012-01-30 13:32:34 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | b9363b2 | 2010-06-09 22:06:15 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. | ||||
4 | |||||
[email protected] | 0bec8e2 | 2010-06-21 22:20:02 | [diff] [blame] | 5 | #include <vector> |
[email protected] | b9363b2 | 2010-06-09 22:06:15 | [diff] [blame] | 6 | |
[email protected] | 30aa5c1a | 2010-07-14 20:47:04 | [diff] [blame] | 7 | #include "base/command_line.h" |
[email protected] | 30aa5c1a | 2010-07-14 20:47:04 | [diff] [blame] | 8 | #include "base/logging.h" |
[email protected] | 6e318e0e | 2011-10-14 23:08:20 | [diff] [blame] | 9 | #include "base/threading/thread_restrictions.h" |
[email protected] | c9e2cbbb | 2012-05-12 21:17:27 | [diff] [blame] | 10 | #include "ui/gl/gl_bindings.h" |
[email protected] | a37d7ff | 2014-01-17 21:31:00 | [diff] [blame] | 11 | #include "ui/gl/gl_context_stub_with_extensions.h" |
[email protected] | b97c908 | 2012-10-25 17:21:38 | [diff] [blame] | 12 | #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] | c9e2cbbb | 2012-05-12 21:17:27 | [diff] [blame] | 15 | #include "ui/gl/gl_implementation.h" |
[email protected] | abeda1f | 2014-02-21 17:08:34 | [diff] [blame] | 16 | #include "ui/gl/gl_implementation_osmesa.h" |
[email protected] | b97c908 | 2012-10-25 17:21:38 | [diff] [blame] | 17 | #include "ui/gl/gl_osmesa_api_implementation.h" |
[email protected] | c9e2cbbb | 2012-05-12 21:17:27 | [diff] [blame] | 18 | #include "ui/gl/gl_switches.h" |
[email protected] | b9363b2 | 2010-06-09 22:06:15 | [diff] [blame] | 19 | |
20 | namespace gfx { | ||||
21 | namespace { | ||||
[email protected] | 0bec8e2 | 2010-06-21 22:20:02 | [diff] [blame] | 22 | |
23 | // TODO(piman): it should be Desktop GL marshalling from double to float. Today | ||||
24 | // on native GLES, we do float->double->float. | ||||
25 | void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) { | ||||
26 | glClearDepthf(static_cast<GLclampf>(depth)); | ||||
27 | } | ||||
28 | |||||
29 | void 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] | d7c2942 | 2014-03-11 06:08:57 | [diff] [blame] | 34 | #if defined(OS_OPENBSD) |
35 | const char kGLLibraryName[] = "libGL.so"; | ||||
36 | #else | ||||
37 | const char kGLLibraryName[] = "libGL.so.1"; | ||||
38 | #endif | ||||
39 | |||||
40 | const char kGLESv2LibraryName[] = "libGLESv2.so.2"; | ||||
41 | const char kEGLLibraryName[] = "libEGL.so.1"; | ||||
42 | |||||
[email protected] | 83afcbcc | 2012-07-27 03:06:27 | [diff] [blame] | 43 | } // namespace |
[email protected] | b9363b2 | 2010-06-09 22:06:15 | [diff] [blame] | 44 | |
[email protected] | 0f5e888 | 2011-11-08 22:29:38 | [diff] [blame] | 45 | void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) { |
[email protected] | 3c4b7ef | 2011-11-21 22:24:49 | [diff] [blame] | 46 | impls->push_back(kGLImplementationDesktopGL); |
[email protected] | 3c4b7ef | 2011-11-21 22:24:49 | [diff] [blame] | 47 | impls->push_back(kGLImplementationEGLGLES2); |
[email protected] | 70518b1 | 2011-11-22 01:39:12 | [diff] [blame] | 48 | impls->push_back(kGLImplementationOSMesaGL); |
[email protected] | 0f5e888 | 2011-11-08 22:29:38 | [diff] [blame] | 49 | } |
50 | |||||
[email protected] | a37d7ff | 2014-01-17 21:31:00 | [diff] [blame] | 51 | bool InitializeStaticGLBindings(GLImplementation implementation) { |
[email protected] | b9363b2 | 2010-06-09 22:06:15 | [diff] [blame] | 52 | // 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] | af7c5d9 | 2014-02-03 19:53:15 | [diff] [blame] | 55 | DCHECK_EQ(kGLImplementationNone, GetGLImplementation()); |
[email protected] | b9363b2 | 2010-06-09 22:06:15 | [diff] [blame] | 56 | |
[email protected] | 6e318e0e | 2011-10-14 23:08:20 | [diff] [blame] | 57 | // 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] | b9363b2 | 2010-06-09 22:06:15 | [diff] [blame] | 63 | switch (implementation) { |
[email protected] | 31e8a4f | 2013-06-29 01:13:27 | [diff] [blame] | 64 | case kGLImplementationOSMesaGL: |
[email protected] | a37d7ff | 2014-01-17 21:31:00 | [diff] [blame] | 65 | return InitializeStaticGLBindingsOSMesaGL(); |
marcheu | 1856f5d5 | 2015-04-04 01:42:53 | [diff] [blame] | 66 | case kGLImplementationDesktopGL: { |
[email protected] | 991c568 | 2012-01-30 13:32:34 | [diff] [blame] | 67 | base::NativeLibrary library = NULL; |
avi | 6b10fd0 | 2014-12-23 05:51:23 | [diff] [blame] | 68 | const base::CommandLine* command_line = |
69 | base::CommandLine::ForCurrentProcess(); | ||||
[email protected] | 991c568 | 2012-01-30 13:32:34 | [diff] [blame] | 70 | |
71 | if (command_line->HasSwitch(switches::kTestGLLib)) | ||||
[email protected] | 6bfbfe2 | 2014-05-01 21:54:37 | [diff] [blame] | 72 | library = LoadLibraryAndPrintError( |
73 | command_line->GetSwitchValueASCII(switches::kTestGLLib).c_str()); | ||||
[email protected] | 991c568 | 2012-01-30 13:32:34 | [diff] [blame] | 74 | |
75 | if (!library) { | ||||
[email protected] | 6bfbfe2 | 2014-05-01 21:54:37 | [diff] [blame] | 76 | library = LoadLibraryAndPrintError(kGLLibraryName); |
[email protected] | 991c568 | 2012-01-30 13:32:34 | [diff] [blame] | 77 | } |
78 | |||||
[email protected] | 6bfbfe2 | 2014-05-01 21:54:37 | [diff] [blame] | 79 | if (!library) |
[email protected] | 30aa5c1a | 2010-07-14 20:47:04 | [diff] [blame] | 80 | return false; |
[email protected] | 30aa5c1a | 2010-07-14 20:47:04 | [diff] [blame] | 81 | |
82 | GLGetProcAddressProc get_proc_address = | ||||
83 | reinterpret_cast<GLGetProcAddressProc>( | ||||
84 | base::GetFunctionPointerFromNativeLibrary( | ||||
85 | library, "glXGetProcAddress")); | ||||
[email protected] | 1b2707bb | 2010-10-06 19:37:16 | [diff] [blame] | 86 | if (!get_proc_address) { |
87 | LOG(ERROR) << "glxGetProcAddress not found."; | ||||
88 | base::UnloadNativeLibrary(library); | ||||
89 | return false; | ||||
90 | } | ||||
[email protected] | 30aa5c1a | 2010-07-14 20:47:04 | [diff] [blame] | 91 | |
92 | SetGLGetProcAddressProc(get_proc_address); | ||||
93 | AddGLNativeLibrary(library); | ||||
marcheu | 1856f5d5 | 2015-04-04 01:42:53 | [diff] [blame] | 94 | SetGLImplementation(kGLImplementationDesktopGL); |
[email protected] | b9363b2 | 2010-06-09 22:06:15 | [diff] [blame] | 95 | |
[email protected] | a37d7ff | 2014-01-17 21:31:00 | [diff] [blame] | 96 | InitializeStaticGLBindingsGL(); |
97 | InitializeStaticGLBindingsGLX(); | ||||
[email protected] | b9363b2 | 2010-06-09 22:06:15 | [diff] [blame] | 98 | break; |
[email protected] | 30aa5c1a | 2010-07-14 20:47:04 | [diff] [blame] | 99 | } |
100 | case kGLImplementationEGLGLES2: { | ||||
[email protected] | 6bfbfe2 | 2014-05-01 21:54:37 | [diff] [blame] | 101 | base::NativeLibrary gles_library = |
102 | LoadLibraryAndPrintError(kGLESv2LibraryName); | ||||
103 | if (!gles_library) | ||||
[email protected] | 1b2707bb | 2010-10-06 19:37:16 | [diff] [blame] | 104 | return false; |
[email protected] | 6bfbfe2 | 2014-05-01 21:54:37 | [diff] [blame] | 105 | base::NativeLibrary egl_library = |
106 | LoadLibraryAndPrintError(kEGLLibraryName); | ||||
[email protected] | 91ac84f7 | 2011-06-22 19:48:02 | [diff] [blame] | 107 | if (!egl_library) { |
108 | base::UnloadNativeLibrary(gles_library); | ||||
[email protected] | 0bec8e2 | 2010-06-21 22:20:02 | [diff] [blame] | 109 | return false; |
[email protected] | 91ac84f7 | 2011-06-22 19:48:02 | [diff] [blame] | 110 | } |
[email protected] | 0bec8e2 | 2010-06-21 22:20:02 | [diff] [blame] | 111 | |
[email protected] | 30aa5c1a | 2010-07-14 20:47:04 | [diff] [blame] | 112 | GLGetProcAddressProc get_proc_address = |
113 | reinterpret_cast<GLGetProcAddressProc>( | ||||
114 | base::GetFunctionPointerFromNativeLibrary( | ||||
115 | egl_library, "eglGetProcAddress")); | ||||
[email protected] | 1b2707bb | 2010-10-06 19:37:16 | [diff] [blame] | 116 | if (!get_proc_address) { |
117 | LOG(ERROR) << "eglGetProcAddress not found."; | ||||
[email protected] | 30aa5c1a | 2010-07-14 20:47:04 | [diff] [blame] | 118 | base::UnloadNativeLibrary(egl_library); |
[email protected] | 1b2707bb | 2010-10-06 19:37:16 | [diff] [blame] | 119 | base::UnloadNativeLibrary(gles_library); |
[email protected] | 0bec8e2 | 2010-06-21 22:20:02 | [diff] [blame] | 120 | return false; |
121 | } | ||||
122 | |||||
[email protected] | 30aa5c1a | 2010-07-14 20:47:04 | [diff] [blame] | 123 | SetGLGetProcAddressProc(get_proc_address); |
124 | AddGLNativeLibrary(egl_library); | ||||
125 | AddGLNativeLibrary(gles_library); | ||||
126 | SetGLImplementation(kGLImplementationEGLGLES2); | ||||
[email protected] | 0bec8e2 | 2010-06-21 22:20:02 | [diff] [blame] | 127 | |
[email protected] | a37d7ff | 2014-01-17 21:31:00 | [diff] [blame] | 128 | InitializeStaticGLBindingsGL(); |
129 | InitializeStaticGLBindingsEGL(); | ||||
[email protected] | 0bec8e2 | 2010-06-21 22:20:02 | [diff] [blame] | 130 | |
131 | // These two functions take single precision float rather than double | ||||
132 | // precision float parameters in GLES. | ||||
[email protected] | b97c908 | 2012-10-25 17:21:38 | [diff] [blame] | 133 | ::gfx::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf; |
134 | ::gfx::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef; | ||||
[email protected] | 0bec8e2 | 2010-06-21 22:20:02 | [diff] [blame] | 135 | break; |
[email protected] | 30aa5c1a | 2010-07-14 20:47:04 | [diff] [blame] | 136 | } |
137 | case kGLImplementationMockGL: { | ||||
[email protected] | 30aa5c1a | 2010-07-14 20:47:04 | [diff] [blame] | 138 | SetGLImplementation(kGLImplementationMockGL); |
[email protected] | a37d7ff | 2014-01-17 21:31:00 | [diff] [blame] | 139 | InitializeStaticGLBindingsGL(); |
[email protected] | b9363b2 | 2010-06-09 22:06:15 | [diff] [blame] | 140 | break; |
[email protected] | 30aa5c1a | 2010-07-14 20:47:04 | [diff] [blame] | 141 | } |
[email protected] | b9363b2 | 2010-06-09 22:06:15 | [diff] [blame] | 142 | default: |
143 | return false; | ||||
144 | } | ||||
145 | |||||
146 | |||||
147 | return true; | ||||
148 | } | ||||
149 | |||||
[email protected] | a37d7ff | 2014-01-17 21:31:00 | [diff] [blame] | 150 | bool InitializeDynamicGLBindings(GLImplementation implementation, |
[email protected] | 6494823b | 2011-10-27 18:30:44 | [diff] [blame] | 151 | GLContext* context) { |
152 | switch (implementation) { | ||||
153 | case kGLImplementationOSMesaGL: | ||||
marcheu | 1856f5d5 | 2015-04-04 01:42:53 | [diff] [blame] | 154 | case kGLImplementationDesktopGL: |
[email protected] | 6494823b | 2011-10-27 18:30:44 | [diff] [blame] | 155 | case kGLImplementationEGLGLES2: |
[email protected] | a37d7ff | 2014-01-17 21:31:00 | [diff] [blame] | 156 | InitializeDynamicGLBindingsGL(context); |
[email protected] | 6494823b | 2011-10-27 18:30:44 | [diff] [blame] | 157 | break; |
158 | case kGLImplementationMockGL: | ||||
[email protected] | a37d7ff | 2014-01-17 21:31:00 | [diff] [blame] | 159 | 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] | 6494823b | 2011-10-27 18:30:44 | [diff] [blame] | 166 | break; |
167 | default: | ||||
168 | return false; | ||||
169 | } | ||||
170 | |||||
171 | return true; | ||||
172 | } | ||||
173 | |||||
[email protected] | 218a5a2 | 2010-11-04 19:27:49 | [diff] [blame] | 174 | void InitializeDebugGLBindings() { |
175 | InitializeDebugGLBindingsEGL(); | ||||
176 | InitializeDebugGLBindingsGL(); | ||||
177 | InitializeDebugGLBindingsGLX(); | ||||
178 | InitializeDebugGLBindingsOSMESA(); | ||||
179 | } | ||||
180 | |||||
[email protected] | 0f5e888 | 2011-11-08 22:29:38 | [diff] [blame] | 181 | void ClearGLBindings() { |
182 | ClearGLBindingsEGL(); | ||||
183 | ClearGLBindingsGL(); | ||||
[email protected] | 0f5e888 | 2011-11-08 22:29:38 | [diff] [blame] | 184 | ClearGLBindingsGLX(); |
185 | ClearGLBindingsOSMESA(); | ||||
[email protected] | 0f5e888 | 2011-11-08 22:29:38 | [diff] [blame] | 186 | SetGLImplementation(kGLImplementationNone); |
187 | |||||
188 | UnloadGLNativeLibraries(); | ||||
189 | } | ||||
190 | |||||
[email protected] | 4589503 | 2013-05-30 17:06:43 | [diff] [blame] | 191 | bool GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo* info) { |
192 | switch (GetGLImplementation()) { | ||||
193 | case kGLImplementationDesktopGL: | ||||
[email protected] | 4589503 | 2013-05-30 17:06:43 | [diff] [blame] | 194 | return GetGLWindowSystemBindingInfoGLX(info); |
195 | case kGLImplementationEGLGLES2: | ||||
196 | return GetGLWindowSystemBindingInfoEGL(info); | ||||
197 | default: | ||||
198 | return false; | ||||
199 | } | ||||
200 | return false; | ||||
201 | } | ||||
202 | |||||
[email protected] | b9363b2 | 2010-06-09 22:06:15 | [diff] [blame] | 203 | } // namespace gfx |