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/lazy_instance.h"
12 #include "base/logging.h"
13 #include "base/threading/thread_local.h"
14 #include "base/trace_event/trace_event.h"
15 #include "ui/gfx/swap_result.h"
16 #include "ui/gl/gl_context.h"
17 #include "ui/gl/gl_implementation.h"
18 #include "ui/gl/gl_switches.h"
27 base::LazyInstance
<base::ThreadLocalPointer
<GLSurface
> >::Leaky
28 current_surface_
= LAZY_INSTANCE_INITIALIZER
;
32 bool GLSurface::InitializeOneOff() {
33 DCHECK_EQ(kGLImplementationNone
, GetGLImplementation());
35 TRACE_EVENT0("gpu", "GLSurface::InitializeOneOff");
37 std::vector
<GLImplementation
> allowed_impls
;
38 GetAllowedGLImplementations(&allowed_impls
);
39 DCHECK(!allowed_impls
.empty());
41 base::CommandLine
* cmd
= base::CommandLine::ForCurrentProcess();
43 // The default implementation is always the first one in list.
44 GLImplementation impl
= allowed_impls
[0];
45 bool fallback_to_osmesa
= false;
46 if (cmd
->HasSwitch(switches::kOverrideUseGLWithOSMesaForTests
)) {
47 impl
= kGLImplementationOSMesaGL
;
48 } else if (cmd
->HasSwitch(switches::kUseGL
)) {
49 std::string requested_implementation_name
=
50 cmd
->GetSwitchValueASCII(switches::kUseGL
);
51 if (requested_implementation_name
== "any") {
52 fallback_to_osmesa
= true;
53 } else if (requested_implementation_name
== "swiftshader") {
54 impl
= kGLImplementationEGLGLES2
;
56 impl
= GetNamedGLImplementation(requested_implementation_name
);
57 if (std::find(allowed_impls
.begin(),
59 impl
) == allowed_impls
.end()) {
60 LOG(ERROR
) << "Requested GL implementation is not available.";
66 bool gpu_service_logging
= cmd
->HasSwitch(switches::kEnableGPUServiceLogging
);
67 bool disable_gl_drawing
= cmd
->HasSwitch(switches::kDisableGLDrawingForTests
);
69 return InitializeOneOffImplementation(
70 impl
, fallback_to_osmesa
, gpu_service_logging
, disable_gl_drawing
);
74 bool GLSurface::InitializeOneOffImplementation(GLImplementation impl
,
75 bool fallback_to_osmesa
,
76 bool gpu_service_logging
,
77 bool disable_gl_drawing
) {
79 InitializeStaticGLBindings(impl
) && InitializeOneOffInternal();
80 if (!initialized
&& fallback_to_osmesa
) {
82 initialized
= InitializeStaticGLBindings(kGLImplementationOSMesaGL
) &&
83 InitializeOneOffInternal();
90 << GetGLImplementationName(GetGLImplementation())
91 << " GL implementation.";
92 if (gpu_service_logging
)
93 InitializeDebugGLBindings();
94 if (disable_gl_drawing
)
95 InitializeNullDrawGLBindings();
101 void GLSurface::InitializeOneOffForTests() {
102 DCHECK_EQ(kGLImplementationNone
, GetGLImplementation());
108 bool use_osmesa
= true;
110 // We usually use OSMesa as this works on all bots. The command line can
111 // override this behaviour to use hardware GL.
112 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
113 switches::kUseGpuInTests
))
116 #if defined(OS_ANDROID)
117 // On Android we always use hardware GL.
121 std::vector
<GLImplementation
> allowed_impls
;
122 GetAllowedGLImplementations(&allowed_impls
);
123 DCHECK(!allowed_impls
.empty());
125 GLImplementation impl
= allowed_impls
[0];
127 impl
= kGLImplementationOSMesaGL
;
129 DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL
))
130 << "kUseGL has not effect in tests";
132 bool fallback_to_osmesa
= false;
133 bool gpu_service_logging
= false;
134 bool disable_gl_drawing
= true;
136 CHECK(InitializeOneOffImplementation(
137 impl
, fallback_to_osmesa
, gpu_service_logging
, disable_gl_drawing
));
141 void GLSurface::InitializeOneOffWithMockBindingsForTests() {
142 DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL
))
143 << "kUseGL has not effect in tests";
145 // This method may be called multiple times in the same process to set up
146 // mock bindings in different ways.
149 bool fallback_to_osmesa
= false;
150 bool gpu_service_logging
= false;
151 bool disable_gl_drawing
= false;
153 CHECK(InitializeOneOffImplementation(kGLImplementationMockGL
,
156 disable_gl_drawing
));
160 void GLSurface::InitializeDynamicMockBindingsForTests(GLContext
* context
) {
161 CHECK(InitializeDynamicGLBindings(kGLImplementationMockGL
, context
));
164 GLSurface::GLSurface() {}
166 bool GLSurface::Initialize() {
170 void GLSurface::DestroyAndTerminateDisplay() {
174 bool GLSurface::Resize(const gfx::Size
& size
) {
179 bool GLSurface::Recreate() {
184 bool GLSurface::DeferDraws() {
188 bool GLSurface::SupportsPostSubBuffer() {
192 unsigned int GLSurface::GetBackingFrameBufferObject() {
196 bool GLSurface::SwapBuffersAsync(const SwapCompletionCallback
& callback
) {
197 DCHECK(!IsSurfaceless());
198 gfx::SwapResult result
= SwapBuffers();
199 callback
.Run(result
);
200 return result
== gfx::SwapResult::SWAP_ACK
;
203 gfx::SwapResult
GLSurface::PostSubBuffer(int x
, int y
, int width
, int height
) {
204 return gfx::SwapResult::SWAP_FAILED
;
207 bool GLSurface::PostSubBufferAsync(int x
,
211 const SwapCompletionCallback
& callback
) {
212 gfx::SwapResult result
= PostSubBuffer(x
, y
, width
, height
);
213 callback
.Run(result
);
214 return result
== gfx::SwapResult::SWAP_ACK
;
217 bool GLSurface::OnMakeCurrent(GLContext
* context
) {
221 void GLSurface::NotifyWasBound() {
224 bool GLSurface::SetBackbufferAllocation(bool allocated
) {
228 void GLSurface::SetFrontbufferAllocation(bool allocated
) {
231 void* GLSurface::GetShareHandle() {
236 void* GLSurface::GetDisplay() {
241 void* GLSurface::GetConfig() {
246 unsigned GLSurface::GetFormat() {
251 VSyncProvider
* GLSurface::GetVSyncProvider() {
255 bool GLSurface::ScheduleOverlayPlane(int z_order
,
256 OverlayTransform transform
,
258 const Rect
& bounds_rect
,
259 const RectF
& crop_rect
) {
264 bool GLSurface::IsSurfaceless() const {
268 GLSurface
* GLSurface::GetCurrent() {
269 return current_surface_
.Pointer()->Get();
272 GLSurface::~GLSurface() {
273 if (GetCurrent() == this)
277 void GLSurface::SetCurrent(GLSurface
* surface
) {
278 current_surface_
.Pointer()->Set(surface
);
281 bool GLSurface::ExtensionsContain(const char* c_extensions
, const char* name
) {
285 std::string
extensions(c_extensions
);
288 std::string
delimited_name(name
);
289 delimited_name
+= " ";
291 return extensions
.find(delimited_name
) != std::string::npos
;
294 void GLSurface::OnSetSwapInterval(int interval
) {
297 GLSurfaceAdapter::GLSurfaceAdapter(GLSurface
* surface
) : surface_(surface
) {}
299 bool GLSurfaceAdapter::Initialize() {
300 return surface_
->Initialize();
303 void GLSurfaceAdapter::Destroy() {
307 bool GLSurfaceAdapter::Resize(const gfx::Size
& size
) {
308 return surface_
->Resize(size
);
311 bool GLSurfaceAdapter::Recreate() {
312 return surface_
->Recreate();
315 bool GLSurfaceAdapter::DeferDraws() {
316 return surface_
->DeferDraws();
319 bool GLSurfaceAdapter::IsOffscreen() {
320 return surface_
->IsOffscreen();
323 gfx::SwapResult
GLSurfaceAdapter::SwapBuffers() {
324 return surface_
->SwapBuffers();
327 bool GLSurfaceAdapter::SwapBuffersAsync(
328 const SwapCompletionCallback
& callback
) {
329 return surface_
->SwapBuffersAsync(callback
);
332 gfx::SwapResult
GLSurfaceAdapter::PostSubBuffer(int x
,
336 return surface_
->PostSubBuffer(x
, y
, width
, height
);
339 bool GLSurfaceAdapter::PostSubBufferAsync(
340 int x
, int y
, int width
, int height
,
341 const SwapCompletionCallback
& callback
) {
342 return surface_
->PostSubBufferAsync(x
, y
, width
, height
, callback
);
345 bool GLSurfaceAdapter::SupportsPostSubBuffer() {
346 return surface_
->SupportsPostSubBuffer();
349 gfx::Size
GLSurfaceAdapter::GetSize() {
350 return surface_
->GetSize();
353 void* GLSurfaceAdapter::GetHandle() {
354 return surface_
->GetHandle();
357 unsigned int GLSurfaceAdapter::GetBackingFrameBufferObject() {
358 return surface_
->GetBackingFrameBufferObject();
361 bool GLSurfaceAdapter::OnMakeCurrent(GLContext
* context
) {
362 return surface_
->OnMakeCurrent(context
);
365 bool GLSurfaceAdapter::SetBackbufferAllocation(bool allocated
) {
366 return surface_
->SetBackbufferAllocation(allocated
);
369 void GLSurfaceAdapter::SetFrontbufferAllocation(bool allocated
) {
370 surface_
->SetFrontbufferAllocation(allocated
);
373 void* GLSurfaceAdapter::GetShareHandle() {
374 return surface_
->GetShareHandle();
377 void* GLSurfaceAdapter::GetDisplay() {
378 return surface_
->GetDisplay();
381 void* GLSurfaceAdapter::GetConfig() {
382 return surface_
->GetConfig();
385 unsigned GLSurfaceAdapter::GetFormat() {
386 return surface_
->GetFormat();
389 VSyncProvider
* GLSurfaceAdapter::GetVSyncProvider() {
390 return surface_
->GetVSyncProvider();
393 bool GLSurfaceAdapter::ScheduleOverlayPlane(int z_order
,
394 OverlayTransform transform
,
396 const Rect
& bounds_rect
,
397 const RectF
& crop_rect
) {
398 return surface_
->ScheduleOverlayPlane(
399 z_order
, transform
, image
, bounds_rect
, crop_rect
);
402 bool GLSurfaceAdapter::IsSurfaceless() const {
403 return surface_
->IsSurfaceless();
406 GLSurfaceAdapter::~GLSurfaceAdapter() {}