Home | History | Annotate | Download | only in gl
      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 bool GLSurface::IsSurfaceless() const {
    239   return false;
    240 }
    241 
    242 GLSurface* GLSurface::GetCurrent() {
    243   return current_surface_.Pointer()->Get();
    244 }
    245 
    246 GLSurface::~GLSurface() {
    247   if (GetCurrent() == this)
    248     SetCurrent(NULL);
    249 }
    250 
    251 void GLSurface::SetCurrent(GLSurface* surface) {
    252   current_surface_.Pointer()->Set(surface);
    253 }
    254 
    255 bool GLSurface::ExtensionsContain(const char* c_extensions, const char* name) {
    256   DCHECK(name);
    257   if (!c_extensions)
    258     return false;
    259   std::string extensions(c_extensions);
    260   extensions += " ";
    261 
    262   std::string delimited_name(name);
    263   delimited_name += " ";
    264 
    265   return extensions.find(delimited_name) != std::string::npos;
    266 }
    267 
    268 GLSurfaceAdapter::GLSurfaceAdapter(GLSurface* surface) : surface_(surface) {}
    269 
    270 bool GLSurfaceAdapter::Initialize() {
    271   return surface_->Initialize();
    272 }
    273 
    274 void GLSurfaceAdapter::Destroy() {
    275   surface_->Destroy();
    276 }
    277 
    278 bool GLSurfaceAdapter::Resize(const gfx::Size& size) {
    279   return surface_->Resize(size);
    280 }
    281 
    282 bool GLSurfaceAdapter::Recreate() {
    283   return surface_->Recreate();
    284 }
    285 
    286 bool GLSurfaceAdapter::DeferDraws() {
    287   return surface_->DeferDraws();
    288 }
    289 
    290 bool GLSurfaceAdapter::IsOffscreen() {
    291   return surface_->IsOffscreen();
    292 }
    293 
    294 bool GLSurfaceAdapter::SwapBuffers() {
    295   return surface_->SwapBuffers();
    296 }
    297 
    298 bool GLSurfaceAdapter::PostSubBuffer(int x, int y, int width, int height) {
    299   return surface_->PostSubBuffer(x, y, width, height);
    300 }
    301 
    302 bool GLSurfaceAdapter::SupportsPostSubBuffer() {
    303   return surface_->SupportsPostSubBuffer();
    304 }
    305 
    306 gfx::Size GLSurfaceAdapter::GetSize() {
    307   return surface_->GetSize();
    308 }
    309 
    310 void* GLSurfaceAdapter::GetHandle() {
    311   return surface_->GetHandle();
    312 }
    313 
    314 unsigned int GLSurfaceAdapter::GetBackingFrameBufferObject() {
    315   return surface_->GetBackingFrameBufferObject();
    316 }
    317 
    318 bool GLSurfaceAdapter::OnMakeCurrent(GLContext* context) {
    319   return surface_->OnMakeCurrent(context);
    320 }
    321 
    322 bool GLSurfaceAdapter::SetBackbufferAllocation(bool allocated) {
    323   return surface_->SetBackbufferAllocation(allocated);
    324 }
    325 
    326 void GLSurfaceAdapter::SetFrontbufferAllocation(bool allocated) {
    327   surface_->SetFrontbufferAllocation(allocated);
    328 }
    329 
    330 void* GLSurfaceAdapter::GetShareHandle() {
    331   return surface_->GetShareHandle();
    332 }
    333 
    334 void* GLSurfaceAdapter::GetDisplay() {
    335   return surface_->GetDisplay();
    336 }
    337 
    338 void* GLSurfaceAdapter::GetConfig() {
    339   return surface_->GetConfig();
    340 }
    341 
    342 unsigned GLSurfaceAdapter::GetFormat() {
    343   return surface_->GetFormat();
    344 }
    345 
    346 VSyncProvider* GLSurfaceAdapter::GetVSyncProvider() {
    347   return surface_->GetVSyncProvider();
    348 }
    349 
    350 bool GLSurfaceAdapter::ScheduleOverlayPlane(int z_order,
    351                                             OverlayTransform transform,
    352                                             GLImage* image,
    353                                             const Rect& bounds_rect,
    354                                             const RectF& crop_rect) {
    355   return surface_->ScheduleOverlayPlane(
    356       z_order, transform, image, bounds_rect, crop_rect);
    357 }
    358 
    359 bool GLSurfaceAdapter::IsSurfaceless() const {
    360   return surface_->IsSurfaceless();
    361 }
    362 
    363 GLSurfaceAdapter::~GLSurfaceAdapter() {}
    364 
    365 }  // namespace gfx
    366