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 bool GLSurface::Resize(const gfx::Size
& size
) {
107 bool GLSurface::Recreate() {
112 bool GLSurface::DeferDraws() {
116 bool GLSurface::SupportsPostSubBuffer() {
120 unsigned int GLSurface::GetBackingFrameBufferObject() {
124 bool GLSurface::SwapBuffersAsync(const SwapCompletionCallback
& callback
) {
125 DCHECK(!IsSurfaceless());
126 gfx::SwapResult result
= SwapBuffers();
127 callback
.Run(result
);
128 return result
== gfx::SwapResult::SWAP_ACK
;
131 gfx::SwapResult
GLSurface::PostSubBuffer(int x
, int y
, int width
, int height
) {
132 return gfx::SwapResult::SWAP_FAILED
;
135 bool GLSurface::PostSubBufferAsync(int x
,
139 const SwapCompletionCallback
& callback
) {
140 gfx::SwapResult result
= PostSubBuffer(x
, y
, width
, height
);
141 callback
.Run(result
);
142 return result
== gfx::SwapResult::SWAP_ACK
;
145 bool GLSurface::OnMakeCurrent(GLContext
* context
) {
149 void GLSurface::NotifyWasBound() {
152 bool GLSurface::SetBackbufferAllocation(bool allocated
) {
156 void GLSurface::SetFrontbufferAllocation(bool allocated
) {
159 void* GLSurface::GetShareHandle() {
164 void* GLSurface::GetDisplay() {
169 void* GLSurface::GetConfig() {
174 unsigned GLSurface::GetFormat() {
179 VSyncProvider
* GLSurface::GetVSyncProvider() {
183 bool GLSurface::ScheduleOverlayPlane(int z_order
,
184 OverlayTransform transform
,
186 const Rect
& bounds_rect
,
187 const RectF
& crop_rect
) {
192 bool GLSurface::IsSurfaceless() const {
196 GLSurface
* GLSurface::GetCurrent() {
197 return current_surface_
.Pointer()->Get();
200 GLSurface::~GLSurface() {
201 if (GetCurrent() == this)
205 void GLSurface::SetCurrent(GLSurface
* surface
) {
206 current_surface_
.Pointer()->Set(surface
);
209 bool GLSurface::ExtensionsContain(const char* c_extensions
, const char* name
) {
213 std::string
extensions(c_extensions
);
216 std::string
delimited_name(name
);
217 delimited_name
+= " ";
219 return extensions
.find(delimited_name
) != std::string::npos
;
222 void GLSurface::OnSetSwapInterval(int interval
) {
225 GLSurfaceAdapter::GLSurfaceAdapter(GLSurface
* surface
) : surface_(surface
) {}
227 bool GLSurfaceAdapter::Initialize() {
228 return surface_
->Initialize();
231 void GLSurfaceAdapter::Destroy() {
235 bool GLSurfaceAdapter::Resize(const gfx::Size
& size
) {
236 return surface_
->Resize(size
);
239 bool GLSurfaceAdapter::Recreate() {
240 return surface_
->Recreate();
243 bool GLSurfaceAdapter::DeferDraws() {
244 return surface_
->DeferDraws();
247 bool GLSurfaceAdapter::IsOffscreen() {
248 return surface_
->IsOffscreen();
251 gfx::SwapResult
GLSurfaceAdapter::SwapBuffers() {
252 return surface_
->SwapBuffers();
255 bool GLSurfaceAdapter::SwapBuffersAsync(
256 const SwapCompletionCallback
& callback
) {
257 return surface_
->SwapBuffersAsync(callback
);
260 gfx::SwapResult
GLSurfaceAdapter::PostSubBuffer(int x
,
264 return surface_
->PostSubBuffer(x
, y
, width
, height
);
267 bool GLSurfaceAdapter::PostSubBufferAsync(
268 int x
, int y
, int width
, int height
,
269 const SwapCompletionCallback
& callback
) {
270 return surface_
->PostSubBufferAsync(x
, y
, width
, height
, callback
);
273 bool GLSurfaceAdapter::SupportsPostSubBuffer() {
274 return surface_
->SupportsPostSubBuffer();
277 gfx::Size
GLSurfaceAdapter::GetSize() {
278 return surface_
->GetSize();
281 void* GLSurfaceAdapter::GetHandle() {
282 return surface_
->GetHandle();
285 unsigned int GLSurfaceAdapter::GetBackingFrameBufferObject() {
286 return surface_
->GetBackingFrameBufferObject();
289 bool GLSurfaceAdapter::OnMakeCurrent(GLContext
* context
) {
290 return surface_
->OnMakeCurrent(context
);
293 bool GLSurfaceAdapter::SetBackbufferAllocation(bool allocated
) {
294 return surface_
->SetBackbufferAllocation(allocated
);
297 void GLSurfaceAdapter::SetFrontbufferAllocation(bool allocated
) {
298 surface_
->SetFrontbufferAllocation(allocated
);
301 void* GLSurfaceAdapter::GetShareHandle() {
302 return surface_
->GetShareHandle();
305 void* GLSurfaceAdapter::GetDisplay() {
306 return surface_
->GetDisplay();
309 void* GLSurfaceAdapter::GetConfig() {
310 return surface_
->GetConfig();
313 unsigned GLSurfaceAdapter::GetFormat() {
314 return surface_
->GetFormat();
317 VSyncProvider
* GLSurfaceAdapter::GetVSyncProvider() {
318 return surface_
->GetVSyncProvider();
321 bool GLSurfaceAdapter::ScheduleOverlayPlane(int z_order
,
322 OverlayTransform transform
,
324 const Rect
& bounds_rect
,
325 const RectF
& crop_rect
) {
326 return surface_
->ScheduleOverlayPlane(
327 z_order
, transform
, image
, bounds_rect
, crop_rect
);
330 bool GLSurfaceAdapter::IsSurfaceless() const {
331 return surface_
->IsSurfaceless();
334 GLSurfaceAdapter::~GLSurfaceAdapter() {}