Added llvm into exceptions as we can't add README.chromium into 3rd party repository
[chromium-blink-merge.git] / ui / gl / gl_surface.cc
blob47690924fa7d4f06da4cc1f033f23823126b8ddb
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"
7 #include <algorithm>
8 #include <vector>
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/gl/gl_context.h"
16 #include "ui/gl/gl_implementation.h"
17 #include "ui/gl/gl_switches.h"
19 #if defined(USE_X11)
20 #include <X11/Xlib.h>
21 #endif
23 namespace gfx {
25 namespace {
26 base::LazyInstance<base::ThreadLocalPointer<GLSurface> >::Leaky
27 current_surface_ = LAZY_INSTANCE_INITIALIZER;
28 } // namespace
30 // static
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;
54 } else {
55 impl = GetNamedGLImplementation(requested_implementation_name);
56 if (std::find(allowed_impls.begin(),
57 allowed_impls.end(),
58 impl) == allowed_impls.end()) {
59 LOG(ERROR) << "Requested GL implementation is not available.";
60 return false;
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);
72 // static
73 bool GLSurface::InitializeOneOffImplementation(GLImplementation impl,
74 bool fallback_to_osmesa,
75 bool gpu_service_logging,
76 bool disable_gl_drawing) {
77 bool initialized =
78 InitializeStaticGLBindings(impl) && InitializeOneOffInternal();
79 if (!initialized && fallback_to_osmesa) {
80 ClearGLBindings();
81 initialized = InitializeStaticGLBindings(kGLImplementationOSMesaGL) &&
82 InitializeOneOffInternal();
84 if (!initialized)
85 ClearGLBindings();
87 if (initialized) {
88 DVLOG(1) << "Using "
89 << GetGLImplementationName(GetGLImplementation())
90 << " GL implementation.";
91 if (gpu_service_logging)
92 InitializeDebugGLBindings();
93 if (disable_gl_drawing)
94 InitializeNullDrawGLBindings();
96 return initialized;
99 // static
100 void GLSurface::InitializeOneOffForTests() {
101 DCHECK_EQ(kGLImplementationNone, GetGLImplementation());
103 #if defined(USE_X11)
104 XInitThreads();
105 #endif
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))
113 use_osmesa = false;
115 #if defined(OS_ANDROID)
116 // On Android we always use hardware GL.
117 use_osmesa = false;
118 #endif
120 std::vector<GLImplementation> allowed_impls;
121 GetAllowedGLImplementations(&allowed_impls);
122 DCHECK(!allowed_impls.empty());
124 GLImplementation impl = allowed_impls[0];
125 if (use_osmesa)
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));
139 // static
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.
146 ClearGLBindings();
148 bool fallback_to_osmesa = false;
149 bool gpu_service_logging = false;
150 bool disable_gl_drawing = false;
152 CHECK(InitializeOneOffImplementation(kGLImplementationMockGL,
153 fallback_to_osmesa,
154 gpu_service_logging,
155 disable_gl_drawing));
158 // static
159 void GLSurface::InitializeDynamicMockBindingsForTests(GLContext* context) {
160 CHECK(InitializeDynamicGLBindings(kGLImplementationMockGL, context));
163 GLSurface::GLSurface() {}
165 bool GLSurface::Initialize() {
166 return true;
169 void GLSurface::DestroyAndTerminateDisplay() {
170 Destroy();
173 bool GLSurface::Resize(const gfx::Size& size) {
174 NOTIMPLEMENTED();
175 return false;
178 bool GLSurface::Recreate() {
179 NOTIMPLEMENTED();
180 return false;
183 bool GLSurface::DeferDraws() {
184 return false;
187 bool GLSurface::SupportsPostSubBuffer() {
188 return false;
191 unsigned int GLSurface::GetBackingFrameBufferObject() {
192 return 0;
195 bool GLSurface::SwapBuffersAsync(const SwapCompletionCallback& callback) {
196 DCHECK(!IsSurfaceless());
197 bool success = SwapBuffers();
198 callback.Run();
199 return success;
202 bool GLSurface::PostSubBuffer(int x, int y, int width, int height) {
203 return false;
206 bool GLSurface::PostSubBufferAsync(int x,
207 int y,
208 int width,
209 int height,
210 const SwapCompletionCallback& callback) {
211 bool success = PostSubBuffer(x, y, width, height);
212 callback.Run();
213 return success;
216 bool GLSurface::OnMakeCurrent(GLContext* context) {
217 return true;
220 void GLSurface::NotifyWasBound() {
223 bool GLSurface::SetBackbufferAllocation(bool allocated) {
224 return true;
227 void GLSurface::SetFrontbufferAllocation(bool allocated) {
230 void* GLSurface::GetShareHandle() {
231 NOTIMPLEMENTED();
232 return NULL;
235 void* GLSurface::GetDisplay() {
236 NOTIMPLEMENTED();
237 return NULL;
240 void* GLSurface::GetConfig() {
241 NOTIMPLEMENTED();
242 return NULL;
245 unsigned GLSurface::GetFormat() {
246 NOTIMPLEMENTED();
247 return 0;
250 VSyncProvider* GLSurface::GetVSyncProvider() {
251 return NULL;
254 bool GLSurface::ScheduleOverlayPlane(int z_order,
255 OverlayTransform transform,
256 GLImage* image,
257 const Rect& bounds_rect,
258 const RectF& crop_rect) {
259 NOTIMPLEMENTED();
260 return false;
263 bool GLSurface::IsSurfaceless() const {
264 return false;
267 GLSurface* GLSurface::GetCurrent() {
268 return current_surface_.Pointer()->Get();
271 GLSurface::~GLSurface() {
272 if (GetCurrent() == this)
273 SetCurrent(NULL);
276 void GLSurface::SetCurrent(GLSurface* surface) {
277 current_surface_.Pointer()->Set(surface);
280 bool GLSurface::ExtensionsContain(const char* c_extensions, const char* name) {
281 DCHECK(name);
282 if (!c_extensions)
283 return false;
284 std::string extensions(c_extensions);
285 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() {
303 surface_->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,
391 GLImage* image,
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() {}
404 } // namespace gfx