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.
5 #include "ui/gl/gl_surface.h"
10 #include "base/command_line.h"
11 #include "base/debug/trace_event.h"
12 #include "base/lazy_instance.h"
13 #include "base/logging.h"
14 #include "base/threading/thread_local.h"
15 #include "ui/gl/gl_context.h"
16 #include "ui/gl/gl_implementation.h"
17 #include "ui/gl/gl_switches.h"
26 base::LazyInstance<base::ThreadLocalPointer<GLSurface> >::Leaky
27 current_surface_ = LAZY_INSTANCE_INITIALIZER;
31 bool GLSurface::InitializeOneOff() {
32 DCHECK_EQ(kGLImplementationNone, GetGLImplementation());
34 TRACE_EVENT0("gpu", "GLSurface::InitializeOneOff");
36 std::vector<GLImplementation> allowed_impls;
37 GetAllowedGLImplementations(&allowed_impls);
38 DCHECK(!allowed_impls.empty());
40 CommandLine* cmd = CommandLine::ForCurrentProcess();
42 // The default implementation is always the first one in list.
43 GLImplementation impl = allowed_impls[0];
44 bool fallback_to_osmesa = false;
45 if (cmd->HasSwitch(switches::kOverrideUseGLWithOSMesaForTests)) {
46 impl = kGLImplementationOSMesaGL;
47 } else if (cmd->HasSwitch(switches::kUseGL)) {
48 std::string requested_implementation_name =
49 cmd->GetSwitchValueASCII(switches::kUseGL);
50 if (requested_implementation_name == "any") {
51 fallback_to_osmesa = true;
52 } else if (requested_implementation_name == "swiftshader") {
53 impl = kGLImplementationEGLGLES2;
55 impl = GetNamedGLImplementation(requested_implementation_name);
56 if (std::find(allowed_impls.begin(),
58 impl) == allowed_impls.end()) {
59 LOG(ERROR) << "Requested GL implementation is not available.";
65 bool gpu_service_logging = cmd->HasSwitch(switches::kEnableGPUServiceLogging);
66 bool disable_gl_drawing = cmd->HasSwitch(switches::kDisableGLDrawingForTests);
68 return InitializeOneOffImplementation(
69 impl, fallback_to_osmesa, gpu_service_logging, disable_gl_drawing);
73 bool GLSurface::InitializeOneOffImplementation(GLImplementation impl,
74 bool fallback_to_osmesa,
75 bool gpu_service_logging,
76 bool disable_gl_drawing) {
78 InitializeStaticGLBindings(impl) && InitializeOneOffInternal();
79 if (!initialized && fallback_to_osmesa) {
81 initialized = InitializeStaticGLBindings(kGLImplementationOSMesaGL) &&
82 InitializeOneOffInternal();
89 << GetGLImplementationName(GetGLImplementation())
90 << " GL implementation.";
91 if (gpu_service_logging)
92 InitializeDebugGLBindings();
93 if (disable_gl_drawing)
94 InitializeNullDrawGLBindings();
100 void GLSurface::InitializeOneOffForTests() {
101 DCHECK_EQ(kGLImplementationNone, GetGLImplementation());
107 bool use_osmesa = true;
109 // We usually use OSMesa as this works on all bots. The command line can
110 // override this behaviour to use hardware GL.
111 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGpuInTests))
114 #if defined(OS_ANDROID)
115 // On Android we always use hardware GL.
119 std::vector<GLImplementation> allowed_impls;
120 GetAllowedGLImplementations(&allowed_impls);
121 DCHECK(!allowed_impls.empty());
123 GLImplementation impl = allowed_impls[0];
125 impl = kGLImplementationOSMesaGL;
127 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL))
128 << "kUseGL has not effect in tests";
130 bool fallback_to_osmesa = false;
131 bool gpu_service_logging = false;
132 bool disable_gl_drawing = true;
134 CHECK(InitializeOneOffImplementation(
135 impl, fallback_to_osmesa, gpu_service_logging, disable_gl_drawing));
139 void GLSurface::InitializeOneOffWithMockBindingsForTests() {
140 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL))
141 << "kUseGL has not effect in tests";
143 // This method may be called multiple times in the same process to set up
144 // mock bindings in different ways.
147 bool fallback_to_osmesa = false;
148 bool gpu_service_logging = false;
149 bool disable_gl_drawing = false;
151 CHECK(InitializeOneOffImplementation(kGLImplementationMockGL,
154 disable_gl_drawing));
158 void GLSurface::InitializeDynamicMockBindingsForTests(GLContext* context) {
159 CHECK(InitializeDynamicGLBindings(kGLImplementationMockGL, context));
162 GLSurface::GLSurface() {}
164 bool GLSurface::Initialize() {
168 bool GLSurface::Resize(const gfx::Size& size) {
173 bool GLSurface::Recreate() {
178 bool GLSurface::DeferDraws() {
182 bool GLSurface::SupportsPostSubBuffer() {
186 unsigned int GLSurface::GetBackingFrameBufferObject() {
190 bool GLSurface::PostSubBuffer(int x, int y, int width, int height) {
194 bool GLSurface::OnMakeCurrent(GLContext* context) {
198 bool GLSurface::SetBackbufferAllocation(bool allocated) {
202 void GLSurface::SetFrontbufferAllocation(bool allocated) {
205 void* GLSurface::GetShareHandle() {
210 void* GLSurface::GetDisplay() {
215 void* GLSurface::GetConfig() {
220 unsigned GLSurface::GetFormat() {
225 VSyncProvider* GLSurface::GetVSyncProvider() {
229 GLSurface* GLSurface::GetCurrent() {
230 return current_surface_.Pointer()->Get();
233 GLSurface::~GLSurface() {
234 if (GetCurrent() == this)
238 void GLSurface::SetCurrent(GLSurface* surface) {
239 current_surface_.Pointer()->Set(surface);
242 bool GLSurface::ExtensionsContain(const char* c_extensions, const char* name) {
246 std::string extensions(c_extensions);
249 std::string delimited_name(name);
250 delimited_name += " ";
252 return extensions.find(delimited_name) != std::string::npos;
255 GLSurfaceAdapter::GLSurfaceAdapter(GLSurface* surface) : surface_(surface) {}
257 bool GLSurfaceAdapter::Initialize() {
258 return surface_->Initialize();
261 void GLSurfaceAdapter::Destroy() {
265 bool GLSurfaceAdapter::Resize(const gfx::Size& size) {
266 return surface_->Resize(size);
269 bool GLSurfaceAdapter::Recreate() {
270 return surface_->Recreate();
273 bool GLSurfaceAdapter::DeferDraws() {
274 return surface_->DeferDraws();
277 bool GLSurfaceAdapter::IsOffscreen() {
278 return surface_->IsOffscreen();
281 bool GLSurfaceAdapter::SwapBuffers() {
282 return surface_->SwapBuffers();
285 bool GLSurfaceAdapter::PostSubBuffer(int x, int y, int width, int height) {
286 return surface_->PostSubBuffer(x, y, width, height);
289 bool GLSurfaceAdapter::SupportsPostSubBuffer() {
290 return surface_->SupportsPostSubBuffer();
293 gfx::Size GLSurfaceAdapter::GetSize() {
294 return surface_->GetSize();
297 void* GLSurfaceAdapter::GetHandle() {
298 return surface_->GetHandle();
301 unsigned int GLSurfaceAdapter::GetBackingFrameBufferObject() {
302 return surface_->GetBackingFrameBufferObject();
305 bool GLSurfaceAdapter::OnMakeCurrent(GLContext* context) {
306 return surface_->OnMakeCurrent(context);
309 bool GLSurfaceAdapter::SetBackbufferAllocation(bool allocated) {
310 return surface_->SetBackbufferAllocation(allocated);
313 void GLSurfaceAdapter::SetFrontbufferAllocation(bool allocated) {
314 surface_->SetFrontbufferAllocation(allocated);
317 void* GLSurfaceAdapter::GetShareHandle() {
318 return surface_->GetShareHandle();
321 void* GLSurfaceAdapter::GetDisplay() {
322 return surface_->GetDisplay();
325 void* GLSurfaceAdapter::GetConfig() {
326 return surface_->GetConfig();
329 unsigned GLSurfaceAdapter::GetFormat() {
330 return surface_->GetFormat();
333 VSyncProvider* GLSurfaceAdapter::GetVSyncProvider() {
334 return surface_->GetVSyncProvider();
337 GLSurfaceAdapter::~GLSurfaceAdapter() {}