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"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gl/gl_version_info.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<base::ThreadLocalPointer<GLContext> >::Leaky
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_context_ = LAZY_INSTANCE_INITIALIZER;
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)base::LazyInstance<base::ThreadLocalPointer<GLContext> >::Leaky
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    current_real_context_ = LAZY_INSTANCE_INITIALIZER;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochGLContext::ScopedReleaseCurrent::ScopedReleaseCurrent() : canceled_(false) {}
30e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
31e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochGLContext::ScopedReleaseCurrent::~ScopedReleaseCurrent() {
32e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (!canceled_ && GetCurrent()) {
33e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    GetCurrent()->ReleaseCurrent(NULL);
34e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
35e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
36e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
37e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid GLContext::ScopedReleaseCurrent::Cancel() {
38e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  canceled_ = true;
39e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
40e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochGLContext::FlushEvent::FlushEvent() {
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochGLContext::FlushEvent::~FlushEvent() {
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid GLContext::FlushEvent::Signal() {
48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  flag_.Set();
49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool GLContext::FlushEvent::IsSignaled() {
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return flag_.IsSet();
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLContext::GLContext(GLShareGroup* share_group) : share_group_(share_group) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!share_group_.get())
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    share_group_ = new GLShareGroup;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  share_group_->AddContext(this);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLContext::~GLContext() {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  share_group_->RemoveContext(this);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetCurrent() == this) {
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SetCurrent(NULL);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochscoped_refptr<GLContext::FlushEvent> GLContext::SignalFlush() {
70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(IsCurrent(NULL));
71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_refptr<FlushEvent> flush_event = new FlushEvent();
72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  flush_events_.push_back(flush_event);
73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return flush_event;
74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContext::GetTotalGpuMemory(size_t* bytes) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bytes);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *bytes = 0;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLContext::SetSafeToForceGpuSwitch() {
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLContext::SetUnbindFboOnMakeCurrent() {
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NOTIMPLEMENTED();
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GLContext::GetExtensions() {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsCurrent(NULL));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* ext = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::string(ext ? ext : "");
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string GLContext::GetGLVersion() {
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(IsCurrent(NULL));
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const char *version =
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      reinterpret_cast<const char*>(glGetString(GL_VERSION));
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return std::string(version ? version : "");
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string GLContext::GetGLRenderer() {
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(IsCurrent(NULL));
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const char *renderer =
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      reinterpret_cast<const char*>(glGetString(GL_RENDERER));
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return std::string(renderer ? renderer : "");
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContext::HasExtension(const char* name) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string extensions = GetExtensions();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions += " ";
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string delimited_name(name);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delimited_name += " ";
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extensions.find(delimited_name) != std::string::npos;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const GLVersionInfo* GLContext::GetVersionInfo() {
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if(!version_info_) {
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string version = GetGLVersion();
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string renderer = GetGLRenderer();
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    version_info_ = scoped_ptr<GLVersionInfo>(
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new GLVersionInfo(version.c_str(), renderer.c_str()));
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return version_info_.get();
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLShareGroup* GLContext::share_group() {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return share_group_.get();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContext::LosesAllContextsOnContextLost() {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (GetGLImplementation()) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kGLImplementationDesktopGL:
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kGLImplementationEGLGLES2:
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kGLImplementationOSMesaGL:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kGLImplementationAppleGL:
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kGLImplementationMockGL:
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLContext* GLContext::GetCurrent() {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return current_context_.Pointer()->Get();
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)GLContext* GLContext::GetRealCurrent() {
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return current_real_context_.Pointer()->Get();
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void GLContext::SetCurrent(GLSurface* surface) {
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  current_context_.Pointer()->Set(surface ? this : NULL);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLSurface::SetCurrent(surface);
161e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Leave the real GL api current so that unit tests work correctly.
162e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // TODO(sievers): Remove this, but needs all gpu_unittest classes
163e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // to create and make current a context.
164e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (!surface && GetGLImplementation() != kGLImplementationMockGL) {
165e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    SetGLApiToNoContext();
166e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLStateRestorer* GLContext::GetGLStateRestorer() {
170a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return state_restorer_.get();
171a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
172a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
173a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GLContext::SetGLStateRestorer(GLStateRestorer* state_restorer) {
174a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  state_restorer_ = make_scoped_ptr(state_restorer);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContext::WasAllocatedUsingRobustnessExtension() {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool GLContext::InitializeDynamicBindings() {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsCurrent(NULL));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool initialized = false;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (initialized)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return initialized;
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  initialized = InitializeDynamicGLBindings(GetGLImplementation(), this);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!initialized)
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LOG(ERROR) << "Could not initialize dynamic bindings.";
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return initialized;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLContext::SetupForVirtualization() {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!virtual_gl_api_) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual_gl_api_.reset(new VirtualGLApi());
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual_gl_api_->Initialize(&g_driver_gl, this);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContext::MakeVirtuallyCurrent(
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLContext* virtual_context, GLSurface* surface) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(virtual_gl_api_);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return virtual_gl_api_->MakeCurrent(virtual_context, surface);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void GLContext::OnReleaseVirtuallyCurrent(GLContext* virtual_context) {
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (virtual_gl_api_)
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    virtual_gl_api_->OnReleaseVirtuallyCurrent(virtual_context);
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLContext::SetRealGLApi() {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetGLToRealGLApi();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid GLContext::OnFlush() {
215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (size_t n = 0; n < flush_events_.size(); n++)
216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    flush_events_[n]->Signal();
217c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  flush_events_.clear();
218c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)GLContextReal::GLContextReal(GLShareGroup* share_group)
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : GLContext(share_group) {}
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)GLContextReal::~GLContextReal() {}
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void GLContextReal::SetCurrent(GLSurface* surface) {
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GLContext::SetCurrent(surface);
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  current_real_context_.Pointer()->Set(surface ? this : NULL);
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gfx
231