root/ui/gl/gl_surface.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. InitializeOneOff
  2. InitializeOneOffImplementation
  3. InitializeOneOffForTests
  4. InitializeOneOffWithMockBindingsForTests
  5. InitializeDynamicMockBindingsForTests
  6. Initialize
  7. Resize
  8. Recreate
  9. DeferDraws
  10. SupportsPostSubBuffer
  11. GetBackingFrameBufferObject
  12. PostSubBuffer
  13. OnMakeCurrent
  14. SetBackbufferAllocation
  15. SetFrontbufferAllocation
  16. GetShareHandle
  17. GetDisplay
  18. GetConfig
  19. GetFormat
  20. GetVSyncProvider
  21. GetCurrent
  22. SetCurrent
  23. ExtensionsContain
  24. Initialize
  25. Destroy
  26. Resize
  27. Recreate
  28. DeferDraws
  29. IsOffscreen
  30. SwapBuffers
  31. PostSubBuffer
  32. SupportsPostSubBuffer
  33. GetSize
  34. GetHandle
  35. GetBackingFrameBufferObject
  36. OnMakeCurrent
  37. SetBackbufferAllocation
  38. SetFrontbufferAllocation
  39. GetShareHandle
  40. GetDisplay
  41. GetConfig
  42. GetFormat
  43. GetVSyncProvider

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gl/gl_surface.h"

#include <algorithm>
#include <vector>

#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/threading/thread_local.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_switches.h"

#if defined(USE_X11)
#include <X11/Xlib.h>
#endif

namespace gfx {

namespace {
base::LazyInstance<base::ThreadLocalPointer<GLSurface> >::Leaky
    current_surface_ = LAZY_INSTANCE_INITIALIZER;
}  // namespace

// static
bool GLSurface::InitializeOneOff() {
  DCHECK_EQ(kGLImplementationNone, GetGLImplementation());

  TRACE_EVENT0("gpu", "GLSurface::InitializeOneOff");

  std::vector<GLImplementation> allowed_impls;
  GetAllowedGLImplementations(&allowed_impls);
  DCHECK(!allowed_impls.empty());

  CommandLine* cmd = CommandLine::ForCurrentProcess();

  // The default implementation is always the first one in list.
  GLImplementation impl = allowed_impls[0];
  bool fallback_to_osmesa = false;
  if (cmd->HasSwitch(switches::kUseGL)) {
    std::string requested_implementation_name =
        cmd->GetSwitchValueASCII(switches::kUseGL);
    if (requested_implementation_name == "any") {
      fallback_to_osmesa = true;
    } else if (requested_implementation_name == "swiftshader") {
      impl = kGLImplementationEGLGLES2;
    } else {
      impl = GetNamedGLImplementation(requested_implementation_name);
      if (std::find(allowed_impls.begin(),
                    allowed_impls.end(),
                    impl) == allowed_impls.end()) {
        LOG(ERROR) << "Requested GL implementation is not available.";
        return false;
      }
    }
  }

  bool gpu_service_logging = cmd->HasSwitch(switches::kEnableGPUServiceLogging);
  bool disable_gl_drawing = cmd->HasSwitch(switches::kDisableGLDrawingForTests);

  return InitializeOneOffImplementation(
      impl, fallback_to_osmesa, gpu_service_logging, disable_gl_drawing);
}

// static
bool GLSurface::InitializeOneOffImplementation(GLImplementation impl,
                                               bool fallback_to_osmesa,
                                               bool gpu_service_logging,
                                               bool disable_gl_drawing) {
  bool initialized =
      InitializeStaticGLBindings(impl) && InitializeOneOffInternal();
  if (!initialized && fallback_to_osmesa) {
    ClearGLBindings();
    initialized = InitializeStaticGLBindings(kGLImplementationOSMesaGL) &&
                  InitializeOneOffInternal();
  }
  if (!initialized)
    ClearGLBindings();

  if (initialized) {
    DVLOG(1) << "Using "
             << GetGLImplementationName(GetGLImplementation())
             << " GL implementation.";
    if (gpu_service_logging)
      InitializeDebugGLBindings();
    if (disable_gl_drawing)
      InitializeNullDrawGLBindings();
  }
  return initialized;
}

// static
void GLSurface::InitializeOneOffForTests() {
  DCHECK_EQ(kGLImplementationNone, GetGLImplementation());

#if defined(USE_X11)
  XInitThreads();
#endif

  bool use_osmesa = true;

  // We usually use OSMesa as this works on all bots. The command line can
  // override this behaviour to use hardware GL.
  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGpuInTests))
    use_osmesa = false;

#if defined(OS_ANDROID)
  // On Android we always use hardware GL.
  use_osmesa = false;
#endif

  std::vector<GLImplementation> allowed_impls;
  GetAllowedGLImplementations(&allowed_impls);
  DCHECK(!allowed_impls.empty());

  GLImplementation impl = allowed_impls[0];
  if (use_osmesa)
    impl = kGLImplementationOSMesaGL;

  DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL))
      << "kUseGL has not effect in tests";

  bool fallback_to_osmesa = false;
  bool gpu_service_logging = false;
  bool disable_gl_drawing = true;

  CHECK(InitializeOneOffImplementation(
      impl, fallback_to_osmesa, gpu_service_logging, disable_gl_drawing));
}

// static
void GLSurface::InitializeOneOffWithMockBindingsForTests() {
  DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL))
      << "kUseGL has not effect in tests";

  // This method may be called multiple times in the same process to set up
  // mock bindings in different ways.
  ClearGLBindings();

  bool fallback_to_osmesa = false;
  bool gpu_service_logging = false;
  bool disable_gl_drawing = false;

  CHECK(InitializeOneOffImplementation(kGLImplementationMockGL,
                                       fallback_to_osmesa,
                                       gpu_service_logging,
                                       disable_gl_drawing));
}

// static
void GLSurface::InitializeDynamicMockBindingsForTests(GLContext* context) {
  CHECK(InitializeDynamicGLBindings(kGLImplementationMockGL, context));
}

GLSurface::GLSurface() {}

bool GLSurface::Initialize() {
  return true;
}

bool GLSurface::Resize(const gfx::Size& size) {
  NOTIMPLEMENTED();
  return false;
}

bool GLSurface::Recreate() {
  NOTIMPLEMENTED();
  return false;
}

bool GLSurface::DeferDraws() {
  return false;
}

bool GLSurface::SupportsPostSubBuffer() {
  return false;
}

unsigned int GLSurface::GetBackingFrameBufferObject() {
  return 0;
}

bool GLSurface::PostSubBuffer(int x, int y, int width, int height) {
  return false;
}

bool GLSurface::OnMakeCurrent(GLContext* context) {
  return true;
}

bool GLSurface::SetBackbufferAllocation(bool allocated) {
  return true;
}

void GLSurface::SetFrontbufferAllocation(bool allocated) {
}

void* GLSurface::GetShareHandle() {
  NOTIMPLEMENTED();
  return NULL;
}

void* GLSurface::GetDisplay() {
  NOTIMPLEMENTED();
  return NULL;
}

void* GLSurface::GetConfig() {
  NOTIMPLEMENTED();
  return NULL;
}

unsigned GLSurface::GetFormat() {
  NOTIMPLEMENTED();
  return 0;
}

VSyncProvider* GLSurface::GetVSyncProvider() {
  return NULL;
}

GLSurface* GLSurface::GetCurrent() {
  return current_surface_.Pointer()->Get();
}

GLSurface::~GLSurface() {
  if (GetCurrent() == this)
    SetCurrent(NULL);
}

void GLSurface::SetCurrent(GLSurface* surface) {
  current_surface_.Pointer()->Set(surface);
}

bool GLSurface::ExtensionsContain(const char* c_extensions, const char* name) {
  DCHECK(name);
  if (!c_extensions)
    return false;
  std::string extensions(c_extensions);
  extensions += " ";

  std::string delimited_name(name);
  delimited_name += " ";

  return extensions.find(delimited_name) != std::string::npos;
}

GLSurfaceAdapter::GLSurfaceAdapter(GLSurface* surface) : surface_(surface) {}

bool GLSurfaceAdapter::Initialize() {
  return surface_->Initialize();
}

void GLSurfaceAdapter::Destroy() {
  surface_->Destroy();
}

bool GLSurfaceAdapter::Resize(const gfx::Size& size) {
  return surface_->Resize(size);
}

bool GLSurfaceAdapter::Recreate() {
  return surface_->Recreate();
}

bool GLSurfaceAdapter::DeferDraws() {
  return surface_->DeferDraws();
}

bool GLSurfaceAdapter::IsOffscreen() {
  return surface_->IsOffscreen();
}

bool GLSurfaceAdapter::SwapBuffers() {
  return surface_->SwapBuffers();
}

bool GLSurfaceAdapter::PostSubBuffer(int x, int y, int width, int height) {
  return surface_->PostSubBuffer(x, y, width, height);
}

bool GLSurfaceAdapter::SupportsPostSubBuffer() {
  return surface_->SupportsPostSubBuffer();
}

gfx::Size GLSurfaceAdapter::GetSize() {
  return surface_->GetSize();
}

void* GLSurfaceAdapter::GetHandle() {
  return surface_->GetHandle();
}

unsigned int GLSurfaceAdapter::GetBackingFrameBufferObject() {
  return surface_->GetBackingFrameBufferObject();
}

bool GLSurfaceAdapter::OnMakeCurrent(GLContext* context) {
  return surface_->OnMakeCurrent(context);
}

bool GLSurfaceAdapter::SetBackbufferAllocation(bool allocated) {
  return surface_->SetBackbufferAllocation(allocated);
}

void GLSurfaceAdapter::SetFrontbufferAllocation(bool allocated) {
  surface_->SetFrontbufferAllocation(allocated);
}

void* GLSurfaceAdapter::GetShareHandle() {
  return surface_->GetShareHandle();
}

void* GLSurfaceAdapter::GetDisplay() {
  return surface_->GetDisplay();
}

void* GLSurfaceAdapter::GetConfig() {
  return surface_->GetConfig();
}

unsigned GLSurfaceAdapter::GetFormat() {
  return surface_->GetFormat();
}

VSyncProvider* GLSurfaceAdapter::GetVSyncProvider() {
  return surface_->GetVSyncProvider();
}

GLSurfaceAdapter::~GLSurfaceAdapter() {}

}  // namespace gfx

/* [<][>][^][v][top][bottom][index][help] */