• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include <string>
6 
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"
18 
19 namespace gfx {
20 
21 namespace {
22 base::LazyInstance<base::ThreadLocalPointer<GLContext> >::Leaky
23     current_context_ = LAZY_INSTANCE_INITIALIZER;
24 
25 base::LazyInstance<base::ThreadLocalPointer<GLContext> >::Leaky
26     current_real_context_ = LAZY_INSTANCE_INITIALIZER;
27 }  // namespace
28 
ScopedReleaseCurrent()29 GLContext::ScopedReleaseCurrent::ScopedReleaseCurrent() : canceled_(false) {}
30 
~ScopedReleaseCurrent()31 GLContext::ScopedReleaseCurrent::~ScopedReleaseCurrent() {
32   if (!canceled_ && GetCurrent()) {
33     GetCurrent()->ReleaseCurrent(NULL);
34   }
35 }
36 
Cancel()37 void GLContext::ScopedReleaseCurrent::Cancel() {
38   canceled_ = true;
39 }
40 
FlushEvent()41 GLContext::FlushEvent::FlushEvent() {
42 }
43 
~FlushEvent()44 GLContext::FlushEvent::~FlushEvent() {
45 }
46 
Signal()47 void GLContext::FlushEvent::Signal() {
48   flag_.Set();
49 }
50 
IsSignaled()51 bool GLContext::FlushEvent::IsSignaled() {
52   return flag_.IsSet();
53 }
54 
GLContext(GLShareGroup * share_group)55 GLContext::GLContext(GLShareGroup* share_group) : share_group_(share_group) {
56   if (!share_group_.get())
57     share_group_ = new GLShareGroup;
58 
59   share_group_->AddContext(this);
60 }
61 
~GLContext()62 GLContext::~GLContext() {
63   share_group_->RemoveContext(this);
64   if (GetCurrent() == this) {
65     SetCurrent(NULL);
66   }
67 }
68 
SignalFlush()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;
74 }
75 
GetTotalGpuMemory(size_t * bytes)76 bool GLContext::GetTotalGpuMemory(size_t* bytes) {
77   DCHECK(bytes);
78   *bytes = 0;
79   return false;
80 }
81 
SetSafeToForceGpuSwitch()82 void GLContext::SetSafeToForceGpuSwitch() {
83 }
84 
SetUnbindFboOnMakeCurrent()85 void GLContext::SetUnbindFboOnMakeCurrent() {
86   NOTIMPLEMENTED();
87 }
88 
GetExtensions()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 : "");
93 }
94 
GetGLVersion()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 : "");
100 }
101 
GetGLRenderer()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 : "");
107 }
108 
HasExtension(const char * name)109 bool GLContext::HasExtension(const char* name) {
110   std::string extensions = GetExtensions();
111   extensions += " ";
112 
113   std::string delimited_name(name);
114   delimited_name += " ";
115 
116   return extensions.find(delimited_name) != std::string::npos;
117 }
118 
GetVersionInfo()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()));
125   }
126   return version_info_.get();
127 }
128 
share_group()129 GLShareGroup* GLContext::share_group() {
130   return share_group_.get();
131 }
132 
LosesAllContextsOnContextLost()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;
147   }
148 }
149 
GetCurrent()150 GLContext* GLContext::GetCurrent() {
151   return current_context_.Pointer()->Get();
152 }
153 
GetRealCurrent()154 GLContext* GLContext::GetRealCurrent() {
155   return current_real_context_.Pointer()->Get();
156 }
157 
SetCurrent(GLSurface * surface)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();
166   }
167 }
168 
GetGLStateRestorer()169 GLStateRestorer* GLContext::GetGLStateRestorer() {
170   return state_restorer_.get();
171 }
172 
SetGLStateRestorer(GLStateRestorer * state_restorer)173 void GLContext::SetGLStateRestorer(GLStateRestorer* state_restorer) {
174   state_restorer_ = make_scoped_ptr(state_restorer);
175 }
176 
WasAllocatedUsingRobustnessExtension()177 bool GLContext::WasAllocatedUsingRobustnessExtension() {
178   return false;
179 }
180 
InitializeDynamicBindings()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;
190 }
191 
SetupForVirtualization()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);
196   }
197 }
198 
MakeVirtuallyCurrent(GLContext * virtual_context,GLSurface * surface)199 bool GLContext::MakeVirtuallyCurrent(
200     GLContext* virtual_context, GLSurface* surface) {
201   DCHECK(virtual_gl_api_);
202   return virtual_gl_api_->MakeCurrent(virtual_context, surface);
203 }
204 
OnReleaseVirtuallyCurrent(GLContext * virtual_context)205 void GLContext::OnReleaseVirtuallyCurrent(GLContext* virtual_context) {
206   if (virtual_gl_api_)
207     virtual_gl_api_->OnReleaseVirtuallyCurrent(virtual_context);
208 }
209 
SetRealGLApi()210 void GLContext::SetRealGLApi() {
211   SetGLToRealGLApi();
212 }
213 
OnFlush()214 void GLContext::OnFlush() {
215   for (size_t n = 0; n < flush_events_.size(); n++)
216     flush_events_[n]->Signal();
217   flush_events_.clear();
218 }
219 
GLContextReal(GLShareGroup * share_group)220 GLContextReal::GLContextReal(GLShareGroup* share_group)
221     : GLContext(share_group) {}
222 
~GLContextReal()223 GLContextReal::~GLContextReal() {}
224 
SetCurrent(GLSurface * surface)225 void GLContextReal::SetCurrent(GLSurface* surface) {
226   GLContext::SetCurrent(surface);
227   current_real_context_.Pointer()->Set(surface ? this : NULL);
228 }
229 
230 }  // namespace gfx
231