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"
23 base::LazyInstance
<base::ThreadLocalPointer
<GLSurface
> >::Leaky
24 current_surface_
= LAZY_INSTANCE_INITIALIZER
;
28 bool GLSurface::InitializeOneOff() {
29 DCHECK_EQ(kGLImplementationNone
, GetGLImplementation());
31 TRACE_EVENT0("gpu", "GLSurface::InitializeOneOff");
33 std::vector
<GLImplementation
> allowed_impls
;
34 GetAllowedGLImplementations(&allowed_impls
);
35 DCHECK(!allowed_impls
.empty());
37 base::CommandLine
* cmd
= base::CommandLine::ForCurrentProcess();
39 // The default implementation is always the first one in list.
40 GLImplementation impl
= allowed_impls
[0];
41 bool fallback_to_osmesa
= false;
42 if (cmd
->HasSwitch(switches::kOverrideUseGLWithOSMesaForTests
)) {
43 impl
= kGLImplementationOSMesaGL
;
44 } else if (cmd
->HasSwitch(switches::kUseGL
)) {
45 std::string requested_implementation_name
=
46 cmd
->GetSwitchValueASCII(switches::kUseGL
);
47 if (requested_implementation_name
== "any") {
48 fallback_to_osmesa
= true;
49 } else if (requested_implementation_name
== "swiftshader") {
50 impl
= kGLImplementationEGLGLES2
;
52 impl
= GetNamedGLImplementation(requested_implementation_name
);
53 if (std::find(allowed_impls
.begin(),
55 impl
) == allowed_impls
.end()) {
56 LOG(ERROR
) << "Requested GL implementation is not available.";
62 bool gpu_service_logging
= cmd
->HasSwitch(switches::kEnableGPUServiceLogging
);
63 bool disable_gl_drawing
= cmd
->HasSwitch(switches::kDisableGLDrawingForTests
);
65 return InitializeOneOffImplementation(
66 impl
, fallback_to_osmesa
, gpu_service_logging
, disable_gl_drawing
);
70 bool GLSurface::InitializeOneOffImplementation(GLImplementation impl
,
71 bool fallback_to_osmesa
,
72 bool gpu_service_logging
,
73 bool disable_gl_drawing
) {
75 InitializeStaticGLBindings(impl
) && InitializeOneOffInternal();
76 if (!initialized
&& fallback_to_osmesa
) {
78 initialized
= InitializeStaticGLBindings(kGLImplementationOSMesaGL
) &&
79 InitializeOneOffInternal();
86 << GetGLImplementationName(GetGLImplementation())
87 << " GL implementation.";
88 if (gpu_service_logging
)
89 InitializeDebugGLBindings();
90 if (disable_gl_drawing
)
91 InitializeNullDrawGLBindings();
96 GLSurface::GLSurface() {}
98 bool GLSurface::Initialize() {
102 void GLSurface::DestroyAndTerminateDisplay() {
106 bool GLSurface::Resize(const gfx::Size
& size
) {
111 bool GLSurface::Recreate() {
116 bool GLSurface::DeferDraws() {
120 bool GLSurface::SupportsPostSubBuffer() {
124 unsigned int GLSurface::GetBackingFrameBufferObject() {
128 bool GLSurface::SwapBuffersAsync(const SwapCompletionCallback
& callback
) {
129 DCHECK(!IsSurfaceless());
130 gfx::SwapResult result
= SwapBuffers();
131 callback
.Run(result
);
132 return result
== gfx::SwapResult::SWAP_ACK
;
135 gfx::SwapResult
GLSurface::PostSubBuffer(int x
, int y
, int width
, int height
) {
136 return gfx::SwapResult::SWAP_FAILED
;
139 bool GLSurface::PostSubBufferAsync(int x
,
143 const SwapCompletionCallback
& callback
) {
144 gfx::SwapResult result
= PostSubBuffer(x
, y
, width
, height
);
145 callback
.Run(result
);
146 return result
== gfx::SwapResult::SWAP_ACK
;
149 bool GLSurface::OnMakeCurrent(GLContext
* context
) {
153 void GLSurface::NotifyWasBound() {
156 bool GLSurface::SetBackbufferAllocation(bool allocated
) {
160 void GLSurface::SetFrontbufferAllocation(bool allocated
) {
163 void* GLSurface::GetShareHandle() {
168 void* GLSurface::GetDisplay() {
173 void* GLSurface::GetConfig() {
178 unsigned GLSurface::GetFormat() {
183 VSyncProvider
* GLSurface::GetVSyncProvider() {
187 bool GLSurface::ScheduleOverlayPlane(int z_order
,
188 OverlayTransform transform
,
190 const Rect
& bounds_rect
,
191 const RectF
& crop_rect
) {
196 bool GLSurface::IsSurfaceless() const {
200 GLSurface
* GLSurface::GetCurrent() {
201 return current_surface_
.Pointer()->Get();
204 GLSurface::~GLSurface() {
205 if (GetCurrent() == this)
209 void GLSurface::SetCurrent(GLSurface
* surface
) {
210 current_surface_
.Pointer()->Set(surface
);
213 bool GLSurface::ExtensionsContain(const char* c_extensions
, const char* name
) {
217 std::string
extensions(c_extensions
);
220 std::string
delimited_name(name
);
221 delimited_name
+= " ";
223 return extensions
.find(delimited_name
) != std::string::npos
;
226 void GLSurface::OnSetSwapInterval(int interval
) {
229 GLSurfaceAdapter::GLSurfaceAdapter(GLSurface
* surface
) : surface_(surface
) {}
231 bool GLSurfaceAdapter::Initialize() {
232 return surface_
->Initialize();
235 void GLSurfaceAdapter::Destroy() {
239 bool GLSurfaceAdapter::Resize(const gfx::Size
& size
) {
240 return surface_
->Resize(size
);
243 bool GLSurfaceAdapter::Recreate() {
244 return surface_
->Recreate();
247 bool GLSurfaceAdapter::DeferDraws() {
248 return surface_
->DeferDraws();
251 bool GLSurfaceAdapter::IsOffscreen() {
252 return surface_
->IsOffscreen();
255 gfx::SwapResult
GLSurfaceAdapter::SwapBuffers() {
256 return surface_
->SwapBuffers();
259 bool GLSurfaceAdapter::SwapBuffersAsync(
260 const SwapCompletionCallback
& callback
) {
261 return surface_
->SwapBuffersAsync(callback
);
264 gfx::SwapResult
GLSurfaceAdapter::PostSubBuffer(int x
,
268 return surface_
->PostSubBuffer(x
, y
, width
, height
);
271 bool GLSurfaceAdapter::PostSubBufferAsync(
272 int x
, int y
, int width
, int height
,
273 const SwapCompletionCallback
& callback
) {
274 return surface_
->PostSubBufferAsync(x
, y
, width
, height
, callback
);
277 bool GLSurfaceAdapter::SupportsPostSubBuffer() {
278 return surface_
->SupportsPostSubBuffer();
281 gfx::Size
GLSurfaceAdapter::GetSize() {
282 return surface_
->GetSize();
285 void* GLSurfaceAdapter::GetHandle() {
286 return surface_
->GetHandle();
289 unsigned int GLSurfaceAdapter::GetBackingFrameBufferObject() {
290 return surface_
->GetBackingFrameBufferObject();
293 bool GLSurfaceAdapter::OnMakeCurrent(GLContext
* context
) {
294 return surface_
->OnMakeCurrent(context
);
297 bool GLSurfaceAdapter::SetBackbufferAllocation(bool allocated
) {
298 return surface_
->SetBackbufferAllocation(allocated
);
301 void GLSurfaceAdapter::SetFrontbufferAllocation(bool allocated
) {
302 surface_
->SetFrontbufferAllocation(allocated
);
305 void* GLSurfaceAdapter::GetShareHandle() {
306 return surface_
->GetShareHandle();
309 void* GLSurfaceAdapter::GetDisplay() {
310 return surface_
->GetDisplay();
313 void* GLSurfaceAdapter::GetConfig() {
314 return surface_
->GetConfig();
317 unsigned GLSurfaceAdapter::GetFormat() {
318 return surface_
->GetFormat();
321 VSyncProvider
* GLSurfaceAdapter::GetVSyncProvider() {
322 return surface_
->GetVSyncProvider();
325 bool GLSurfaceAdapter::ScheduleOverlayPlane(int z_order
,
326 OverlayTransform transform
,
328 const Rect
& bounds_rect
,
329 const RectF
& crop_rect
) {
330 return surface_
->ScheduleOverlayPlane(
331 z_order
, transform
, image
, bounds_rect
, crop_rect
);
334 bool GLSurfaceAdapter::IsSurfaceless() const {
335 return surface_
->IsSurfaceless();
338 GLSurfaceAdapter::~GLSurfaceAdapter() {}