Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / ui / gl / gl_surface.cc
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.
4
5 #include "ui/gl/gl_surface.h"
6
7 #include <algorithm>
8 #include <vector>
9
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"
18
19 #if defined(USE_X11)
20 #include <X11/Xlib.h>
21 #endif
22
23 namespace gfx {
24
25 namespace {
26 base::LazyInstance<base::ThreadLocalPointer<GLSurface> >::Leaky
27     current_surface_ = LAZY_INSTANCE_INITIALIZER;
28 }  // namespace
29
30 // static
31 bool GLSurface::InitializeOneOff() {
32   DCHECK_EQ(kGLImplementationNone, GetGLImplementation());
33
34   TRACE_EVENT0("gpu", "GLSurface::InitializeOneOff");
35
36   std::vector<GLImplementation> allowed_impls;
37   GetAllowedGLImplementations(&allowed_impls);
38   DCHECK(!allowed_impls.empty());
39
40   CommandLine* cmd = CommandLine::ForCurrentProcess();
41
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;
61       }
62     }
63   }
64
65   bool gpu_service_logging = cmd->HasSwitch(switches::kEnableGPUServiceLogging);
66   bool disable_gl_drawing = cmd->HasSwitch(switches::kDisableGLDrawingForTests);
67
68   return InitializeOneOffImplementation(
69       impl, fallback_to_osmesa, gpu_service_logging, disable_gl_drawing);
70 }
71
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();
83   }
84   if (!initialized)
85     ClearGLBindings();
86
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();
95   }
96   return initialized;
97 }
98
99 // static
100 void GLSurface::InitializeOneOffForTests() {
101   DCHECK_EQ(kGLImplementationNone, GetGLImplementation());
102
103 #if defined(USE_X11)
104   XInitThreads();
105 #endif
106
107   bool use_osmesa = true;
108
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 (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGpuInTests))
112     use_osmesa = false;
113
114 #if defined(OS_ANDROID)
115   // On Android we always use hardware GL.
116   use_osmesa = false;
117 #endif
118
119   std::vector<GLImplementation> allowed_impls;
120   GetAllowedGLImplementations(&allowed_impls);
121   DCHECK(!allowed_impls.empty());
122
123   GLImplementation impl = allowed_impls[0];
124   if (use_osmesa)
125     impl = kGLImplementationOSMesaGL;
126
127   DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL))
128       << "kUseGL has not effect in tests";
129
130   bool fallback_to_osmesa = false;
131   bool gpu_service_logging = false;
132   bool disable_gl_drawing = true;
133
134   CHECK(InitializeOneOffImplementation(
135       impl, fallback_to_osmesa, gpu_service_logging, disable_gl_drawing));
136 }
137
138 // static
139 void GLSurface::InitializeOneOffWithMockBindingsForTests() {
140   DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL))
141       << "kUseGL has not effect in tests";
142
143   // This method may be called multiple times in the same process to set up
144   // mock bindings in different ways.
145   ClearGLBindings();
146
147   bool fallback_to_osmesa = false;
148   bool gpu_service_logging = false;
149   bool disable_gl_drawing = false;
150
151   CHECK(InitializeOneOffImplementation(kGLImplementationMockGL,
152                                        fallback_to_osmesa,
153                                        gpu_service_logging,
154                                        disable_gl_drawing));
155 }
156
157 // static
158 void GLSurface::InitializeDynamicMockBindingsForTests(GLContext* context) {
159   CHECK(InitializeDynamicGLBindings(kGLImplementationMockGL, context));
160 }
161
162 GLSurface::GLSurface() {}
163
164 bool GLSurface::Initialize() {
165   return true;
166 }
167
168 bool GLSurface::Resize(const gfx::Size& size) {
169   NOTIMPLEMENTED();
170   return false;
171 }
172
173 bool GLSurface::Recreate() {
174   NOTIMPLEMENTED();
175   return false;
176 }
177
178 bool GLSurface::DeferDraws() {
179   return false;
180 }
181
182 bool GLSurface::SupportsPostSubBuffer() {
183   return false;
184 }
185
186 unsigned int GLSurface::GetBackingFrameBufferObject() {
187   return 0;
188 }
189
190 bool GLSurface::PostSubBuffer(int x, int y, int width, int height) {
191   return false;
192 }
193
194 bool GLSurface::OnMakeCurrent(GLContext* context) {
195   return true;
196 }
197
198 bool GLSurface::SetBackbufferAllocation(bool allocated) {
199   return true;
200 }
201
202 void GLSurface::SetFrontbufferAllocation(bool allocated) {
203 }
204
205 void* GLSurface::GetShareHandle() {
206   NOTIMPLEMENTED();
207   return NULL;
208 }
209
210 void* GLSurface::GetDisplay() {
211   NOTIMPLEMENTED();
212   return NULL;
213 }
214
215 void* GLSurface::GetConfig() {
216   NOTIMPLEMENTED();
217   return NULL;
218 }
219
220 unsigned GLSurface::GetFormat() {
221   NOTIMPLEMENTED();
222   return 0;
223 }
224
225 VSyncProvider* GLSurface::GetVSyncProvider() {
226   return NULL;
227 }
228
229 bool GLSurface::ScheduleOverlayPlane(int z_order,
230                                      OverlayTransform transform,
231                                      GLImage* image,
232                                      const Rect& bounds_rect,
233                                      const RectF& crop_rect) {
234   NOTIMPLEMENTED();
235   return false;
236 }
237
238 GLSurface* GLSurface::GetCurrent() {
239   return current_surface_.Pointer()->Get();
240 }
241
242 GLSurface::~GLSurface() {
243   if (GetCurrent() == this)
244     SetCurrent(NULL);
245 }
246
247 void GLSurface::SetCurrent(GLSurface* surface) {
248   current_surface_.Pointer()->Set(surface);
249 }
250
251 bool GLSurface::ExtensionsContain(const char* c_extensions, const char* name) {
252   DCHECK(name);
253   if (!c_extensions)
254     return false;
255   std::string extensions(c_extensions);
256   extensions += " ";
257
258   std::string delimited_name(name);
259   delimited_name += " ";
260
261   return extensions.find(delimited_name) != std::string::npos;
262 }
263
264 GLSurfaceAdapter::GLSurfaceAdapter(GLSurface* surface) : surface_(surface) {}
265
266 bool GLSurfaceAdapter::Initialize() {
267   return surface_->Initialize();
268 }
269
270 void GLSurfaceAdapter::Destroy() {
271   surface_->Destroy();
272 }
273
274 bool GLSurfaceAdapter::Resize(const gfx::Size& size) {
275   return surface_->Resize(size);
276 }
277
278 bool GLSurfaceAdapter::Recreate() {
279   return surface_->Recreate();
280 }
281
282 bool GLSurfaceAdapter::DeferDraws() {
283   return surface_->DeferDraws();
284 }
285
286 bool GLSurfaceAdapter::IsOffscreen() {
287   return surface_->IsOffscreen();
288 }
289
290 bool GLSurfaceAdapter::SwapBuffers() {
291   return surface_->SwapBuffers();
292 }
293
294 bool GLSurfaceAdapter::PostSubBuffer(int x, int y, int width, int height) {
295   return surface_->PostSubBuffer(x, y, width, height);
296 }
297
298 bool GLSurfaceAdapter::SupportsPostSubBuffer() {
299   return surface_->SupportsPostSubBuffer();
300 }
301
302 gfx::Size GLSurfaceAdapter::GetSize() {
303   return surface_->GetSize();
304 }
305
306 void* GLSurfaceAdapter::GetHandle() {
307   return surface_->GetHandle();
308 }
309
310 unsigned int GLSurfaceAdapter::GetBackingFrameBufferObject() {
311   return surface_->GetBackingFrameBufferObject();
312 }
313
314 bool GLSurfaceAdapter::OnMakeCurrent(GLContext* context) {
315   return surface_->OnMakeCurrent(context);
316 }
317
318 bool GLSurfaceAdapter::SetBackbufferAllocation(bool allocated) {
319   return surface_->SetBackbufferAllocation(allocated);
320 }
321
322 void GLSurfaceAdapter::SetFrontbufferAllocation(bool allocated) {
323   surface_->SetFrontbufferAllocation(allocated);
324 }
325
326 void* GLSurfaceAdapter::GetShareHandle() {
327   return surface_->GetShareHandle();
328 }
329
330 void* GLSurfaceAdapter::GetDisplay() {
331   return surface_->GetDisplay();
332 }
333
334 void* GLSurfaceAdapter::GetConfig() {
335   return surface_->GetConfig();
336 }
337
338 unsigned GLSurfaceAdapter::GetFormat() {
339   return surface_->GetFormat();
340 }
341
342 VSyncProvider* GLSurfaceAdapter::GetVSyncProvider() {
343   return surface_->GetVSyncProvider();
344 }
345
346 bool GLSurfaceAdapter::ScheduleOverlayPlane(int z_order,
347                                             OverlayTransform transform,
348                                             GLImage* image,
349                                             const Rect& bounds_rect,
350                                             const RectF& crop_rect) {
351   return surface_->ScheduleOverlayPlane(
352       z_order, transform, image, bounds_rect, crop_rect);
353 }
354
355 GLSurfaceAdapter::~GLSurfaceAdapter() {}
356
357 }  // namespace gfx