Fix crash on key events in touchview.
[chromium-blink-merge.git] / ui / gl / gl_context.cc
blob533b7d3146e89de6242720d611f9d967bde6dd94
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 void GLContext::SetUnbindFboOnMakeCurrent() {
86 NOTIMPLEMENTED();
89 std::string GLContext::GetExtensions() {
90 DCHECK(IsCurrent(NULL));
91 const char* ext = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
92 return std::string(ext ? ext : "");
95 std::string GLContext::GetGLVersion() {
96 DCHECK(IsCurrent(NULL));
97 const char *version =
98 reinterpret_cast<const char*>(glGetString(GL_VERSION));
99 return std::string(version ? version : "");
102 std::string GLContext::GetGLRenderer() {
103 DCHECK(IsCurrent(NULL));
104 const char *renderer =
105 reinterpret_cast<const char*>(glGetString(GL_RENDERER));
106 return std::string(renderer ? renderer : "");
109 bool GLContext::HasExtension(const char* name) {
110 std::string extensions = GetExtensions();
111 extensions += " ";
113 std::string delimited_name(name);
114 delimited_name += " ";
116 return extensions.find(delimited_name) != std::string::npos;
119 const GLVersionInfo* GLContext::GetVersionInfo() {
120 if(!version_info_) {
121 std::string version = GetGLVersion();
122 std::string renderer = GetGLRenderer();
123 version_info_ = scoped_ptr<GLVersionInfo>(
124 new GLVersionInfo(version.c_str(), renderer.c_str()));
126 return version_info_.get();
129 GLShareGroup* GLContext::share_group() {
130 return share_group_.get();
133 bool GLContext::LosesAllContextsOnContextLost() {
134 switch (GetGLImplementation()) {
135 case kGLImplementationDesktopGL:
136 return false;
137 case kGLImplementationEGLGLES2:
138 return true;
139 case kGLImplementationOSMesaGL:
140 case kGLImplementationAppleGL:
141 return false;
142 case kGLImplementationMockGL:
143 return false;
144 default:
145 NOTREACHED();
146 return true;
150 GLContext* GLContext::GetCurrent() {
151 return current_context_.Pointer()->Get();
154 GLContext* GLContext::GetRealCurrent() {
155 return current_real_context_.Pointer()->Get();
158 void GLContext::SetCurrent(GLSurface* surface) {
159 current_context_.Pointer()->Set(surface ? this : NULL);
160 GLSurface::SetCurrent(surface);
161 // Leave the real GL api current so that unit tests work correctly.
162 // TODO(sievers): Remove this, but needs all gpu_unittest classes
163 // to create and make current a context.
164 if (!surface && GetGLImplementation() != kGLImplementationMockGL) {
165 SetGLApiToNoContext();
169 GLStateRestorer* GLContext::GetGLStateRestorer() {
170 return state_restorer_.get();
173 void GLContext::SetGLStateRestorer(GLStateRestorer* state_restorer) {
174 state_restorer_ = make_scoped_ptr(state_restorer);
177 bool GLContext::WasAllocatedUsingRobustnessExtension() {
178 return false;
181 bool GLContext::InitializeDynamicBindings() {
182 DCHECK(IsCurrent(NULL));
183 static bool initialized = false;
184 if (initialized)
185 return initialized;
186 initialized = InitializeDynamicGLBindings(GetGLImplementation(), this);
187 if (!initialized)
188 LOG(ERROR) << "Could not initialize dynamic bindings.";
189 return initialized;
192 void GLContext::SetupForVirtualization() {
193 if (!virtual_gl_api_) {
194 virtual_gl_api_.reset(new VirtualGLApi());
195 virtual_gl_api_->Initialize(&g_driver_gl, this);
199 bool GLContext::MakeVirtuallyCurrent(
200 GLContext* virtual_context, GLSurface* surface) {
201 DCHECK(virtual_gl_api_);
202 return virtual_gl_api_->MakeCurrent(virtual_context, surface);
205 void GLContext::OnReleaseVirtuallyCurrent(GLContext* virtual_context) {
206 if (virtual_gl_api_)
207 virtual_gl_api_->OnReleaseVirtuallyCurrent(virtual_context);
210 void GLContext::SetRealGLApi() {
211 SetGLToRealGLApi();
214 void GLContext::OnFlush() {
215 for (size_t n = 0; n < flush_events_.size(); n++)
216 flush_events_[n]->Signal();
217 flush_events_.clear();
220 GLContextReal::GLContextReal(GLShareGroup* share_group)
221 : GLContext(share_group) {}
223 GLContextReal::~GLContextReal() {}
225 void GLContextReal::SetCurrent(GLSurface* surface) {
226 GLContext::SetCurrent(surface);
227 current_real_context_.Pointer()->Set(surface ? this : NULL);
230 } // namespace gfx