Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: ui/gfx/gl/gl_surface_egl.cc

Issue 6839008: Split EGLContext in GLContextEGL and GLSurfaceEGL. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/gfx/gl/gl_surface_egl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/gl/gl_surface_egl.h"
5 6
6 #include "build/build_config.h" 7 #include "build/build_config.h"
7 #include "base/logging.h" 8 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
9 #include "third_party/angle/include/EGL/egl.h" 10 #include "third_party/angle/include/EGL/egl.h"
10 #include "ui/gfx/gl/gl_context_egl.h" 11 #include "ui/gfx/gl/egl_util.h"
11 12
12 // This header must come after the above third-party include, as 13 // This header must come after the above third-party include, as
13 // it brings in #defines that cause conflicts. 14 // it brings in #defines that cause conflicts.
14 #include "ui/gfx/gl/gl_bindings.h" 15 #include "ui/gfx/gl/gl_bindings.h"
15 16
16 #if defined(OS_LINUX) 17 #if defined(OS_LINUX)
17 extern "C" { 18 extern "C" {
18 #include <X11/Xlib.h> 19 #include <X11/Xlib.h>
19 } 20 }
20 #define EGL_HAS_PBUFFERS 1
21 #endif 21 #endif
22 22
23 namespace gfx { 23 namespace gfx {
24 24
25 namespace { 25 namespace {
26 26 EGLConfig g_config;
27 // The EGL configuration to use.
28 EGLDisplay g_display; 27 EGLDisplay g_display;
29 EGLConfig g_config;
30
31 // Returns the last EGL error as a string.
32 const char* GetLastEGLErrorString() {
33 EGLint error = eglGetError();
34 switch (error) {
35 case EGL_SUCCESS:
36 return "EGL_SUCCESS";
37 case EGL_BAD_ACCESS:
38 return "EGL_BAD_ACCESS";
39 case EGL_BAD_ALLOC:
40 return "EGL_BAD_ALLOC";
41 case EGL_BAD_ATTRIBUTE:
42 return "EGL_BAD_ATTRIBUTE";
43 case EGL_BAD_CONTEXT:
44 return "EGL_BAD_CONTEXT";
45 case EGL_BAD_CONFIG:
46 return "EGL_BAD_CONFIG";
47 case EGL_BAD_CURRENT_SURFACE:
48 return "EGL_BAD_CURRENT_SURFACE";
49 case EGL_BAD_DISPLAY:
50 return "EGL_BAD_DISPLAY";
51 case EGL_BAD_SURFACE:
52 return "EGL_BAD_SURFACE";
53 case EGL_BAD_MATCH:
54 return "EGL_BAD_MATCH";
55 case EGL_BAD_PARAMETER:
56 return "EGL_BAD_PARAMETER";
57 case EGL_BAD_NATIVE_PIXMAP:
58 return "EGL_BAD_NATIVE_PIXMAP";
59 case EGL_BAD_NATIVE_WINDOW:
60 return "EGL_BAD_NATIVE_WINDOW";
61 default:
62 return "UNKNOWN";
63 }
64 }
65 } // namespace anonymous
66
67 SharedEGLSurface::SharedEGLSurface(EGLSurface surface) : surface_(surface) {
68 } 28 }
69 29
70 SharedEGLSurface::~SharedEGLSurface() { 30 GLSurfaceEGL::GLSurfaceEGL() {
71 if (surface_) {
72 if (!eglDestroySurface(g_display, surface_)) {
73 LOG(ERROR) << "eglDestroySurface failed with error "
74 << GetLastEGLErrorString();
75 }
76 }
77 } 31 }
78 32
79 EGLSurface SharedEGLSurface::egl_surface() const { 33 GLSurfaceEGL::~GLSurfaceEGL() {
80 return surface_;
81 } 34 }
82 35
83 bool BaseEGLContext::InitializeOneOff() { 36 bool GLSurfaceEGL::InitializeOneOff() {
84 static bool initialized = false; 37 static bool initialized = false;
85 if (initialized) 38 if (initialized)
86 return true; 39 return true;
87 40
88 #ifdef OS_LINUX 41 #ifdef OS_LINUX
89 EGLNativeDisplayType native_display = XOpenDisplay(NULL); 42 EGLNativeDisplayType native_display = XOpenDisplay(NULL);
90 #else 43 #else
91 EGLNativeDisplayType native_display = EGL_DEFAULT_DISPLAY; 44 EGLNativeDisplayType native_display = EGL_DEFAULT_DISPLAY;
92 #endif 45 #endif
93 g_display = eglGetDisplay(native_display); 46 g_display = eglGetDisplay(native_display);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 << GetLastEGLErrorString(); 97 << GetLastEGLErrorString();
145 return false; 98 return false;
146 } 99 }
147 100
148 g_config = configs[0]; 101 g_config = configs[0];
149 102
150 initialized = true; 103 initialized = true;
151 return true; 104 return true;
152 } 105 }
153 106
154 EGLDisplay BaseEGLContext::GetDisplay() { 107 EGLDisplay GLSurfaceEGL::GetDisplay() {
155 return g_display; 108 return g_display;
156 } 109 }
157 110
158 std::string BaseEGLContext::GetExtensions() { 111 EGLConfig GLSurfaceEGL::GetConfig() {
159 const char* extensions = eglQueryString(g_display, EGL_EXTENSIONS); 112 return g_config;
160 if (!extensions)
161 return GLContext::GetExtensions();
162
163 return GLContext::GetExtensions() + " " + extensions;
164 } 113 }
165 114
166 NativeViewEGLContext::NativeViewEGLContext(void* window) 115 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(void* window)
167 : window_(window), 116 : window_(window),
168 context_(NULL) 117 surface_(NULL)
169 { 118 {
170 } 119 }
171 120
172 NativeViewEGLContext::~NativeViewEGLContext() { 121 NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() {
122 Destroy();
173 } 123 }
174 124
175 bool NativeViewEGLContext::Initialize() { 125 bool NativeViewGLSurfaceEGL::Initialize() {
176 DCHECK(!context_); 126 DCHECK(!surface_);
177 127
178 // Create a surface for the native window. 128 // Create a surface for the native window.
179 EGLNativeWindowType native_window = 129 EGLNativeWindowType native_window =
180 reinterpret_cast<EGLNativeWindowType>(window_); 130 reinterpret_cast<EGLNativeWindowType>(window_);
181 surface_ = new SharedEGLSurface(eglCreateWindowSurface(g_display, 131 surface_ = eglCreateWindowSurface(g_display,
182 g_config, 132 g_config,
183 native_window, 133 native_window,
184 NULL)); 134 NULL);
185 135
186 if (!surface_->egl_surface()) { 136 if (!surface_) {
187 LOG(ERROR) << "eglCreateWindowSurface failed with error " 137 LOG(ERROR) << "eglCreateWindowSurface failed with error "
188 << GetLastEGLErrorString(); 138 << GetLastEGLErrorString();
189 Destroy(); 139 Destroy();
190 return false; 140 return false;
191 } 141 }
192 142
193 static const EGLint kContextAttributes[] = {
194 EGL_CONTEXT_CLIENT_VERSION, 2,
195 EGL_NONE
196 };
197
198 context_ = eglCreateContext(g_display, g_config, NULL, kContextAttributes);
199 if (!context_) {
200 LOG(ERROR) << "eglCreateContext failed with error "
201 << GetLastEGLErrorString();
202 Destroy();
203 return false;
204 }
205
206 if (!MakeCurrent()) {
207 LOG(ERROR) << "MakeCurrent failed.";
208 Destroy();
209 return false;
210 }
211
212 if (!InitializeCommon()) {
213 LOG(ERROR) << "GLContext::InitializeCommon failed.";
214 Destroy();
215 return false;
216 }
217
218 return true; 143 return true;
219 } 144 }
220 145
221 void NativeViewEGLContext::Destroy() { 146 void NativeViewGLSurfaceEGL::Destroy() {
222 if (context_) { 147 if (surface_) {
223 if (!eglDestroyContext(g_display, context_)) { 148 if (!eglDestroySurface(g_display, surface_)) {
224 LOG(ERROR) << "eglDestroyContext failed with error " 149 LOG(ERROR) << "eglDestroySurface failed with error "
225 << GetLastEGLErrorString(); 150 << GetLastEGLErrorString();
226 } 151 }
227 152 surface_ = NULL;
228 context_ = NULL;
229 } 153 }
230
231 surface_ = NULL;
232 } 154 }
233 155
234 bool NativeViewEGLContext::MakeCurrent() { 156 bool NativeViewGLSurfaceEGL::IsOffscreen() {
235 DCHECK(context_);
236 if (context_ == eglGetCurrentContext())
237 return true;
238 if (!eglMakeCurrent(g_display,
239 surface_->egl_surface(),
240 surface_->egl_surface(),
241 context_)) {
242 VLOG(1) << "eglMakeCurrent failed with error "
243 << GetLastEGLErrorString();
244 return false;
245 }
246
247 return true;
248 }
249
250 bool NativeViewEGLContext::IsCurrent() {
251 DCHECK(context_);
252 return context_ == eglGetCurrentContext();
253 }
254
255 bool NativeViewEGLContext::IsOffscreen() {
256 return false; 157 return false;
257 } 158 }
258 159
259 bool NativeViewEGLContext::SwapBuffers() { 160 bool NativeViewGLSurfaceEGL::SwapBuffers() {
260 if (!eglSwapBuffers(g_display, surface_->egl_surface())) { 161 if (!eglSwapBuffers(g_display, surface_)) {
261 VLOG(1) << "eglSwapBuffers failed with error " 162 VLOG(1) << "eglSwapBuffers failed with error "
262 << GetLastEGLErrorString(); 163 << GetLastEGLErrorString();
263 return false; 164 return false;
264 } 165 }
265 166
266 return true; 167 return true;
267 } 168 }
268 169
269 gfx::Size NativeViewEGLContext::GetSize() { 170 gfx::Size NativeViewGLSurfaceEGL::GetSize() {
270 #if defined(OS_WIN)
271 RECT rect;
272 if (!GetClientRect(static_cast<HWND>(window_), &rect)) {
273 DCHECK(false) << "GetClientRect failed.";
274 return gfx::Size();
275 }
276
277 return gfx::Size(rect.right - rect.left, rect.bottom - rect.top);
278 #else
279 // TODO(piman): This doesn't work correctly on Windows yet, the size doesn't
280 // get updated on resize. When it does, we can share the code.
281 EGLint width; 171 EGLint width;
282 EGLint height; 172 EGLint height;
283 if (!eglQuerySurface( 173 if (!eglQuerySurface(g_display, surface_, EGL_WIDTH, &width) ||
284 g_display, surface_->egl_surface(), EGL_WIDTH, &width) || 174 !eglQuerySurface(g_display, surface_, EGL_HEIGHT, &height)) {
285 !eglQuerySurface(
286 g_display, surface_->egl_surface(), EGL_HEIGHT, &height)) {
287 NOTREACHED() << "eglQuerySurface failed with error " 175 NOTREACHED() << "eglQuerySurface failed with error "
288 << GetLastEGLErrorString(); 176 << GetLastEGLErrorString();
289 return gfx::Size(); 177 return gfx::Size();
290 } 178 }
291 179
292 return gfx::Size(width, height); 180 return gfx::Size(width, height);
293 #endif
294 } 181 }
295 182
296 void* NativeViewEGLContext::GetHandle() { 183 EGLSurface NativeViewGLSurfaceEGL::GetHandle() {
297 return context_;
298 }
299
300 void NativeViewEGLContext::SetSwapInterval(int interval) {
301 DCHECK(IsCurrent());
302 if (!eglSwapInterval(g_display, interval)) {
303 LOG(ERROR) << "eglSwapInterval failed with error "
304 << GetLastEGLErrorString();
305 }
306 }
307
308 SharedEGLSurface* NativeViewEGLContext::GetSurface() {
309 return surface_; 184 return surface_;
310 } 185 }
311 186
312 SecondaryEGLContext::SecondaryEGLContext() 187 PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size)
313 : context_(NULL) 188 : size_(size),
314 { 189 surface_(NULL) {
315 } 190 }
316 191
317 SecondaryEGLContext::~SecondaryEGLContext() { 192 PbufferGLSurfaceEGL::~PbufferGLSurfaceEGL() {
193 Destroy();
318 } 194 }
319 195
320 bool SecondaryEGLContext::Initialize(GLContext* shared_context) { 196 bool PbufferGLSurfaceEGL::Initialize() {
321 DCHECK(!context_); 197 DCHECK(!surface_);
322 198
323 static const EGLint kContextAttributes[] = { 199 const EGLint pbuffer_attribs[] = {
324 EGL_CONTEXT_CLIENT_VERSION, 2, 200 EGL_WIDTH, size_.width(),
201 EGL_HEIGHT, size_.height(),
325 EGL_NONE 202 EGL_NONE
326 }; 203 };
327 204
328 if (shared_context) { 205 surface_ = eglCreatePbufferSurface(g_display,
329 surface_ = static_cast<BaseEGLContext*>(shared_context)->GetSurface(); 206 g_config,
330 207 pbuffer_attribs);
331 // Create a context. 208 if (!surface_) {
332 context_ = eglCreateContext(g_display, 209 LOG(ERROR) << "eglCreatePbufferSurface failed with error "
333 g_config,
334 shared_context->GetHandle(),
335 kContextAttributes);
336 } else {
337 #ifdef EGL_HAS_PBUFFERS
338 static const EGLint kPbufferAttribs[] = {
339 EGL_WIDTH, 1,
340 EGL_HEIGHT, 1,
341 EGL_NONE
342 };
343
344 surface_ = new SharedEGLSurface(eglCreatePbufferSurface(g_display,
345 g_config,
346 kPbufferAttribs));
347 if (!surface_->egl_surface()) {
348 LOG(ERROR) << "eglCreatePbufferSurface failed with error "
349 << GetLastEGLErrorString();
350 Destroy();
351 return false;
352 }
353
354 context_ = eglCreateContext(g_display, g_config, NULL, kContextAttributes);
355 #else
356 NOTIMPLEMENTED() << "Offscreen non-shared GLES context";
357 return false;
358 #endif
359 }
360
361 if (!context_) {
362 LOG(ERROR) << "eglCreateContext failed with error "
363 << GetLastEGLErrorString(); 210 << GetLastEGLErrorString();
364 Destroy(); 211 Destroy();
365 return false; 212 return false;
366 } 213 }
367 214
368 return true; 215 return true;
369 } 216 }
370 217
371 void SecondaryEGLContext::Destroy() { 218 void PbufferGLSurfaceEGL::Destroy() {
372 if (context_) { 219 if (surface_) {
373 if (!eglDestroyContext(g_display, context_)) { 220 if (!eglDestroySurface(g_display, surface_)) {
374 LOG(ERROR) << "eglDestroyContext failed with error " 221 LOG(ERROR) << "eglDestroySurface failed with error "
375 << GetLastEGLErrorString(); 222 << GetLastEGLErrorString();
376 } 223 }
377 224 surface_ = NULL;
378 context_ = NULL;
379 } 225 }
380
381 surface_ = NULL;
382 } 226 }
383 227
384 bool SecondaryEGLContext::MakeCurrent() { 228 bool PbufferGLSurfaceEGL::IsOffscreen() {
385 DCHECK(context_);
386 if (context_ == eglGetCurrentContext())
387 return true;
388 if (!eglMakeCurrent(g_display,
389 surface_->egl_surface(),
390 surface_->egl_surface(),
391 context_)) {
392 VLOG(1) << "eglMakeCurrent failed with error "
393 << GetLastEGLErrorString();
394 return false;
395 }
396
397 return true; 229 return true;
398 } 230 }
399 231
400 bool SecondaryEGLContext::IsCurrent() { 232 bool PbufferGLSurfaceEGL::SwapBuffers() {
401 DCHECK(context_); 233 NOTREACHED() << "Attempted to call SwapBuffers on a PbufferGLSurfaceEGL.";
402 return context_ == eglGetCurrentContext();
403 }
404
405 bool SecondaryEGLContext::IsOffscreen() {
406 return true;
407 }
408
409 bool SecondaryEGLContext::SwapBuffers() {
410 NOTREACHED() << "Attempted to call SwapBuffers on a SecondaryEGLContext.";
411 return false; 234 return false;
412 } 235 }
413 236
414 gfx::Size SecondaryEGLContext::GetSize() { 237 gfx::Size PbufferGLSurfaceEGL::GetSize() {
415 NOTREACHED() << "Should not be requesting size of this SecondaryEGLContext."; 238 return size_;
416 return gfx::Size(1, 1);
417 } 239 }
418 240
419 void* SecondaryEGLContext::GetHandle() { 241 EGLSurface PbufferGLSurfaceEGL::GetHandle() {
420 return context_;
421 }
422
423 void SecondaryEGLContext::SetSwapInterval(int interval) {
424 DCHECK(IsCurrent());
425 NOTREACHED() << "Attempt to call SetSwapInterval on a SecondaryEGLContext.";
426 }
427
428 SharedEGLSurface* SecondaryEGLContext::GetSurface() {
429 return surface_; 242 return surface_;
430 } 243 }
431 244
432 } // namespace gfx 245 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/gl/gl_surface_egl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698