Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(357)

Side by Side Diff: ui/gl/gl_implementation_win.cc

Issue 2099163003: Revert of Move static GL binding initialization to //ui/gl/init. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/gl/gl_implementation_ozone.cc ('k') | ui/gl/gl_implementation_x11.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gl/gl_implementation.h" 5 #include <vector>
6 6
7 #include "base/at_exit.h"
8 #include "base/base_paths.h"
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/files/file_path.h"
12 #include "base/lazy_instance.h"
13 #include "base/logging.h"
14 #include "base/native_library.h"
15 #include "base/path_service.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/threading/thread_restrictions.h"
18 #include "base/trace_event/trace_event.h"
19 #include "base/win/windows_version.h"
20 // TODO(jmadill): Apply to all platforms eventually
21 #include "ui/gl/angle_platform_impl.h"
22 #include "ui/gl/gl_bindings.h"
7 #include "ui/gl/gl_context_stub_with_extensions.h" 23 #include "ui/gl/gl_context_stub_with_extensions.h"
8 #include "ui/gl/gl_egl_api_implementation.h" 24 #include "ui/gl/gl_egl_api_implementation.h"
9 #include "ui/gl/gl_gl_api_implementation.h" 25 #include "ui/gl/gl_gl_api_implementation.h"
26 #include "ui/gl/gl_implementation.h"
10 #include "ui/gl/gl_osmesa_api_implementation.h" 27 #include "ui/gl/gl_osmesa_api_implementation.h"
28 #include "ui/gl/gl_surface_wgl.h"
11 #include "ui/gl/gl_wgl_api_implementation.h" 29 #include "ui/gl/gl_wgl_api_implementation.h"
12 30
31 #if defined(ENABLE_SWIFTSHADER)
32 #include "software_renderer.h"
33 #endif
34
13 namespace gl { 35 namespace gl {
14 36
37 namespace {
38
39 const wchar_t kD3DCompiler[] = L"D3DCompiler_47.dll";
40
41 void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
42 glClearDepthf(static_cast<GLclampf>(depth));
43 }
44
45 void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
46 GLclampd z_far) {
47 glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
48 }
49
50 bool LoadD3DXLibrary(const base::FilePath& module_path,
51 const base::FilePath::StringType& name) {
52 base::NativeLibrary library =
53 base::LoadNativeLibrary(base::FilePath(name), NULL);
54 if (!library) {
55 library = base::LoadNativeLibrary(module_path.Append(name), NULL);
56 if (!library) {
57 DVLOG(1) << name << " not found.";
58 return false;
59 }
60 }
61 return true;
62 }
63
64 // TODO(jmadill): Apply to all platforms eventually
65 base::LazyInstance<ANGLEPlatformImpl> g_angle_platform_impl =
66 LAZY_INSTANCE_INITIALIZER;
67
68 ANGLEPlatformShutdownFunc g_angle_platform_shutdown = nullptr;
69
70 } // namespace
71
15 void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) { 72 void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
16 impls->push_back(kGLImplementationEGLGLES2); 73 impls->push_back(kGLImplementationEGLGLES2);
17 impls->push_back(kGLImplementationDesktopGL); 74 impls->push_back(kGLImplementationDesktopGL);
18 impls->push_back(kGLImplementationOSMesaGL); 75 impls->push_back(kGLImplementationOSMesaGL);
19 } 76 }
20 77
78 bool InitializeStaticGLBindings(GLImplementation implementation) {
79 // Prevent reinitialization with a different implementation. Once the gpu
80 // unit tests have initialized with kGLImplementationMock, we don't want to
81 // later switch to another GL implementation.
82 DCHECK_EQ(kGLImplementationNone, GetGLImplementation());
83
84 // Allow the main thread or another to initialize these bindings
85 // after instituting restrictions on I/O. Going forward they will
86 // likely be used in the browser process on most platforms. The
87 // one-time initialization cost is small, between 2 and 5 ms.
88 base::ThreadRestrictions::ScopedAllowIO allow_io;
89
90 switch (implementation) {
91 case kGLImplementationOSMesaGL: {
92 base::FilePath module_path;
93 PathService::Get(base::DIR_MODULE, &module_path);
94 base::NativeLibrary library = base::LoadNativeLibrary(
95 module_path.Append(L"osmesa.dll"), NULL);
96 if (!library) {
97 PathService::Get(base::DIR_EXE, &module_path);
98 library = base::LoadNativeLibrary(
99 module_path.Append(L"osmesa.dll"), NULL);
100 if (!library) {
101 DVLOG(1) << "osmesa.dll not found";
102 return false;
103 }
104 }
105
106 GLGetProcAddressProc get_proc_address =
107 reinterpret_cast<GLGetProcAddressProc>(
108 base::GetFunctionPointerFromNativeLibrary(
109 library, "OSMesaGetProcAddress"));
110 if (!get_proc_address) {
111 DLOG(ERROR) << "OSMesaGetProcAddress not found.";
112 base::UnloadNativeLibrary(library);
113 return false;
114 }
115
116 SetGLGetProcAddressProc(get_proc_address);
117 AddGLNativeLibrary(library);
118 SetGLImplementation(kGLImplementationOSMesaGL);
119
120 InitializeStaticGLBindingsGL();
121 InitializeStaticGLBindingsOSMESA();
122 break;
123 }
124 case kGLImplementationEGLGLES2: {
125 base::FilePath module_path;
126 if (!PathService::Get(base::DIR_MODULE, &module_path))
127 return false;
128
129 // Attempt to load the D3DX shader compiler using the default search path
130 // and if that fails, using an absolute path. This is to ensure these DLLs
131 // are loaded before ANGLE is loaded in case they are not in the default
132 // search path.
133 LoadD3DXLibrary(module_path, kD3DCompiler);
134
135 base::FilePath gles_path;
136 const base::CommandLine* command_line =
137 base::CommandLine::ForCurrentProcess();
138 bool using_swift_shader =
139 command_line->GetSwitchValueASCII(switches::kUseGL) ==
140 kGLImplementationSwiftShaderName;
141 if (using_swift_shader) {
142 if (!command_line->HasSwitch(switches::kSwiftShaderPath))
143 return false;
144 gles_path =
145 command_line->GetSwitchValuePath(switches::kSwiftShaderPath);
146 // Preload library
147 LoadLibrary(L"ddraw.dll");
148 } else {
149 gles_path = module_path;
150 }
151
152 // Load libglesv2.dll before libegl.dll because the latter is dependent on
153 // the former and if there is another version of libglesv2.dll in the dll
154 // search path, it will get loaded instead.
155 base::NativeLibrary gles_library = base::LoadNativeLibrary(
156 gles_path.Append(L"libglesv2.dll"), NULL);
157 if (!gles_library) {
158 DVLOG(1) << "libglesv2.dll not found";
159 return false;
160 }
161
162 // When using EGL, first try eglGetProcAddress and then Windows
163 // GetProcAddress on both the EGL and GLES2 DLLs.
164 base::NativeLibrary egl_library = base::LoadNativeLibrary(
165 gles_path.Append(L"libegl.dll"), NULL);
166 if (!egl_library) {
167 DVLOG(1) << "libegl.dll not found.";
168 base::UnloadNativeLibrary(gles_library);
169 return false;
170 }
171
172 #if defined(ENABLE_SWIFTSHADER)
173 if (using_swift_shader) {
174 SetupSoftwareRenderer(gles_library);
175 }
176 #endif
177
178 if (!using_swift_shader) {
179 // Init ANGLE platform here, before we call GetPlatformDisplay().
180 // TODO(jmadill): Apply to all platforms eventually
181 ANGLEPlatformInitializeFunc angle_platform_init =
182 reinterpret_cast<ANGLEPlatformInitializeFunc>(
183 base::GetFunctionPointerFromNativeLibrary(
184 gles_library,
185 "ANGLEPlatformInitialize"));
186 if (angle_platform_init) {
187 angle_platform_init(&g_angle_platform_impl.Get());
188
189 g_angle_platform_shutdown =
190 reinterpret_cast<ANGLEPlatformShutdownFunc>(
191 base::GetFunctionPointerFromNativeLibrary(
192 gles_library,
193 "ANGLEPlatformShutdown"));
194 }
195 }
196
197 GLGetProcAddressProc get_proc_address =
198 reinterpret_cast<GLGetProcAddressProc>(
199 base::GetFunctionPointerFromNativeLibrary(
200 egl_library, "eglGetProcAddress"));
201 if (!get_proc_address) {
202 LOG(ERROR) << "eglGetProcAddress not found.";
203 base::UnloadNativeLibrary(egl_library);
204 base::UnloadNativeLibrary(gles_library);
205 return false;
206 }
207
208 SetGLGetProcAddressProc(get_proc_address);
209 AddGLNativeLibrary(egl_library);
210 AddGLNativeLibrary(gles_library);
211 SetGLImplementation(kGLImplementationEGLGLES2);
212
213 InitializeStaticGLBindingsGL();
214 InitializeStaticGLBindingsEGL();
215
216 // These two functions take single precision float rather than double
217 // precision float parameters in GLES.
218 ::gl::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf;
219 ::gl::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef;
220 break;
221 }
222 case kGLImplementationDesktopGL: {
223 base::NativeLibrary library = base::LoadNativeLibrary(
224 base::FilePath(L"opengl32.dll"), NULL);
225 if (!library) {
226 DVLOG(1) << "opengl32.dll not found";
227 return false;
228 }
229
230 GLGetProcAddressProc get_proc_address =
231 reinterpret_cast<GLGetProcAddressProc>(
232 base::GetFunctionPointerFromNativeLibrary(
233 library, "wglGetProcAddress"));
234 if (!get_proc_address) {
235 LOG(ERROR) << "wglGetProcAddress not found.";
236 base::UnloadNativeLibrary(library);
237 return false;
238 }
239
240 SetGLGetProcAddressProc(get_proc_address);
241 AddGLNativeLibrary(library);
242 SetGLImplementation(kGLImplementationDesktopGL);
243
244 // Initialize GL surface and get some functions needed for the context
245 // creation below.
246 if (!GLSurfaceWGL::InitializeOneOff()) {
247 LOG(ERROR) << "GLSurfaceWGL::InitializeOneOff failed.";
248 return false;
249 }
250 wglCreateContextProc wglCreateContextFn =
251 reinterpret_cast<wglCreateContextProc>(
252 GetGLProcAddress("wglCreateContext"));
253 wglDeleteContextProc wglDeleteContextFn =
254 reinterpret_cast<wglDeleteContextProc>(
255 GetGLProcAddress("wglDeleteContext"));
256 wglMakeCurrentProc wglMakeCurrentFn =
257 reinterpret_cast<wglMakeCurrentProc>(
258 GetGLProcAddress("wglMakeCurrent"));
259
260 // Create a temporary GL context to bind to entry points. This is needed
261 // because wglGetProcAddress is specified to return NULL for all queries
262 // if a context is not current in MSDN documentation, and the static
263 // bindings may contain functions that need to be queried with
264 // wglGetProcAddress. OpenGL wiki further warns that other error values
265 // than NULL could also be returned from wglGetProcAddress on some
266 // implementations, so we need to clear the WGL bindings and reinitialize
267 // them after the context creation.
268 HGLRC gl_context = wglCreateContextFn(GLSurfaceWGL::GetDisplayDC());
269 if (!gl_context) {
270 LOG(ERROR) << "Failed to create temporary context.";
271 return false;
272 }
273 if (!wglMakeCurrentFn(GLSurfaceWGL::GetDisplayDC(), gl_context)) {
274 LOG(ERROR) << "Failed to make temporary GL context current.";
275 wglDeleteContextFn(gl_context);
276 return false;
277 }
278
279 InitializeStaticGLBindingsGL();
280 InitializeStaticGLBindingsWGL();
281
282 wglMakeCurrent(NULL, NULL);
283 wglDeleteContext(gl_context);
284
285 break;
286 }
287 case kGLImplementationMockGL: {
288 SetGLImplementation(kGLImplementationMockGL);
289 InitializeStaticGLBindingsGL();
290 break;
291 }
292 default:
293 return false;
294 }
295
296 return true;
297 }
298
21 bool InitializeDynamicGLBindings(GLImplementation implementation, 299 bool InitializeDynamicGLBindings(GLImplementation implementation,
22 GLContext* context) { 300 GLContext* context) {
23 switch (implementation) { 301 switch (implementation) {
24 case kGLImplementationOSMesaGL: 302 case kGLImplementationOSMesaGL:
25 case kGLImplementationEGLGLES2: 303 case kGLImplementationEGLGLES2:
26 case kGLImplementationDesktopGL: 304 case kGLImplementationDesktopGL:
27 InitializeDynamicGLBindingsGL(context); 305 InitializeDynamicGLBindingsGL(context);
28 break; 306 break;
29 case kGLImplementationMockGL: 307 case kGLImplementationMockGL:
30 if (!context) { 308 if (!context) {
31 scoped_refptr<GLContextStubWithExtensions> mock_context( 309 scoped_refptr<GLContextStubWithExtensions> mock_context(
32 new GLContextStubWithExtensions()); 310 new GLContextStubWithExtensions());
33 mock_context->SetGLVersionString("3.0"); 311 mock_context->SetGLVersionString("3.0");
34 InitializeDynamicGLBindingsGL(mock_context.get()); 312 InitializeDynamicGLBindingsGL(mock_context.get());
35 } else { 313 } else
36 InitializeDynamicGLBindingsGL(context); 314 InitializeDynamicGLBindingsGL(context);
37 }
38 break; 315 break;
39 default: 316 default:
40 return false; 317 return false;
41 } 318 }
42 319
43 return true; 320 return true;
44 } 321 }
45 322
323 void InitializeDebugGLBindings() {
324 InitializeDebugGLBindingsEGL();
325 InitializeDebugGLBindingsGL();
326 InitializeDebugGLBindingsOSMESA();
327 InitializeDebugGLBindingsWGL();
328 }
329
330 void ClearGLBindings() {
331 // TODO(jmadill): Apply to all platforms eventually
332 if (g_angle_platform_shutdown) {
333 g_angle_platform_shutdown();
334 }
335
336 ClearGLBindingsEGL();
337 ClearGLBindingsGL();
338 ClearGLBindingsOSMESA();
339 ClearGLBindingsWGL();
340 SetGLImplementation(kGLImplementationNone);
341 UnloadGLNativeLibraries();
342 }
343
46 bool GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo* info) { 344 bool GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo* info) {
47 switch (GetGLImplementation()) { 345 switch (GetGLImplementation()) {
48 case kGLImplementationDesktopGL: 346 case kGLImplementationDesktopGL:
49 return GetGLWindowSystemBindingInfoWGL(info); 347 return GetGLWindowSystemBindingInfoWGL(info);
50 case kGLImplementationEGLGLES2: 348 case kGLImplementationEGLGLES2:
51 return GetGLWindowSystemBindingInfoEGL(info); 349 return GetGLWindowSystemBindingInfoEGL(info);
52 default: 350 default:
53 return false; 351 return false;
54 } 352 }
55 } 353 }
56 354
57 } // namespace gl 355 } // namespace gl
OLDNEW
« no previous file with comments | « ui/gl/gl_implementation_ozone.cc ('k') | ui/gl/gl_implementation_x11.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698