Suppress data races in blink::Scheduler
[chromium-blink-merge.git] / ui / gl / gl_context.cc
blobf89f1d2a697c1d658cec151e64cab4f1e121e1e1
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::GLContext(GLShareGroup* share_group) :
42 share_group_(share_group),
43 swap_interval_(1),
44 force_swap_interval_zero_(false) {
45 if (!share_group_.get())
46 share_group_ = new GLShareGroup;
48 share_group_->AddContext(this);
51 GLContext::~GLContext() {
52 share_group_->RemoveContext(this);
53 if (GetCurrent() == this) {
54 SetCurrent(NULL);
58 bool GLContext::GetTotalGpuMemory(size_t* bytes) {
59 DCHECK(bytes);
60 *bytes = 0;
61 return false;
64 void GLContext::SetSafeToForceGpuSwitch() {
67 bool GLContext::ForceGpuSwitchIfNeeded() {
68 return true;
71 void GLContext::SetUnbindFboOnMakeCurrent() {
72 NOTIMPLEMENTED();
75 std::string GLContext::GetExtensions() {
76 DCHECK(IsCurrent(NULL));
77 const char* ext = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
78 return std::string(ext ? ext : "");
81 std::string GLContext::GetGLVersion() {
82 DCHECK(IsCurrent(NULL));
83 const char *version =
84 reinterpret_cast<const char*>(glGetString(GL_VERSION));
85 return std::string(version ? version : "");
88 std::string GLContext::GetGLRenderer() {
89 DCHECK(IsCurrent(NULL));
90 const char *renderer =
91 reinterpret_cast<const char*>(glGetString(GL_RENDERER));
92 return std::string(renderer ? renderer : "");
95 bool GLContext::HasExtension(const char* name) {
96 std::string extensions = GetExtensions();
97 extensions += " ";
99 std::string delimited_name(name);
100 delimited_name += " ";
102 return extensions.find(delimited_name) != std::string::npos;
105 const GLVersionInfo* GLContext::GetVersionInfo() {
106 if(!version_info_) {
107 std::string version = GetGLVersion();
108 std::string renderer = GetGLRenderer();
109 version_info_ = scoped_ptr<GLVersionInfo>(
110 new GLVersionInfo(version.c_str(), renderer.c_str()));
112 return version_info_.get();
115 GLShareGroup* GLContext::share_group() {
116 return share_group_.get();
119 bool GLContext::LosesAllContextsOnContextLost() {
120 switch (GetGLImplementation()) {
121 case kGLImplementationDesktopGL:
122 return false;
123 case kGLImplementationEGLGLES2:
124 return true;
125 case kGLImplementationOSMesaGL:
126 case kGLImplementationAppleGL:
127 return false;
128 case kGLImplementationMockGL:
129 return false;
130 default:
131 NOTREACHED();
132 return true;
136 GLContext* GLContext::GetCurrent() {
137 return current_context_.Pointer()->Get();
140 GLContext* GLContext::GetRealCurrent() {
141 return current_real_context_.Pointer()->Get();
144 void GLContext::SetCurrent(GLSurface* surface) {
145 current_context_.Pointer()->Set(surface ? this : NULL);
146 GLSurface::SetCurrent(surface);
147 // Leave the real GL api current so that unit tests work correctly.
148 // TODO(sievers): Remove this, but needs all gpu_unittest classes
149 // to create and make current a context.
150 if (!surface && GetGLImplementation() != kGLImplementationMockGL) {
151 SetGLApiToNoContext();
155 GLStateRestorer* GLContext::GetGLStateRestorer() {
156 return state_restorer_.get();
159 void GLContext::SetGLStateRestorer(GLStateRestorer* state_restorer) {
160 state_restorer_ = make_scoped_ptr(state_restorer);
163 void GLContext::SetSwapInterval(int interval) {
164 swap_interval_ = interval;
165 OnSetSwapInterval(force_swap_interval_zero_ ? 0 : swap_interval_);
168 void GLContext::ForceSwapIntervalZero(bool force) {
169 force_swap_interval_zero_ = force;
170 OnSetSwapInterval(force_swap_interval_zero_ ? 0 : swap_interval_);
173 bool GLContext::WasAllocatedUsingRobustnessExtension() {
174 return false;
177 bool GLContext::InitializeDynamicBindings() {
178 DCHECK(IsCurrent(NULL));
179 static bool initialized = false;
180 if (initialized)
181 return initialized;
182 initialized = InitializeDynamicGLBindings(GetGLImplementation(), this);
183 if (!initialized)
184 LOG(ERROR) << "Could not initialize dynamic bindings.";
185 return initialized;
188 void GLContext::SetupForVirtualization() {
189 if (!virtual_gl_api_) {
190 virtual_gl_api_.reset(new VirtualGLApi());
191 virtual_gl_api_->Initialize(&g_driver_gl, this);
195 bool GLContext::MakeVirtuallyCurrent(
196 GLContext* virtual_context, GLSurface* surface) {
197 DCHECK(virtual_gl_api_);
198 if (!ForceGpuSwitchIfNeeded())
199 return false;
200 return virtual_gl_api_->MakeCurrent(virtual_context, surface);
203 void GLContext::OnReleaseVirtuallyCurrent(GLContext* virtual_context) {
204 if (virtual_gl_api_)
205 virtual_gl_api_->OnReleaseVirtuallyCurrent(virtual_context);
208 void GLContext::SetRealGLApi() {
209 SetGLToRealGLApi();
212 GLContextReal::GLContextReal(GLShareGroup* share_group)
213 : GLContext(share_group) {}
215 GLContextReal::~GLContextReal() {}
217 void GLContextReal::SetCurrent(GLSurface* surface) {
218 GLContext::SetCurrent(surface);
219 current_real_context_.Pointer()->Set(surface ? this : NULL);
222 } // namespace gfx