• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include <vector>
6 
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "base/threading/thread_restrictions.h"
10 #include "ui/gl/gl_bindings.h"
11 #include "ui/gl/gl_egl_api_implementation.h"
12 #include "ui/gl/gl_gl_api_implementation.h"
13 #include "ui/gl/gl_glx_api_implementation.h"
14 #include "ui/gl/gl_implementation.h"
15 #include "ui/gl/gl_implementation_linux.h"
16 #include "ui/gl/gl_osmesa_api_implementation.h"
17 #include "ui/gl/gl_switches.h"
18 
19 namespace gfx {
20 namespace {
21 
22 // TODO(piman): it should be Desktop GL marshalling from double to float. Today
23 // on native GLES, we do float->double->float.
MarshalClearDepthToClearDepthf(GLclampd depth)24 void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
25   glClearDepthf(static_cast<GLclampf>(depth));
26 }
27 
MarshalDepthRangeToDepthRangef(GLclampd z_near,GLclampd z_far)28 void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
29                                                     GLclampd z_far) {
30   glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
31 }
32 
33 }  // namespace
34 
GetAllowedGLImplementations(std::vector<GLImplementation> * impls)35 void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
36   impls->push_back(kGLImplementationDesktopGL);
37   impls->push_back(kGLImplementationEGLGLES2);
38   impls->push_back(kGLImplementationOSMesaGL);
39 }
40 
InitializeGLBindings(GLImplementation implementation)41 bool InitializeGLBindings(GLImplementation implementation) {
42   // Prevent reinitialization with a different implementation. Once the gpu
43   // unit tests have initialized with kGLImplementationMock, we don't want to
44   // later switch to another GL implementation.
45   if (GetGLImplementation() != kGLImplementationNone)
46     return true;
47 
48   // Allow the main thread or another to initialize these bindings
49   // after instituting restrictions on I/O. Going forward they will
50   // likely be used in the browser process on most platforms. The
51   // one-time initialization cost is small, between 2 and 5 ms.
52   base::ThreadRestrictions::ScopedAllowIO allow_io;
53 
54   switch (implementation) {
55     case kGLImplementationOSMesaGL:
56       return InitializeGLBindingsOSMesaGL();
57     case kGLImplementationDesktopGL: {
58       base::NativeLibrary library = NULL;
59       const CommandLine* command_line = CommandLine::ForCurrentProcess();
60 
61       if (command_line->HasSwitch(switches::kTestGLLib))
62         library = LoadLibrary(command_line->GetSwitchValueASCII(
63             switches::kTestGLLib).c_str());
64 
65       if (!library) {
66 #if defined(OS_OPENBSD)
67         library = LoadLibrary("libGL.so");
68 #else
69         library = LoadLibrary("libGL.so.1");
70 #endif
71       }
72 
73       if (!library)
74         return false;
75 
76       GLGetProcAddressProc get_proc_address =
77           reinterpret_cast<GLGetProcAddressProc>(
78               base::GetFunctionPointerFromNativeLibrary(
79                   library, "glXGetProcAddress"));
80       if (!get_proc_address) {
81         LOG(ERROR) << "glxGetProcAddress not found.";
82         base::UnloadNativeLibrary(library);
83         return false;
84       }
85 
86       SetGLGetProcAddressProc(get_proc_address);
87       AddGLNativeLibrary(library);
88       SetGLImplementation(kGLImplementationDesktopGL);
89 
90       InitializeGLBindingsGL();
91       InitializeGLBindingsGLX();
92       break;
93     }
94     case kGLImplementationEGLGLES2: {
95       base::NativeLibrary gles_library = LoadLibrary("libGLESv2.so.2");
96       if (!gles_library)
97         return false;
98       base::NativeLibrary egl_library = LoadLibrary("libEGL.so.1");
99       if (!egl_library) {
100         base::UnloadNativeLibrary(gles_library);
101         return false;
102       }
103 
104       GLGetProcAddressProc get_proc_address =
105           reinterpret_cast<GLGetProcAddressProc>(
106               base::GetFunctionPointerFromNativeLibrary(
107                   egl_library, "eglGetProcAddress"));
108       if (!get_proc_address) {
109         LOG(ERROR) << "eglGetProcAddress not found.";
110         base::UnloadNativeLibrary(egl_library);
111         base::UnloadNativeLibrary(gles_library);
112         return false;
113       }
114 
115       SetGLGetProcAddressProc(get_proc_address);
116       AddGLNativeLibrary(egl_library);
117       AddGLNativeLibrary(gles_library);
118       SetGLImplementation(kGLImplementationEGLGLES2);
119 
120       InitializeGLBindingsGL();
121       InitializeGLBindingsEGL();
122 
123       // These two functions take single precision float rather than double
124       // precision float parameters in GLES.
125       ::gfx::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf;
126       ::gfx::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef;
127       break;
128     }
129     case kGLImplementationMockGL: {
130       SetGLGetProcAddressProc(GetMockGLProcAddress);
131       SetGLImplementation(kGLImplementationMockGL);
132       InitializeGLBindingsGL();
133       break;
134     }
135     default:
136       return false;
137   }
138 
139 
140   return true;
141 }
142 
InitializeGLExtensionBindings(GLImplementation implementation,GLContext * context)143 bool InitializeGLExtensionBindings(GLImplementation implementation,
144     GLContext* context) {
145   switch (implementation) {
146     case kGLImplementationOSMesaGL:
147       InitializeGLExtensionBindingsGL(context);
148       InitializeGLExtensionBindingsOSMESA(context);
149       break;
150     case kGLImplementationDesktopGL:
151       InitializeGLExtensionBindingsGL(context);
152       InitializeGLExtensionBindingsGLX(context);
153       break;
154     case kGLImplementationEGLGLES2:
155       InitializeGLExtensionBindingsGL(context);
156       InitializeGLExtensionBindingsEGL(context);
157       break;
158     case kGLImplementationMockGL:
159       InitializeGLExtensionBindingsGL(context);
160       break;
161     default:
162       return false;
163   }
164 
165   return true;
166 }
167 
InitializeDebugGLBindings()168 void InitializeDebugGLBindings() {
169   InitializeDebugGLBindingsEGL();
170   InitializeDebugGLBindingsGL();
171   InitializeDebugGLBindingsGLX();
172   InitializeDebugGLBindingsOSMESA();
173 }
174 
ClearGLBindings()175 void ClearGLBindings() {
176   ClearGLBindingsEGL();
177   ClearGLBindingsGL();
178   ClearGLBindingsGLX();
179   ClearGLBindingsOSMESA();
180   SetGLImplementation(kGLImplementationNone);
181 
182   UnloadGLNativeLibraries();
183 }
184 
GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo * info)185 bool GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo* info) {
186   switch (GetGLImplementation()) {
187     case kGLImplementationDesktopGL:
188       return GetGLWindowSystemBindingInfoGLX(info);
189     case kGLImplementationEGLGLES2:
190       return GetGLWindowSystemBindingInfoEGL(info);
191     default:
192       return false;
193   }
194   return false;
195 }
196 
197 }  // namespace gfx
198