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

Side by Side Diff: ui/gl/init/gl_initializer_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/init/gl_initializer_ozone.cc ('k') | ui/gl/init/gl_initializer_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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/init/gl_initializer.h" 5 #include "ui/gl/init/gl_initializer.h"
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" 7 #include "base/logging.h"
14 #include "base/native_library.h" 8 #include "ui/gl/gl_implementation.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"
23 #include "ui/gl/gl_egl_api_implementation.h"
24 #include "ui/gl/gl_gl_api_implementation.h"
25 #include "ui/gl/gl_osmesa_api_implementation.h"
26 #include "ui/gl/gl_surface_egl.h" 9 #include "ui/gl/gl_surface_egl.h"
27 #include "ui/gl/gl_surface_wgl.h" 10 #include "ui/gl/gl_surface_wgl.h"
28 #include "ui/gl/gl_wgl_api_implementation.h"
29 #include "ui/gl/vsync_provider_win.h" 11 #include "ui/gl/vsync_provider_win.h"
30 12
31 #if defined(ENABLE_SWIFTSHADER)
32 #include "software_renderer.h"
33 #endif
34
35 namespace gl { 13 namespace gl {
36 namespace init { 14 namespace init {
37 15
38 namespace {
39
40 const wchar_t kD3DCompiler[] = L"D3DCompiler_47.dll";
41
42 // TODO(jmadill): Apply to all platforms eventually
43 base::LazyInstance<ANGLEPlatformImpl> g_angle_platform_impl =
44 LAZY_INSTANCE_INITIALIZER;
45
46 ANGLEPlatformShutdownFunc g_angle_platform_shutdown = nullptr;
47
48 bool LoadD3DXLibrary(const base::FilePath& module_path,
49 const base::FilePath::StringType& name) {
50 base::NativeLibrary library =
51 base::LoadNativeLibrary(base::FilePath(name), nullptr);
52 if (!library) {
53 library = base::LoadNativeLibrary(module_path.Append(name), nullptr);
54 if (!library) {
55 DVLOG(1) << name << " not found.";
56 return false;
57 }
58 }
59 return true;
60 }
61
62 bool InitializeStaticOSMesaInternal() {
63 base::FilePath module_path;
64 PathService::Get(base::DIR_MODULE, &module_path);
65 base::NativeLibrary library =
66 base::LoadNativeLibrary(module_path.Append(L"osmesa.dll"), nullptr);
67 if (!library) {
68 PathService::Get(base::DIR_EXE, &module_path);
69 library =
70 base::LoadNativeLibrary(module_path.Append(L"osmesa.dll"), nullptr);
71 if (!library) {
72 DVLOG(1) << "osmesa.dll not found";
73 return false;
74 }
75 }
76
77 GLGetProcAddressProc get_proc_address =
78 reinterpret_cast<GLGetProcAddressProc>(
79 base::GetFunctionPointerFromNativeLibrary(library,
80 "OSMesaGetProcAddress"));
81 if (!get_proc_address) {
82 DLOG(ERROR) << "OSMesaGetProcAddress not found.";
83 base::UnloadNativeLibrary(library);
84 return false;
85 }
86
87 SetGLGetProcAddressProc(get_proc_address);
88 AddGLNativeLibrary(library);
89 SetGLImplementation(kGLImplementationOSMesaGL);
90
91 InitializeStaticGLBindingsGL();
92 InitializeStaticGLBindingsOSMESA();
93
94 return true;
95 }
96
97 bool InitializeStaticEGLInternal() {
98 base::FilePath module_path;
99 if (!PathService::Get(base::DIR_MODULE, &module_path))
100 return false;
101
102 // Attempt to load the D3DX shader compiler using the default search path
103 // and if that fails, using an absolute path. This is to ensure these DLLs
104 // are loaded before ANGLE is loaded in case they are not in the default
105 // search path.
106 LoadD3DXLibrary(module_path, kD3DCompiler);
107
108 base::FilePath gles_path;
109 const base::CommandLine* command_line =
110 base::CommandLine::ForCurrentProcess();
111 bool using_swift_shader =
112 command_line->GetSwitchValueASCII(switches::kUseGL) ==
113 kGLImplementationSwiftShaderName;
114 if (using_swift_shader) {
115 if (!command_line->HasSwitch(switches::kSwiftShaderPath))
116 return false;
117 gles_path = command_line->GetSwitchValuePath(switches::kSwiftShaderPath);
118 // Preload library
119 LoadLibrary(L"ddraw.dll");
120 } else {
121 gles_path = module_path;
122 }
123
124 // Load libglesv2.dll before libegl.dll because the latter is dependent on
125 // the former and if there is another version of libglesv2.dll in the dll
126 // search path, it will get loaded instead.
127 base::NativeLibrary gles_library =
128 base::LoadNativeLibrary(gles_path.Append(L"libglesv2.dll"), nullptr);
129 if (!gles_library) {
130 DVLOG(1) << "libglesv2.dll not found";
131 return false;
132 }
133
134 // When using EGL, first try eglGetProcAddress and then Windows
135 // GetProcAddress on both the EGL and GLES2 DLLs.
136 base::NativeLibrary egl_library =
137 base::LoadNativeLibrary(gles_path.Append(L"libegl.dll"), nullptr);
138 if (!egl_library) {
139 DVLOG(1) << "libegl.dll not found.";
140 base::UnloadNativeLibrary(gles_library);
141 return false;
142 }
143
144 #if defined(ENABLE_SWIFTSHADER)
145 if (using_swift_shader) {
146 SetupSoftwareRenderer(gles_library);
147 }
148 #endif
149
150 if (!using_swift_shader) {
151 // Init ANGLE platform here, before we call GetPlatformDisplay().
152 // TODO(jmadill): Apply to all platforms eventually
153 ANGLEPlatformInitializeFunc angle_platform_init =
154 reinterpret_cast<ANGLEPlatformInitializeFunc>(
155 base::GetFunctionPointerFromNativeLibrary(
156 gles_library, "ANGLEPlatformInitialize"));
157 if (angle_platform_init) {
158 angle_platform_init(&g_angle_platform_impl.Get());
159
160 g_angle_platform_shutdown = reinterpret_cast<ANGLEPlatformShutdownFunc>(
161 base::GetFunctionPointerFromNativeLibrary(gles_library,
162 "ANGLEPlatformShutdown"));
163 }
164 }
165
166 GLGetProcAddressProc get_proc_address =
167 reinterpret_cast<GLGetProcAddressProc>(
168 base::GetFunctionPointerFromNativeLibrary(egl_library,
169 "eglGetProcAddress"));
170 if (!get_proc_address) {
171 LOG(ERROR) << "eglGetProcAddress not found.";
172 base::UnloadNativeLibrary(egl_library);
173 base::UnloadNativeLibrary(gles_library);
174 return false;
175 }
176
177 SetGLGetProcAddressProc(get_proc_address);
178 AddGLNativeLibrary(egl_library);
179 AddGLNativeLibrary(gles_library);
180 SetGLImplementation(kGLImplementationEGLGLES2);
181
182 InitializeStaticGLBindingsGL();
183 InitializeStaticGLBindingsEGL();
184
185 return true;
186 }
187
188 bool InitializeStaticWGLInternal() {
189 base::NativeLibrary library =
190 base::LoadNativeLibrary(base::FilePath(L"opengl32.dll"), nullptr);
191 if (!library) {
192 DVLOG(1) << "opengl32.dll not found";
193 return false;
194 }
195
196 GLGetProcAddressProc get_proc_address =
197 reinterpret_cast<GLGetProcAddressProc>(
198 base::GetFunctionPointerFromNativeLibrary(library,
199 "wglGetProcAddress"));
200 if (!get_proc_address) {
201 LOG(ERROR) << "wglGetProcAddress not found.";
202 base::UnloadNativeLibrary(library);
203 return false;
204 }
205
206 SetGLGetProcAddressProc(get_proc_address);
207 AddGLNativeLibrary(library);
208 SetGLImplementation(kGLImplementationDesktopGL);
209
210 // Initialize GL surface and get some functions needed for the context
211 // creation below.
212 if (!GLSurfaceWGL::InitializeOneOff()) {
213 LOG(ERROR) << "GLSurfaceWGL::InitializeOneOff failed.";
214 return false;
215 }
216 wglCreateContextProc wglCreateContextFn =
217 reinterpret_cast<wglCreateContextProc>(
218 GetGLProcAddress("wglCreateContext"));
219 wglDeleteContextProc wglDeleteContextFn =
220 reinterpret_cast<wglDeleteContextProc>(
221 GetGLProcAddress("wglDeleteContext"));
222 wglMakeCurrentProc wglMakeCurrentFn =
223 reinterpret_cast<wglMakeCurrentProc>(GetGLProcAddress("wglMakeCurrent"));
224
225 // Create a temporary GL context to bind to entry points. This is needed
226 // because wglGetProcAddress is specified to return nullptr for all queries
227 // if a context is not current in MSDN documentation, and the static
228 // bindings may contain functions that need to be queried with
229 // wglGetProcAddress. OpenGL wiki further warns that other error values
230 // than nullptr could also be returned from wglGetProcAddress on some
231 // implementations, so we need to clear the WGL bindings and reinitialize
232 // them after the context creation.
233 HGLRC gl_context = wglCreateContextFn(GLSurfaceWGL::GetDisplayDC());
234 if (!gl_context) {
235 LOG(ERROR) << "Failed to create temporary context.";
236 return false;
237 }
238 if (!wglMakeCurrentFn(GLSurfaceWGL::GetDisplayDC(), gl_context)) {
239 LOG(ERROR) << "Failed to make temporary GL context current.";
240 wglDeleteContextFn(gl_context);
241 return false;
242 }
243
244 InitializeStaticGLBindingsGL();
245 InitializeStaticGLBindingsWGL();
246
247 wglMakeCurrent(nullptr, nullptr);
248 wglDeleteContext(gl_context);
249
250 return true;
251 }
252
253 } // namespace
254
255 bool InitializeGLOneOffPlatform() { 16 bool InitializeGLOneOffPlatform() {
256 VSyncProviderWin::InitializeOneOff(); 17 VSyncProviderWin::InitializeOneOff();
257 18
258 switch (GetGLImplementation()) { 19 switch (GetGLImplementation()) {
259 case kGLImplementationDesktopGL: 20 case kGLImplementationDesktopGL:
260 if (!GLSurfaceWGL::InitializeOneOff()) { 21 if (!GLSurfaceWGL::InitializeOneOff()) {
261 LOG(ERROR) << "GLSurfaceWGL::InitializeOneOff failed."; 22 LOG(ERROR) << "GLSurfaceWGL::InitializeOneOff failed.";
262 return false; 23 return false;
263 } 24 }
264 break; 25 break;
265 case kGLImplementationEGLGLES2: 26 case kGLImplementationEGLGLES2:
266 if (!GLSurfaceEGL::InitializeOneOff()) { 27 if (!GLSurfaceEGL::InitializeOneOff()) {
267 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed."; 28 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed.";
268 return false; 29 return false;
269 } 30 }
270 break; 31 break;
271 case kGLImplementationOSMesaGL: 32 case kGLImplementationOSMesaGL:
272 case kGLImplementationMockGL: 33 case kGLImplementationMockGL:
273 break; 34 break;
274 default: 35 default:
275 NOTREACHED(); 36 NOTREACHED();
276 } 37 }
277 return true; 38 return true;
278 } 39 }
279 40
280 bool InitializeStaticGLBindings(GLImplementation implementation) {
281 // Prevent reinitialization with a different implementation. Once the gpu
282 // unit tests have initialized with kGLImplementationMock, we don't want to
283 // later switch to another GL implementation.
284 DCHECK_EQ(kGLImplementationNone, GetGLImplementation());
285
286 // Allow the main thread or another to initialize these bindings
287 // after instituting restrictions on I/O. Going forward they will
288 // likely be used in the browser process on most platforms. The
289 // one-time initialization cost is small, between 2 and 5 ms.
290 base::ThreadRestrictions::ScopedAllowIO allow_io;
291
292 switch (implementation) {
293 case kGLImplementationOSMesaGL:
294 return InitializeStaticOSMesaInternal();
295 case kGLImplementationEGLGLES2:
296 return InitializeStaticEGLInternal();
297 case kGLImplementationDesktopGL:
298 return InitializeStaticWGLInternal();
299 case kGLImplementationMockGL:
300 SetGLImplementation(kGLImplementationMockGL);
301 InitializeStaticGLBindingsGL();
302 return true;
303 default:
304 NOTREACHED();
305 }
306
307 return false;
308 }
309
310 void InitializeDebugGLBindings() {
311 InitializeDebugGLBindingsEGL();
312 InitializeDebugGLBindingsGL();
313 InitializeDebugGLBindingsOSMESA();
314 InitializeDebugGLBindingsWGL();
315 }
316
317 void ClearGLBindingsPlatform() {
318 // TODO(jmadill): Apply to all platforms eventually
319 if (g_angle_platform_shutdown) {
320 g_angle_platform_shutdown();
321 }
322
323 ClearGLBindingsEGL();
324 ClearGLBindingsGL();
325 ClearGLBindingsOSMESA();
326 ClearGLBindingsWGL();
327 }
328
329 } // namespace init 41 } // namespace init
330 } // namespace gl 42 } // namespace gl
OLDNEW
« no previous file with comments | « ui/gl/init/gl_initializer_ozone.cc ('k') | ui/gl/init/gl_initializer_x11.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698