gl_context.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_local.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_bindings.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_context.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_gl_api_implementation.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_implementation.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_surface.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_switches.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<base::ThreadLocalPointer<GLContext> >::Leaky
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_context_ = LAZY_INSTANCE_INITIALIZER;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLContext::GLContext(GLShareGroup* share_group) : share_group_(share_group) {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!share_group_.get())
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    share_group_ = new GLShareGroup;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  share_group_->AddContext(this);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLContext::~GLContext() {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  share_group_->RemoveContext(this);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetCurrent() == this) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetCurrent(NULL, NULL);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContext::GetTotalGpuMemory(size_t* bytes) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bytes);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *bytes = 0;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GLContext::GetExtensions() {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsCurrent(NULL));
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* ext = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::string(ext ? ext : "");
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContext::HasExtension(const char* name) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string extensions = GetExtensions();
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions += " ";
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string delimited_name(name);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delimited_name += " ";
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extensions.find(delimited_name) != std::string::npos;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLShareGroup* GLContext::share_group() {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return share_group_.get();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContext::LosesAllContextsOnContextLost() {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (GetGLImplementation()) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kGLImplementationDesktopGL:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kGLImplementationEGLGLES2:
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kGLImplementationOSMesaGL:
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kGLImplementationAppleGL:
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kGLImplementationMockGL:
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLContext* GLContext::GetCurrent() {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return current_context_.Pointer()->Get();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLContext::SetCurrent(GLContext* context, GLSurface* surface) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_context_.Pointer()->Set(context);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLSurface::SetCurrent(surface);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLStateRestorer* GLContext::GetGLStateRestorer() {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContext::WasAllocatedUsingRobustnessExtension() {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContext::InitializeExtensionBindings() {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsCurrent(NULL));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool initialized = false;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (initialized)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return initialized;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initialized = InitializeGLExtensionBindings(GetGLImplementation(), this);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!initialized)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Could not initialize extension bindings.";
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return initialized;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLContext::SetupForVirtualization() {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!virtual_gl_api_) {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual_gl_api_.reset(new VirtualGLApi());
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual_gl_api_->Initialize(&g_driver_gl, this);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContext::MakeVirtuallyCurrent(
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLContext* virtual_context, GLSurface* surface) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(virtual_gl_api_);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return virtual_gl_api_->MakeCurrent(virtual_context, surface);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLContext::SetRealGLApi() {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetGLToRealGLApi();
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gfx
128