Mac: Fix performance issues with remote CoreAnimation
[chromium-blink-merge.git] / ui / gl / gl_context.cc
blobe35806917f3e15cbc87f77124a8fa4c73d850e80
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.
5 #include <string>
7 #include "base/command_line.h"
8 #include "base/lazy_instance.h"
9 #include "base/logging.h"
10 #include "base/threading/thread_local.h"
11 #include "ui/gl/gl_bindings.h"
12 #include "ui/gl/gl_context.h"
13 #include "ui/gl/gl_gl_api_implementation.h"
14 #include "ui/gl/gl_implementation.h"
15 #include "ui/gl/gl_surface.h"
16 #include "ui/gl/gl_switches.h"
17 #include "ui/gl/gl_version_info.h"
19 namespace gfx {
21 namespace {
22 base::LazyInstance<base::ThreadLocalPointer<GLContext> >::Leaky
23 current_context_ = LAZY_INSTANCE_INITIALIZER;
25 base::LazyInstance<base::ThreadLocalPointer<GLContext> >::Leaky
26 current_real_context_ = LAZY_INSTANCE_INITIALIZER;
27 } // namespace
29 GLContext::ScopedReleaseCurrent::ScopedReleaseCurrent() : canceled_(false) {}
31 GLContext::ScopedReleaseCurrent::~ScopedReleaseCurrent() {
32 if (!canceled_ && GetCurrent()) {
33 GetCurrent()->ReleaseCurrent(NULL);
37 void GLContext::ScopedReleaseCurrent::Cancel() {
38 canceled_ = true;
41 GLContext::FlushEvent::FlushEvent() {
44 GLContext::FlushEvent::~FlushEvent() {
47 void GLContext::FlushEvent::Signal() {
48 flag_.Set();
51 bool GLContext::FlushEvent::IsSignaled() {
52 return flag_.IsSet();
55 GLContext::GLContext(GLShareGroup* share_group) : share_group_(share_group) {
56 if (!share_group_.get())
57 share_group_ = new GLShareGroup;
59 share_group_->AddContext(this);
62 GLContext::~GLContext() {
63 share_group_->RemoveContext(this);
64 if (GetCurrent() == this) {
65 SetCurrent(NULL);
69 scoped_refptr<GLContext::FlushEvent> GLContext::SignalFlush() {
70 DCHECK(IsCurrent(NULL));
71 scoped_refptr<FlushEvent> flush_event = new FlushEvent();
72 flush_events_.push_back(flush_event);
73 return flush_event;
76 bool GLContext::GetTotalGpuMemory(size_t* bytes) {
77 DCHECK(bytes);
78 *bytes = 0;
79 return false;
82 void GLContext::SetSafeToForceGpuSwitch() {
85 bool GLContext::ForceGpuSwitchIfNeeded() {
86 return true;
89 void GLContext::SetUnbindFboOnMakeCurrent() {
90 NOTIMPLEMENTED();
93 std::string GLContext::GetExtensions() {
94 DCHECK(IsCurrent(NULL));
95 const char* ext = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
96 return std::string(ext ? ext : "");
99 std::string GLContext::GetGLVersion() {
100 DCHECK(IsCurrent(NULL));
101 const char *version =
102 reinterpret_cast<const char*>(glGetString(GL_VERSION));
103 return std::string(version ? version : "");
106 std::string GLContext::GetGLRenderer() {
107 DCHECK(IsCurrent(NULL));
108 const char *renderer =
109 reinterpret_cast<const char*>(glGetString(GL_RENDERER));
110 return std::string(renderer ? renderer : "");
113 bool GLContext::HasExtension(const char* name) {
114 std::string extensions = GetExtensions();
115 extensions += " ";
117 std::string delimited_name(name);
118 delimited_name += " ";
120 return extensions.find(delimited_name) != std::string::npos;
123 const GLVersionInfo* GLContext::GetVersionInfo() {
124 if(!version_info_) {
125 std::string version = GetGLVersion();
126 std::string renderer = GetGLRenderer();
127 version_info_ = scoped_ptr<GLVersionInfo>(
128 new GLVersionInfo(version.c_str(), renderer.c_str()));
130 return version_info_.get();
133 GLShareGroup* GLContext::share_group() {
134 return share_group_.get();
137 bool GLContext::LosesAllContextsOnContextLost() {
138 switch (GetGLImplementation()) {
139 case kGLImplementationDesktopGL:
140 return false;
141 case kGLImplementationEGLGLES2:
142 return true;
143 case kGLImplementationOSMesaGL:
144 case kGLImplementationAppleGL:
145 return false;
146 case kGLImplementationMockGL:
147 return false;
148 default:
149 NOTREACHED();
150 return true;
154 GLContext* GLContext::GetCurrent() {
155 return current_context_.Pointer()->Get();
158 GLContext* GLContext::GetRealCurrent() {
159 return current_real_context_.Pointer()->Get();
162 void GLContext::SetCurrent(GLSurface* surface) {
163 current_context_.Pointer()->Set(surface ? this : NULL);
164 GLSurface::SetCurrent(surface);
165 // Leave the real GL api current so that unit tests work correctly.
166 // TODO(sievers): Remove this, but needs all gpu_unittest classes
167 // to create and make current a context.
168 if (!surface && GetGLImplementation() != kGLImplementationMockGL) {
169 SetGLApiToNoContext();
173 GLStateRestorer* GLContext::GetGLStateRestorer() {
174 return state_restorer_.get();
177 void GLContext::SetGLStateRestorer(GLStateRestorer* state_restorer) {
178 state_restorer_ = make_scoped_ptr(state_restorer);
181 bool GLContext::WasAllocatedUsingRobustnessExtension() {
182 return false;
185 bool GLContext::InitializeDynamicBindings() {
186 DCHECK(IsCurrent(NULL));
187 static bool initialized = false;
188 if (initialized)
189 return initialized;
190 initialized = InitializeDynamicGLBindings(GetGLImplementation(), this);
191 if (!initialized)
192 LOG(ERROR) << "Could not initialize dynamic bindings.";
193 return initialized;
196 void GLContext::SetupForVirtualization() {
197 if (!virtual_gl_api_) {
198 virtual_gl_api_.reset(new VirtualGLApi());
199 virtual_gl_api_->Initialize(&g_driver_gl, this);
203 bool GLContext::MakeVirtuallyCurrent(
204 GLContext* virtual_context, GLSurface* surface) {
205 DCHECK(virtual_gl_api_);
206 if (!ForceGpuSwitchIfNeeded())
207 return false;
208 return virtual_gl_api_->MakeCurrent(virtual_context, surface);
211 void GLContext::OnReleaseVirtuallyCurrent(GLContext* virtual_context) {
212 if (virtual_gl_api_)
213 virtual_gl_api_->OnReleaseVirtuallyCurrent(virtual_context);
216 void GLContext::SetRealGLApi() {
217 SetGLToRealGLApi();
220 void GLContext::OnFlush() {
221 for (size_t n = 0; n < flush_events_.size(); n++)
222 flush_events_[n]->Signal();
223 flush_events_.clear();
226 GLContextReal::GLContextReal(GLShareGroup* share_group)
227 : GLContext(share_group) {}
229 GLContextReal::~GLContextReal() {}
231 void GLContextReal::SetCurrent(GLSurface* surface) {
232 GLContext::SetCurrent(surface);
233 current_real_context_.Pointer()->Set(surface ? this : NULL);
236 } // namespace gfx