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

Side by Side Diff: ui/gfx/gl/gl_context_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_context_egl.h ('k') | ui/gfx/gl/gl_context_linux.cc » ('j') | 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_context_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/gl_surface_egl.h"
12 #include "ui/gfx/gl/egl_util.h"
11 13
12 // This header must come after the above third-party include, as 14 // This header must come after the above third-party include, as
13 // it brings in #defines that cause conflicts. 15 // it brings in #defines that cause conflicts.
14 #include "ui/gfx/gl/gl_bindings.h" 16 #include "ui/gfx/gl/gl_bindings.h"
15 17
16 #if defined(OS_LINUX) 18 #if defined(OS_LINUX)
17 extern "C" { 19 extern "C" {
18 #include <X11/Xlib.h> 20 #include <X11/Xlib.h>
19 } 21 }
20 #define EGL_HAS_PBUFFERS 1 22 #define EGL_HAS_PBUFFERS 1
21 #endif 23 #endif
22 24
23 namespace gfx { 25 namespace gfx {
24 26
25 namespace { 27 std::string GLContextEGL::GetExtensions() {
26 28 const char* extensions = eglQueryString(GLSurfaceEGL::GetDisplay(),
27 // The EGL configuration to use. 29 EGL_EXTENSIONS);
28 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 }
69
70 SharedEGLSurface::~SharedEGLSurface() {
71 if (surface_) {
72 if (!eglDestroySurface(g_display, surface_)) {
73 LOG(ERROR) << "eglDestroySurface failed with error "
74 << GetLastEGLErrorString();
75 }
76 }
77 }
78
79 EGLSurface SharedEGLSurface::egl_surface() const {
80 return surface_;
81 }
82
83 bool BaseEGLContext::InitializeOneOff() {
84 static bool initialized = false;
85 if (initialized)
86 return true;
87
88 #ifdef OS_LINUX
89 EGLNativeDisplayType native_display = XOpenDisplay(NULL);
90 #else
91 EGLNativeDisplayType native_display = EGL_DEFAULT_DISPLAY;
92 #endif
93 g_display = eglGetDisplay(native_display);
94 if (!g_display) {
95 LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString();
96 return false;
97 }
98
99 if (!eglInitialize(g_display, NULL, NULL)) {
100 LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString();
101 return false;
102 }
103
104 // Choose an EGL configuration.
105 static const EGLint kConfigAttribs[] = {
106 EGL_BUFFER_SIZE, 32,
107 EGL_ALPHA_SIZE, 8,
108 EGL_BLUE_SIZE, 8,
109 EGL_RED_SIZE, 8,
110 EGL_DEPTH_SIZE, 16,
111 EGL_STENCIL_SIZE, 8,
112 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
113 #ifdef EGL_HAS_PBUFFERS
114 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
115 #else
116 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
117 #endif
118 EGL_NONE
119 };
120
121 EGLint num_configs;
122 if (!eglChooseConfig(g_display,
123 kConfigAttribs,
124 NULL,
125 0,
126 &num_configs)) {
127 LOG(ERROR) << "eglChooseConfig failed failed with error "
128 << GetLastEGLErrorString();
129 return false;
130 }
131
132 if (num_configs == 0) {
133 LOG(ERROR) << "No suitable EGL configs found.";
134 return false;
135 }
136
137 scoped_array<EGLConfig> configs(new EGLConfig[num_configs]);
138 if (!eglChooseConfig(g_display,
139 kConfigAttribs,
140 configs.get(),
141 num_configs,
142 &num_configs)) {
143 LOG(ERROR) << "eglChooseConfig failed with error "
144 << GetLastEGLErrorString();
145 return false;
146 }
147
148 g_config = configs[0];
149
150 initialized = true;
151 return true;
152 }
153
154 EGLDisplay BaseEGLContext::GetDisplay() {
155 return g_display;
156 }
157
158 std::string BaseEGLContext::GetExtensions() {
159 const char* extensions = eglQueryString(g_display, EGL_EXTENSIONS);
160 if (!extensions) 30 if (!extensions)
161 return GLContext::GetExtensions(); 31 return GLContext::GetExtensions();
162 32
163 return GLContext::GetExtensions() + " " + extensions; 33 return GLContext::GetExtensions() + " " + extensions;
164 } 34 }
165 35
166 NativeViewEGLContext::NativeViewEGLContext(void* window) 36 GLContextEGL::GLContextEGL(GLSurfaceEGL* surface)
167 : window_(window), 37 : surface_(surface),
168 context_(NULL) 38 context_(NULL)
169 { 39 {
170 } 40 }
171 41
172 NativeViewEGLContext::~NativeViewEGLContext() { 42 GLContextEGL::~GLContextEGL() {
173 } 43 }
174 44
175 bool NativeViewEGLContext::Initialize() { 45 bool GLContextEGL::Initialize(GLContext* shared_context) {
176 DCHECK(!context_); 46 DCHECK(!context_);
177 47
178 // Create a surface for the native window.
179 EGLNativeWindowType native_window =
180 reinterpret_cast<EGLNativeWindowType>(window_);
181 surface_ = new SharedEGLSurface(eglCreateWindowSurface(g_display,
182 g_config,
183 native_window,
184 NULL));
185
186 if (!surface_->egl_surface()) {
187 LOG(ERROR) << "eglCreateWindowSurface failed with error "
188 << GetLastEGLErrorString();
189 Destroy();
190 return false;
191 }
192
193 static const EGLint kContextAttributes[] = { 48 static const EGLint kContextAttributes[] = {
194 EGL_CONTEXT_CLIENT_VERSION, 2, 49 EGL_CONTEXT_CLIENT_VERSION, 2,
195 EGL_NONE 50 EGL_NONE
196 }; 51 };
197 52
198 context_ = eglCreateContext(g_display, g_config, NULL, kContextAttributes); 53 context_ = eglCreateContext(
54 GLSurfaceEGL::GetDisplay(),
55 GLSurfaceEGL::GetConfig(),
56 shared_context ? shared_context->GetHandle() : NULL,
57 kContextAttributes);
199 if (!context_) { 58 if (!context_) {
200 LOG(ERROR) << "eglCreateContext failed with error " 59 LOG(ERROR) << "eglCreateContext failed with error "
201 << GetLastEGLErrorString(); 60 << GetLastEGLErrorString();
202 Destroy(); 61 Destroy();
203 return false; 62 return false;
204 } 63 }
205 64
206 if (!MakeCurrent()) { 65 if (!MakeCurrent()) {
207 LOG(ERROR) << "MakeCurrent failed."; 66 LOG(ERROR) << "MakeCurrent failed.";
208 Destroy(); 67 Destroy();
209 return false; 68 return false;
210 } 69 }
211 70
212 if (!InitializeCommon()) { 71 if (!InitializeCommon()) {
213 LOG(ERROR) << "GLContext::InitializeCommon failed."; 72 LOG(ERROR) << "GLContext::InitializeCommon failed.";
214 Destroy(); 73 Destroy();
215 return false; 74 return false;
216 } 75 }
217 76
218 return true; 77 return true;
219 } 78 }
220 79
221 void NativeViewEGLContext::Destroy() { 80 void GLContextEGL::Destroy() {
222 if (context_) { 81 if (context_) {
223 if (!eglDestroyContext(g_display, context_)) { 82 if (!eglDestroyContext(GLSurfaceEGL::GetDisplay(), context_)) {
224 LOG(ERROR) << "eglDestroyContext failed with error " 83 LOG(ERROR) << "eglDestroyContext failed with error "
225 << GetLastEGLErrorString(); 84 << GetLastEGLErrorString();
226 } 85 }
227 86
228 context_ = NULL; 87 context_ = NULL;
229 } 88 }
230
231 surface_ = NULL;
232 } 89 }
233 90
234 bool NativeViewEGLContext::MakeCurrent() { 91 bool GLContextEGL::MakeCurrent() {
235 DCHECK(context_); 92 DCHECK(context_);
236 if (context_ == eglGetCurrentContext()) 93 if (IsCurrent())
237 return true; 94 return true;
238 if (!eglMakeCurrent(g_display, 95
239 surface_->egl_surface(), 96 if (!eglMakeCurrent(GLSurfaceEGL::GetDisplay(),
240 surface_->egl_surface(), 97 surface_->GetHandle(),
98 surface_->GetHandle(),
241 context_)) { 99 context_)) {
242 VLOG(1) << "eglMakeCurrent failed with error " 100 VLOG(1) << "eglMakeCurrent failed with error "
243 << GetLastEGLErrorString(); 101 << GetLastEGLErrorString();
244 return false; 102 return false;
245 } 103 }
246 104
247 return true; 105 return true;
248 } 106 }
249 107
250 bool NativeViewEGLContext::IsCurrent() { 108 bool GLContextEGL::IsCurrent() {
251 DCHECK(context_); 109 DCHECK(context_);
252 return context_ == eglGetCurrentContext(); 110 return context_ == eglGetCurrentContext();
253 } 111 }
254 112
255 bool NativeViewEGLContext::IsOffscreen() { 113 bool GLContextEGL::IsOffscreen() {
256 return false; 114 // TODO(apatrick): remove this from GLContext interface.
115 return surface_->IsOffscreen();
257 } 116 }
258 117
259 bool NativeViewEGLContext::SwapBuffers() { 118 bool GLContextEGL::SwapBuffers() {
260 if (!eglSwapBuffers(g_display, surface_->egl_surface())) { 119 // TODO(apatrick): remove this from GLContext interface.
261 VLOG(1) << "eglSwapBuffers failed with error " 120 return surface_->SwapBuffers();
262 << GetLastEGLErrorString();
263 return false;
264 }
265
266 return true;
267 } 121 }
268 122
269 gfx::Size NativeViewEGLContext::GetSize() { 123 gfx::Size GLContextEGL::GetSize() {
270 #if defined(OS_WIN) 124 // TODO(apatrick): remove this from GLContext interface.
271 RECT rect; 125 return surface_->GetSize();
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;
282 EGLint height;
283 if (!eglQuerySurface(
284 g_display, surface_->egl_surface(), EGL_WIDTH, &width) ||
285 !eglQuerySurface(
286 g_display, surface_->egl_surface(), EGL_HEIGHT, &height)) {
287 NOTREACHED() << "eglQuerySurface failed with error "
288 << GetLastEGLErrorString();
289 return gfx::Size();
290 }
291
292 return gfx::Size(width, height);
293 #endif
294 } 126 }
295 127
296 void* NativeViewEGLContext::GetHandle() { 128 void* GLContextEGL::GetHandle() {
297 return context_; 129 return context_;
298 } 130 }
299 131
300 void NativeViewEGLContext::SetSwapInterval(int interval) { 132 void GLContextEGL::SetSwapInterval(int interval) {
301 DCHECK(IsCurrent()); 133 DCHECK(IsCurrent());
302 if (!eglSwapInterval(g_display, interval)) { 134 if (!eglSwapInterval(GLSurfaceEGL::GetDisplay(), interval)) {
303 LOG(ERROR) << "eglSwapInterval failed with error " 135 LOG(ERROR) << "eglSwapInterval failed with error "
304 << GetLastEGLErrorString(); 136 << GetLastEGLErrorString();
305 } 137 }
306 } 138 }
307 139
308 SharedEGLSurface* NativeViewEGLContext::GetSurface() {
309 return surface_;
310 }
311
312 SecondaryEGLContext::SecondaryEGLContext()
313 : context_(NULL)
314 {
315 }
316
317 SecondaryEGLContext::~SecondaryEGLContext() {
318 }
319
320 bool SecondaryEGLContext::Initialize(GLContext* shared_context) {
321 DCHECK(!context_);
322
323 static const EGLint kContextAttributes[] = {
324 EGL_CONTEXT_CLIENT_VERSION, 2,
325 EGL_NONE
326 };
327
328 if (shared_context) {
329 surface_ = static_cast<BaseEGLContext*>(shared_context)->GetSurface();
330
331 // Create a context.
332 context_ = eglCreateContext(g_display,
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();
364 Destroy();
365 return false;
366 }
367
368 return true;
369 }
370
371 void SecondaryEGLContext::Destroy() {
372 if (context_) {
373 if (!eglDestroyContext(g_display, context_)) {
374 LOG(ERROR) << "eglDestroyContext failed with error "
375 << GetLastEGLErrorString();
376 }
377
378 context_ = NULL;
379 }
380
381 surface_ = NULL;
382 }
383
384 bool SecondaryEGLContext::MakeCurrent() {
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;
398 }
399
400 bool SecondaryEGLContext::IsCurrent() {
401 DCHECK(context_);
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;
412 }
413
414 gfx::Size SecondaryEGLContext::GetSize() {
415 NOTREACHED() << "Should not be requesting size of this SecondaryEGLContext.";
416 return gfx::Size(1, 1);
417 }
418
419 void* SecondaryEGLContext::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_;
430 }
431
432 } // namespace gfx 140 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/gl/gl_context_egl.h ('k') | ui/gfx/gl/gl_context_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698