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 base::CommandLine
* cmd
= base::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 (base::CommandLine::ForCurrentProcess()->HasSwitch(
112 switches::kUseGpuInTests
))
115 #if defined(OS_ANDROID)
116 // On Android we always use hardware GL.
120 std::vector
<GLImplementation
> allowed_impls
;
121 GetAllowedGLImplementations(&allowed_impls
);
122 DCHECK(!allowed_impls
.empty());
124 GLImplementation impl
= allowed_impls
[0];
126 impl
= kGLImplementationOSMesaGL
;
128 DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL
))
129 << "kUseGL has not effect in tests";
131 bool fallback_to_osmesa
= false;
132 bool gpu_service_logging
= false;
133 bool disable_gl_drawing
= true;
135 CHECK(InitializeOneOffImplementation(
136 impl
, fallback_to_osmesa
, gpu_service_logging
, disable_gl_drawing
));
140 void GLSurface::InitializeOneOffWithMockBindingsForTests() {
141 DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL
))
142 << "kUseGL has not effect in tests";
144 // This method may be called multiple times in the same process to set up
145 // mock bindings in different ways.
148 bool fallback_to_osmesa
= false;
149 bool gpu_service_logging
= false;
150 bool disable_gl_drawing
= false;
152 CHECK(InitializeOneOffImplementation(kGLImplementationMockGL
,
155 disable_gl_drawing
));
159 void GLSurface::InitializeDynamicMockBindingsForTests(GLContext
* context
) {
160 CHECK(InitializeDynamicGLBindings(kGLImplementationMockGL
, context
));
163 GLSurface::GLSurface() {}
165 bool GLSurface::Initialize() {
169 void GLSurface::DestroyAndTerminateDisplay() {
173 bool GLSurface::Resize(const gfx::Size
& size
) {
178 bool GLSurface::Recreate() {
183 bool GLSurface::DeferDraws() {
187 bool GLSurface::SupportsPostSubBuffer() {
191 unsigned int GLSurface::GetBackingFrameBufferObject() {
195 bool GLSurface::SwapBuffersAsync(const SwapCompletionCallback
& callback
) {
196 DCHECK(!IsSurfaceless());
197 bool success
= SwapBuffers();
202 bool GLSurface::PostSubBuffer(int x
, int y
, int width
, int height
) {
206 bool GLSurface::PostSubBufferAsync(int x
,
210 const SwapCompletionCallback
& callback
) {
211 bool success
= PostSubBuffer(x
, y
, width
, height
);
216 bool GLSurface::OnMakeCurrent(GLContext
* context
) {
220 void GLSurface::NotifyWasBound() {
223 bool GLSurface::SetBackbufferAllocation(bool allocated
) {
227 void GLSurface::SetFrontbufferAllocation(bool allocated
) {
230 void* GLSurface::GetShareHandle() {
235 void* GLSurface::GetDisplay() {
240 void* GLSurface::GetConfig() {
245 unsigned GLSurface::GetFormat() {
250 VSyncProvider
* GLSurface::GetVSyncProvider() {
254 bool GLSurface::ScheduleOverlayPlane(int z_order
,
255 OverlayTransform transform
,
257 const Rect
& bounds_rect
,
258 const RectF
& crop_rect
) {
263 bool GLSurface::IsSurfaceless() const {
267 GLSurface
* GLSurface::GetCurrent() {
268 return current_surface_
.Pointer()->Get();
271 GLSurface::~GLSurface() {
272 if (GetCurrent() == this)
276 void GLSurface::SetCurrent(GLSurface
* surface
) {
277 current_surface_
.Pointer()->Set(surface
);
280 bool GLSurface::ExtensionsContain(const char* c_extensions
, const char* name
) {
284 std::string
extensions(c_extensions
);
287 std::string
delimited_name(name
);
288 delimited_name
+= " ";
290 return extensions
.find(delimited_name
) != std::string::npos
;
293 void GLSurface::OnSetSwapInterval(int interval
) {
296 GLSurfaceAdapter::GLSurfaceAdapter(GLSurface
* surface
) : surface_(surface
) {}
298 bool GLSurfaceAdapter::Initialize() {
299 return surface_
->Initialize();
302 void GLSurfaceAdapter::Destroy() {
306 bool GLSurfaceAdapter::Resize(const gfx::Size
& size
) {
307 return surface_
->Resize(size
);
310 bool GLSurfaceAdapter::Recreate() {
311 return surface_
->Recreate();
314 bool GLSurfaceAdapter::DeferDraws() {
315 return surface_
->DeferDraws();
318 bool GLSurfaceAdapter::IsOffscreen() {
319 return surface_
->IsOffscreen();
322 bool GLSurfaceAdapter::SwapBuffers() {
323 return surface_
->SwapBuffers();
326 bool GLSurfaceAdapter::SwapBuffersAsync(
327 const SwapCompletionCallback
& callback
) {
328 return surface_
->SwapBuffersAsync(callback
);
331 bool GLSurfaceAdapter::PostSubBuffer(int x
, int y
, int width
, int height
) {
332 return surface_
->PostSubBuffer(x
, y
, width
, height
);
335 bool GLSurfaceAdapter::PostSubBufferAsync(
336 int x
, int y
, int width
, int height
,
337 const SwapCompletionCallback
& callback
) {
338 return surface_
->PostSubBufferAsync(x
, y
, width
, height
, callback
);
341 bool GLSurfaceAdapter::SupportsPostSubBuffer() {
342 return surface_
->SupportsPostSubBuffer();
345 gfx::Size
GLSurfaceAdapter::GetSize() {
346 return surface_
->GetSize();
349 void* GLSurfaceAdapter::GetHandle() {
350 return surface_
->GetHandle();
353 unsigned int GLSurfaceAdapter::GetBackingFrameBufferObject() {
354 return surface_
->GetBackingFrameBufferObject();
357 bool GLSurfaceAdapter::OnMakeCurrent(GLContext
* context
) {
358 return surface_
->OnMakeCurrent(context
);
361 bool GLSurfaceAdapter::SetBackbufferAllocation(bool allocated
) {
362 return surface_
->SetBackbufferAllocation(allocated
);
365 void GLSurfaceAdapter::SetFrontbufferAllocation(bool allocated
) {
366 surface_
->SetFrontbufferAllocation(allocated
);
369 void* GLSurfaceAdapter::GetShareHandle() {
370 return surface_
->GetShareHandle();
373 void* GLSurfaceAdapter::GetDisplay() {
374 return surface_
->GetDisplay();
377 void* GLSurfaceAdapter::GetConfig() {
378 return surface_
->GetConfig();
381 unsigned GLSurfaceAdapter::GetFormat() {
382 return surface_
->GetFormat();
385 VSyncProvider
* GLSurfaceAdapter::GetVSyncProvider() {
386 return surface_
->GetVSyncProvider();
389 bool GLSurfaceAdapter::ScheduleOverlayPlane(int z_order
,
390 OverlayTransform transform
,
392 const Rect
& bounds_rect
,
393 const RectF
& crop_rect
) {
394 return surface_
->ScheduleOverlayPlane(
395 z_order
, transform
, image
, bounds_rect
, crop_rect
);
398 bool GLSurfaceAdapter::IsSurfaceless() const {
399 return surface_
->IsSurfaceless();
402 GLSurfaceAdapter::~GLSurfaceAdapter() {}