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 "ui/gl/gl_surface.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "base/command_line.h"
11 #include "base/debug/trace_event.h"
12 #include "base/lazy_instance.h"
13 #include "base/logging.h"
14 #include "base/threading/thread_local.h"
15 #include "ui/gl/gl_context.h"
16 #include "ui/gl/gl_implementation.h"
17
18 namespace gfx {
19
20 namespace {
21 base::LazyInstance<base::ThreadLocalPointer<GLSurface> >::Leaky
22 current_surface_ = LAZY_INSTANCE_INITIALIZER;
23 } // namespace
24
25 // static
InitializeOneOff()26 bool GLSurface::InitializeOneOff() {
27 static bool initialized = false;
28 if (initialized)
29 return true;
30
31 TRACE_EVENT0("gpu", "GLSurface::InitializeOneOff");
32
33 std::vector<GLImplementation> allowed_impls;
34 GetAllowedGLImplementations(&allowed_impls);
35 DCHECK(!allowed_impls.empty());
36
37 // The default implementation is always the first one in list.
38 GLImplementation impl = allowed_impls[0];
39 bool fallback_to_osmesa = false;
40 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL)) {
41 std::string requested_implementation_name =
42 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL);
43 if (requested_implementation_name == "any") {
44 fallback_to_osmesa = true;
45 } else if (requested_implementation_name == "swiftshader") {
46 impl = kGLImplementationEGLGLES2;
47 } else {
48 impl = GetNamedGLImplementation(requested_implementation_name);
49 if (std::find(allowed_impls.begin(),
50 allowed_impls.end(),
51 impl) == allowed_impls.end()) {
52 LOG(ERROR) << "Requested GL implementation is not available.";
53 return false;
54 }
55 }
56 }
57
58 initialized = InitializeGLBindings(impl) && InitializeOneOffInternal();
59 if (!initialized && fallback_to_osmesa) {
60 ClearGLBindings();
61 initialized = InitializeGLBindings(kGLImplementationOSMesaGL) &&
62 InitializeOneOffInternal();
63 }
64
65 if (initialized) {
66 DVLOG(1) << "Using "
67 << GetGLImplementationName(GetGLImplementation())
68 << " GL implementation.";
69 if (CommandLine::ForCurrentProcess()->HasSwitch(
70 switches::kEnableGPUServiceLogging))
71 InitializeDebugGLBindings();
72 }
73 return initialized;
74 }
75
GLSurface()76 GLSurface::GLSurface() {}
77
Initialize()78 bool GLSurface::Initialize() {
79 return true;
80 }
81
Resize(const gfx::Size & size)82 bool GLSurface::Resize(const gfx::Size& size) {
83 NOTIMPLEMENTED();
84 return false;
85 }
86
Recreate()87 bool GLSurface::Recreate() {
88 NOTIMPLEMENTED();
89 return false;
90 }
91
DeferDraws()92 bool GLSurface::DeferDraws() {
93 return false;
94 }
95
GetExtensions()96 std::string GLSurface::GetExtensions() {
97 return std::string();
98 }
99
HasExtension(const char * name)100 bool GLSurface::HasExtension(const char* name) {
101 std::string extensions = GetExtensions();
102 extensions += " ";
103
104 std::string delimited_name(name);
105 delimited_name += " ";
106
107 return extensions.find(delimited_name) != std::string::npos;
108 }
109
GetBackingFrameBufferObject()110 unsigned int GLSurface::GetBackingFrameBufferObject() {
111 return 0;
112 }
113
PostSubBuffer(int x,int y,int width,int height)114 bool GLSurface::PostSubBuffer(int x, int y, int width, int height) {
115 return false;
116 }
117
OnMakeCurrent(GLContext * context)118 bool GLSurface::OnMakeCurrent(GLContext* context) {
119 return true;
120 }
121
SetBackbufferAllocation(bool allocated)122 bool GLSurface::SetBackbufferAllocation(bool allocated) {
123 return true;
124 }
125
SetFrontbufferAllocation(bool allocated)126 void GLSurface::SetFrontbufferAllocation(bool allocated) {
127 }
128
GetShareHandle()129 void* GLSurface::GetShareHandle() {
130 NOTIMPLEMENTED();
131 return NULL;
132 }
133
GetDisplay()134 void* GLSurface::GetDisplay() {
135 NOTIMPLEMENTED();
136 return NULL;
137 }
138
GetConfig()139 void* GLSurface::GetConfig() {
140 NOTIMPLEMENTED();
141 return NULL;
142 }
143
GetFormat()144 unsigned GLSurface::GetFormat() {
145 NOTIMPLEMENTED();
146 return 0;
147 }
148
GetVSyncProvider()149 VSyncProvider* GLSurface::GetVSyncProvider() {
150 return NULL;
151 }
152
GetCurrent()153 GLSurface* GLSurface::GetCurrent() {
154 return current_surface_.Pointer()->Get();
155 }
156
~GLSurface()157 GLSurface::~GLSurface() {
158 if (GetCurrent() == this)
159 SetCurrent(NULL);
160 }
161
SetCurrent(GLSurface * surface)162 void GLSurface::SetCurrent(GLSurface* surface) {
163 current_surface_.Pointer()->Set(surface);
164 }
165
ExtensionsContain(const char * c_extensions,const char * name)166 bool GLSurface::ExtensionsContain(const char* c_extensions, const char* name) {
167 DCHECK(name);
168 if (!c_extensions)
169 return false;
170 std::string extensions(c_extensions);
171 extensions += " ";
172
173 std::string delimited_name(name);
174 delimited_name += " ";
175
176 return extensions.find(delimited_name) != std::string::npos;
177 }
178
GLSurfaceAdapter(GLSurface * surface)179 GLSurfaceAdapter::GLSurfaceAdapter(GLSurface* surface) : surface_(surface) {}
180
Initialize()181 bool GLSurfaceAdapter::Initialize() {
182 return surface_->Initialize();
183 }
184
Destroy()185 void GLSurfaceAdapter::Destroy() {
186 surface_->Destroy();
187 }
188
Resize(const gfx::Size & size)189 bool GLSurfaceAdapter::Resize(const gfx::Size& size) {
190 return surface_->Resize(size);
191 }
192
Recreate()193 bool GLSurfaceAdapter::Recreate() {
194 return surface_->Recreate();
195 }
196
DeferDraws()197 bool GLSurfaceAdapter::DeferDraws() {
198 return surface_->DeferDraws();
199 }
200
IsOffscreen()201 bool GLSurfaceAdapter::IsOffscreen() {
202 return surface_->IsOffscreen();
203 }
204
SwapBuffers()205 bool GLSurfaceAdapter::SwapBuffers() {
206 return surface_->SwapBuffers();
207 }
208
PostSubBuffer(int x,int y,int width,int height)209 bool GLSurfaceAdapter::PostSubBuffer(int x, int y, int width, int height) {
210 return surface_->PostSubBuffer(x, y, width, height);
211 }
212
GetExtensions()213 std::string GLSurfaceAdapter::GetExtensions() {
214 return surface_->GetExtensions();
215 }
216
GetSize()217 gfx::Size GLSurfaceAdapter::GetSize() {
218 return surface_->GetSize();
219 }
220
GetHandle()221 void* GLSurfaceAdapter::GetHandle() {
222 return surface_->GetHandle();
223 }
224
GetBackingFrameBufferObject()225 unsigned int GLSurfaceAdapter::GetBackingFrameBufferObject() {
226 return surface_->GetBackingFrameBufferObject();
227 }
228
OnMakeCurrent(GLContext * context)229 bool GLSurfaceAdapter::OnMakeCurrent(GLContext* context) {
230 return surface_->OnMakeCurrent(context);
231 }
232
SetBackbufferAllocation(bool allocated)233 bool GLSurfaceAdapter::SetBackbufferAllocation(bool allocated) {
234 return surface_->SetBackbufferAllocation(allocated);
235 }
236
SetFrontbufferAllocation(bool allocated)237 void GLSurfaceAdapter::SetFrontbufferAllocation(bool allocated) {
238 surface_->SetFrontbufferAllocation(allocated);
239 }
240
GetShareHandle()241 void* GLSurfaceAdapter::GetShareHandle() {
242 return surface_->GetShareHandle();
243 }
244
GetDisplay()245 void* GLSurfaceAdapter::GetDisplay() {
246 return surface_->GetDisplay();
247 }
248
GetConfig()249 void* GLSurfaceAdapter::GetConfig() {
250 return surface_->GetConfig();
251 }
252
GetFormat()253 unsigned GLSurfaceAdapter::GetFormat() {
254 return surface_->GetFormat();
255 }
256
GetVSyncProvider()257 VSyncProvider* GLSurfaceAdapter::GetVSyncProvider() {
258 return surface_->GetVSyncProvider();
259 }
260
~GLSurfaceAdapter()261 GLSurfaceAdapter::~GLSurfaceAdapter() {}
262
263 } // namespace gfx
264