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

Side by Side Diff: ui/gfx/gl/egl_util.h

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 | « content/gpu/gpu_info_collector_win.cc ('k') | ui/gfx/gl/egl_util.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 5 #ifndef UI_GFX_GL_EGL_UTIL_H_
6 #include "build/build_config.h" 6 #define UI_GFX_GL_EGL_UTIL_H_
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "third_party/angle/include/EGL/egl.h"
10 #include "ui/gfx/gl/gl_context_egl.h"
11
12 // This header must come after the above third-party include, as
13 // it brings in #defines that cause conflicts.
14 #include "ui/gfx/gl/gl_bindings.h"
15
16 #if defined(OS_LINUX)
17 extern "C" {
18 #include <X11/Xlib.h>
19 }
20 #define EGL_HAS_PBUFFERS 1
21 #endif
22 7
23 namespace gfx { 8 namespace gfx {
24 9
25 namespace {
26
27 // The EGL configuration to use.
28 EGLDisplay g_display;
29 EGLConfig g_config;
30
31 // Returns the last EGL error as a string. 10 // Returns the last EGL error as a string.
32 const char* GetLastEGLErrorString() { 11 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)
161 return GLContext::GetExtensions();
162
163 return GLContext::GetExtensions() + " " + extensions;
164 }
165
166 NativeViewEGLContext::NativeViewEGLContext(void* window)
167 : window_(window),
168 context_(NULL)
169 {
170 }
171
172 NativeViewEGLContext::~NativeViewEGLContext() {
173 }
174
175 bool NativeViewEGLContext::Initialize() {
176 DCHECK(!context_);
177
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[] = {
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;
219 }
220
221 void NativeViewEGLContext::Destroy() {
222 if (context_) {
223 if (!eglDestroyContext(g_display, context_)) {
224 LOG(ERROR) << "eglDestroyContext failed with error "
225 << GetLastEGLErrorString();
226 }
227
228 context_ = NULL;
229 }
230
231 surface_ = NULL;
232 }
233
234 bool NativeViewEGLContext::MakeCurrent() {
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;
257 }
258
259 bool NativeViewEGLContext::SwapBuffers() {
260 if (!eglSwapBuffers(g_display, surface_->egl_surface())) {
261 VLOG(1) << "eglSwapBuffers failed with error "
262 << GetLastEGLErrorString();
263 return false;
264 }
265
266 return true;
267 }
268
269 gfx::Size NativeViewEGLContext::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;
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 }
295
296 void* NativeViewEGLContext::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_;
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 12
432 } // namespace gfx 13 } // namespace gfx
14
15 #endif // UI_GFX_GL_EGL_UTIL_H_
OLDNEW
« no previous file with comments | « content/gpu/gpu_info_collector_win.cc ('k') | ui/gfx/gl/egl_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698