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.
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"
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
;
29 GLContext::GLContext(GLShareGroup
* share_group
) : share_group_(share_group
) {
30 if (!share_group_
.get())
31 share_group_
= new GLShareGroup
;
33 share_group_
->AddContext(this);
36 GLContext::~GLContext() {
37 share_group_
->RemoveContext(this);
38 if (GetCurrent() == this) {
43 bool GLContext::GetTotalGpuMemory(size_t* bytes
) {
49 void GLContext::SetSafeToForceGpuSwitch() {
52 void GLContext::SetUnbindFboOnMakeCurrent() {
56 std::string
GLContext::GetExtensions() {
57 DCHECK(IsCurrent(NULL
));
58 const char* ext
= reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS
));
59 return std::string(ext
? ext
: "");
62 std::string
GLContext::GetGLVersion() {
63 DCHECK(IsCurrent(NULL
));
65 reinterpret_cast<const char*>(glGetString(GL_VERSION
));
66 return std::string(version
? version
: "");
69 bool GLContext::HasExtension(const char* name
) {
70 std::string extensions
= GetExtensions();
73 std::string
delimited_name(name
);
74 delimited_name
+= " ";
76 return extensions
.find(delimited_name
) != std::string::npos
;
79 const GLVersionInfo
* GLContext::GetVersionInfo() {
81 std::string version
= GetGLVersion();
82 version_info_
= scoped_ptr
<GLVersionInfo
>(
83 new GLVersionInfo(version
.c_str()));
85 return version_info_
.get();
88 GLShareGroup
* GLContext::share_group() {
89 return share_group_
.get();
92 bool GLContext::LosesAllContextsOnContextLost() {
93 switch (GetGLImplementation()) {
94 case kGLImplementationDesktopGL
:
96 case kGLImplementationEGLGLES2
:
98 case kGLImplementationOSMesaGL
:
99 case kGLImplementationAppleGL
:
101 case kGLImplementationMockGL
:
109 GLContext
* GLContext::GetCurrent() {
110 return current_context_
.Pointer()->Get();
113 GLContext
* GLContext::GetRealCurrent() {
114 return current_real_context_
.Pointer()->Get();
117 void GLContext::SetCurrent(GLSurface
* surface
) {
118 current_context_
.Pointer()->Set(surface
? this : NULL
);
119 GLSurface::SetCurrent(surface
);
122 GLStateRestorer
* GLContext::GetGLStateRestorer() {
123 return state_restorer_
.get();
126 void GLContext::SetGLStateRestorer(GLStateRestorer
* state_restorer
) {
127 state_restorer_
= make_scoped_ptr(state_restorer
);
130 bool GLContext::WasAllocatedUsingRobustnessExtension() {
134 bool GLContext::InitializeDynamicBindings() {
135 DCHECK(IsCurrent(NULL
));
136 static bool initialized
= false;
139 initialized
= InitializeDynamicGLBindings(GetGLImplementation(), this);
141 LOG(ERROR
) << "Could not initialize dynamic bindings.";
145 void GLContext::SetupForVirtualization() {
146 if (!virtual_gl_api_
) {
147 virtual_gl_api_
.reset(new VirtualGLApi());
148 virtual_gl_api_
->Initialize(&g_driver_gl
, this);
152 bool GLContext::MakeVirtuallyCurrent(
153 GLContext
* virtual_context
, GLSurface
* surface
) {
154 DCHECK(virtual_gl_api_
);
155 return virtual_gl_api_
->MakeCurrent(virtual_context
, surface
);
158 void GLContext::OnReleaseVirtuallyCurrent(GLContext
* virtual_context
) {
160 virtual_gl_api_
->OnReleaseVirtuallyCurrent(virtual_context
);
163 void GLContext::SetRealGLApi() {
167 GLContextReal::GLContextReal(GLShareGroup
* share_group
)
168 : GLContext(share_group
) {}
170 GLContextReal::~GLContextReal() {}
172 void GLContextReal::SetCurrent(GLSurface
* surface
) {
173 GLContext::SetCurrent(surface
);
174 current_real_context_
.Pointer()->Set(surface
? this : NULL
);