OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <EGL/egl.h> | 5 #include <EGL/egl.h> |
6 | 6 |
7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
8 #if defined(OS_LINUX) | 8 #if defined(OS_LINUX) |
9 #include "app/x11_util.h" | 9 #include "app/x11_util.h" |
10 #define EGL_HAS_PBUFFERS 1 | 10 #define EGL_HAS_PBUFFERS 1 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 case EGL_BAD_NATIVE_PIXMAP: | 51 case EGL_BAD_NATIVE_PIXMAP: |
52 return "EGL_BAD_NATIVE_PIXMAP"; | 52 return "EGL_BAD_NATIVE_PIXMAP"; |
53 case EGL_BAD_NATIVE_WINDOW: | 53 case EGL_BAD_NATIVE_WINDOW: |
54 return "EGL_BAD_NATIVE_WINDOW"; | 54 return "EGL_BAD_NATIVE_WINDOW"; |
55 default: | 55 default: |
56 return "UNKNOWN"; | 56 return "UNKNOWN"; |
57 } | 57 } |
58 } | 58 } |
59 } // namespace anonymous | 59 } // namespace anonymous |
60 | 60 |
| 61 SharedEGLSurface::SharedEGLSurface(EGLSurface surface) : surface_(surface) { |
| 62 } |
| 63 |
| 64 SharedEGLSurface::~SharedEGLSurface() { |
| 65 if (surface_) { |
| 66 if (!eglDestroySurface(g_display, surface_)) { |
| 67 LOG(ERROR) << "eglDestroySurface failed with error " |
| 68 << GetLastEGLErrorString(); |
| 69 } |
| 70 } |
| 71 } |
| 72 |
| 73 EGLSurface SharedEGLSurface::egl_surface() const { |
| 74 return surface_; |
| 75 } |
| 76 |
61 bool BaseEGLContext::InitializeOneOff() { | 77 bool BaseEGLContext::InitializeOneOff() { |
62 static bool initialized = false; | 78 static bool initialized = false; |
63 if (initialized) | 79 if (initialized) |
64 return true; | 80 return true; |
65 | 81 |
66 #ifdef OS_LINUX | 82 #ifdef OS_LINUX |
67 EGLNativeDisplayType native_display = x11_util::GetXDisplay(); | 83 EGLNativeDisplayType native_display = x11_util::GetXDisplay(); |
68 #else | 84 #else |
69 EGLNativeDisplayType native_display = EGL_DEFAULT_DISPLAY; | 85 EGLNativeDisplayType native_display = EGL_DEFAULT_DISPLAY; |
70 #endif | 86 #endif |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 std::string BaseEGLContext::GetExtensions() { | 152 std::string BaseEGLContext::GetExtensions() { |
137 const char* extensions = eglQueryString(g_display, EGL_EXTENSIONS); | 153 const char* extensions = eglQueryString(g_display, EGL_EXTENSIONS); |
138 if (!extensions) | 154 if (!extensions) |
139 return GLContext::GetExtensions(); | 155 return GLContext::GetExtensions(); |
140 | 156 |
141 return GLContext::GetExtensions() + " " + extensions; | 157 return GLContext::GetExtensions() + " " + extensions; |
142 } | 158 } |
143 | 159 |
144 NativeViewEGLContext::NativeViewEGLContext(void* window) | 160 NativeViewEGLContext::NativeViewEGLContext(void* window) |
145 : window_(window), | 161 : window_(window), |
146 surface_(NULL), | |
147 context_(NULL) | 162 context_(NULL) |
148 { | 163 { |
149 } | 164 } |
150 | 165 |
151 NativeViewEGLContext::~NativeViewEGLContext() { | 166 NativeViewEGLContext::~NativeViewEGLContext() { |
152 } | 167 } |
153 | 168 |
154 bool NativeViewEGLContext::Initialize() { | 169 bool NativeViewEGLContext::Initialize() { |
155 DCHECK(!context_); | 170 DCHECK(!context_); |
156 | 171 |
157 // Create a surface for the native window. | 172 // Create a surface for the native window. |
158 EGLNativeWindowType native_window = | 173 EGLNativeWindowType native_window = |
159 reinterpret_cast<EGLNativeWindowType>(window_); | 174 reinterpret_cast<EGLNativeWindowType>(window_); |
160 surface_ = eglCreateWindowSurface(g_display, g_config, native_window, NULL); | 175 surface_ = new SharedEGLSurface(eglCreateWindowSurface(g_display, |
| 176 g_config, |
| 177 native_window, |
| 178 NULL)); |
161 | 179 |
162 if (!surface_) { | 180 if (!surface_->egl_surface()) { |
163 LOG(ERROR) << "eglCreateWindowSurface failed with error " | 181 LOG(ERROR) << "eglCreateWindowSurface failed with error " |
164 << GetLastEGLErrorString(); | 182 << GetLastEGLErrorString(); |
165 Destroy(); | 183 Destroy(); |
166 return false; | 184 return false; |
167 } | 185 } |
168 | 186 |
169 static const EGLint kContextAttributes[] = { | 187 static const EGLint kContextAttributes[] = { |
170 EGL_CONTEXT_CLIENT_VERSION, 2, | 188 EGL_CONTEXT_CLIENT_VERSION, 2, |
171 EGL_NONE | 189 EGL_NONE |
172 }; | 190 }; |
(...skipping 24 matching lines...) Expand all Loading... |
197 void NativeViewEGLContext::Destroy() { | 215 void NativeViewEGLContext::Destroy() { |
198 if (context_) { | 216 if (context_) { |
199 if (!eglDestroyContext(g_display, context_)) { | 217 if (!eglDestroyContext(g_display, context_)) { |
200 LOG(ERROR) << "eglDestroyContext failed with error " | 218 LOG(ERROR) << "eglDestroyContext failed with error " |
201 << GetLastEGLErrorString(); | 219 << GetLastEGLErrorString(); |
202 } | 220 } |
203 | 221 |
204 context_ = NULL; | 222 context_ = NULL; |
205 } | 223 } |
206 | 224 |
207 if (surface_) { | 225 surface_ = NULL; |
208 if (!eglDestroySurface(g_display, surface_)) { | |
209 LOG(ERROR) << "eglDestroySurface failed with error " | |
210 << GetLastEGLErrorString(); | |
211 } | |
212 | |
213 surface_ = NULL; | |
214 } | |
215 } | 226 } |
216 | 227 |
217 bool NativeViewEGLContext::MakeCurrent() { | 228 bool NativeViewEGLContext::MakeCurrent() { |
218 DCHECK(context_); | 229 DCHECK(context_); |
219 if (!eglMakeCurrent(g_display, | 230 if (!eglMakeCurrent(g_display, |
220 surface_, surface_, | 231 surface_->egl_surface(), |
| 232 surface_->egl_surface(), |
221 context_)) { | 233 context_)) { |
222 VLOG(1) << "eglMakeCurrent failed with error " | 234 VLOG(1) << "eglMakeCurrent failed with error " |
223 << GetLastEGLErrorString(); | 235 << GetLastEGLErrorString(); |
224 return false; | 236 return false; |
225 } | 237 } |
226 | 238 |
227 return true; | 239 return true; |
228 } | 240 } |
229 | 241 |
230 bool NativeViewEGLContext::IsCurrent() { | 242 bool NativeViewEGLContext::IsCurrent() { |
231 DCHECK(context_); | 243 DCHECK(context_); |
232 return context_ == eglGetCurrentContext(); | 244 return context_ == eglGetCurrentContext(); |
233 } | 245 } |
234 | 246 |
235 bool NativeViewEGLContext::IsOffscreen() { | 247 bool NativeViewEGLContext::IsOffscreen() { |
236 return false; | 248 return false; |
237 } | 249 } |
238 | 250 |
239 bool NativeViewEGLContext::SwapBuffers() { | 251 bool NativeViewEGLContext::SwapBuffers() { |
240 if (!eglSwapBuffers(g_display, surface_)) { | 252 if (!eglSwapBuffers(g_display, surface_->egl_surface())) { |
241 VLOG(1) << "eglSwapBuffers failed with error " | 253 VLOG(1) << "eglSwapBuffers failed with error " |
242 << GetLastEGLErrorString(); | 254 << GetLastEGLErrorString(); |
243 return false; | 255 return false; |
244 } | 256 } |
245 | 257 |
246 return true; | 258 return true; |
247 } | 259 } |
248 | 260 |
249 gfx::Size NativeViewEGLContext::GetSize() { | 261 gfx::Size NativeViewEGLContext::GetSize() { |
250 #if defined(OS_WIN) | 262 #if defined(OS_WIN) |
251 RECT rect; | 263 RECT rect; |
252 if (!GetClientRect(static_cast<HWND>(window_), &rect)) { | 264 if (!GetClientRect(static_cast<HWND>(window_), &rect)) { |
253 DCHECK(false) << "GetClientRect failed."; | 265 DCHECK(false) << "GetClientRect failed."; |
254 return gfx::Size(); | 266 return gfx::Size(); |
255 } | 267 } |
256 | 268 |
257 return gfx::Size(rect.right - rect.left, rect.bottom - rect.top); | 269 return gfx::Size(rect.right - rect.left, rect.bottom - rect.top); |
258 #else | 270 #else |
259 // TODO(piman): This doesn't work correctly on Windows yet, the size doesn't | 271 // TODO(piman): This doesn't work correctly on Windows yet, the size doesn't |
260 // get updated on resize. When it does, we can share the code. | 272 // get updated on resize. When it does, we can share the code. |
261 EGLint width; | 273 EGLint width; |
262 EGLint height; | 274 EGLint height; |
263 if (!eglQuerySurface(g_display, surface_, EGL_WIDTH, &width) || | 275 if (!eglQuerySurface( |
264 !eglQuerySurface(g_display, surface_, EGL_HEIGHT, &height)) { | 276 g_display, surface_->egl_surface(), EGL_WIDTH, &width) || |
| 277 !eglQuerySurface( |
| 278 g_display, surface_->egl_surface(), EGL_HEIGHT, &height)) { |
265 NOTREACHED() << "eglQuerySurface failed with error " | 279 NOTREACHED() << "eglQuerySurface failed with error " |
266 << GetLastEGLErrorString(); | 280 << GetLastEGLErrorString(); |
267 return gfx::Size(); | 281 return gfx::Size(); |
268 } | 282 } |
269 | 283 |
270 return gfx::Size(width, height); | 284 return gfx::Size(width, height); |
271 #endif | 285 #endif |
272 } | 286 } |
273 | 287 |
274 void* NativeViewEGLContext::GetHandle() { | 288 void* NativeViewEGLContext::GetHandle() { |
275 return context_; | 289 return context_; |
276 } | 290 } |
277 | 291 |
278 void NativeViewEGLContext::SetSwapInterval(int interval) { | 292 void NativeViewEGLContext::SetSwapInterval(int interval) { |
279 DCHECK(IsCurrent()); | 293 DCHECK(IsCurrent()); |
280 if (!eglSwapInterval(g_display, interval)) { | 294 if (!eglSwapInterval(g_display, interval)) { |
281 LOG(ERROR) << "eglSwapInterval failed with error " | 295 LOG(ERROR) << "eglSwapInterval failed with error " |
282 << GetLastEGLErrorString(); | 296 << GetLastEGLErrorString(); |
283 } | 297 } |
284 } | 298 } |
285 | 299 |
286 EGLSurface NativeViewEGLContext::GetSurface() { | 300 SharedEGLSurface* NativeViewEGLContext::GetSurface() { |
287 return surface_; | 301 return surface_; |
288 } | 302 } |
289 | 303 |
290 SecondaryEGLContext::SecondaryEGLContext() | 304 SecondaryEGLContext::SecondaryEGLContext() |
291 : surface_(NULL), | 305 : context_(NULL) |
292 own_surface_(false), | |
293 context_(NULL) | |
294 { | 306 { |
295 } | 307 } |
296 | 308 |
297 SecondaryEGLContext::~SecondaryEGLContext() { | 309 SecondaryEGLContext::~SecondaryEGLContext() { |
298 } | 310 } |
299 | 311 |
300 bool SecondaryEGLContext::Initialize(GLContext* shared_context) { | 312 bool SecondaryEGLContext::Initialize(GLContext* shared_context) { |
301 DCHECK(!context_); | 313 DCHECK(!context_); |
302 | 314 |
303 static const EGLint kContextAttributes[] = { | 315 static const EGLint kContextAttributes[] = { |
304 EGL_CONTEXT_CLIENT_VERSION, 2, | 316 EGL_CONTEXT_CLIENT_VERSION, 2, |
305 EGL_NONE | 317 EGL_NONE |
306 }; | 318 }; |
307 | 319 |
308 if (shared_context) { | 320 if (shared_context) { |
309 surface_ = static_cast<BaseEGLContext*>(shared_context)->GetSurface(); | 321 surface_ = static_cast<BaseEGLContext*>(shared_context)->GetSurface(); |
310 own_surface_ = false; | |
311 | 322 |
312 // Create a context. | 323 // Create a context. |
313 context_ = eglCreateContext(g_display, | 324 context_ = eglCreateContext(g_display, |
314 g_config, | 325 g_config, |
315 shared_context->GetHandle(), | 326 shared_context->GetHandle(), |
316 kContextAttributes); | 327 kContextAttributes); |
317 } else { | 328 } else { |
318 #ifdef EGL_HAS_PBUFFERS | 329 #ifdef EGL_HAS_PBUFFERS |
319 static const EGLint kPbufferAttribs[] = { | 330 static const EGLint kPbufferAttribs[] = { |
320 EGL_WIDTH, 1, | 331 EGL_WIDTH, 1, |
321 EGL_HEIGHT, 1, | 332 EGL_HEIGHT, 1, |
322 EGL_NONE | 333 EGL_NONE |
323 }; | 334 }; |
324 | 335 |
325 surface_ = eglCreatePbufferSurface(g_display, g_config, kPbufferAttribs); | 336 surface_ = new SharedEGLSurface(eglCreatePbufferSurface(g_display, |
326 if (!surface_) { | 337 g_config, |
| 338 kPbufferAttribs)); |
| 339 if (!surface_->egl_surface()) { |
327 LOG(ERROR) << "eglCreatePbufferSurface failed with error " | 340 LOG(ERROR) << "eglCreatePbufferSurface failed with error " |
328 << GetLastEGLErrorString(); | 341 << GetLastEGLErrorString(); |
| 342 Destroy(); |
329 return false; | 343 return false; |
330 } | 344 } |
331 own_surface_ = true; | |
332 | 345 |
333 context_ = eglCreateContext(g_display, g_config, NULL, kContextAttributes); | 346 context_ = eglCreateContext(g_display, g_config, NULL, kContextAttributes); |
334 #else | 347 #else |
335 NOTIMPLEMENTED() << "Offscreen non-shared GLES context"; | 348 NOTIMPLEMENTED() << "Offscreen non-shared GLES context"; |
336 return false; | 349 return false; |
337 #endif | 350 #endif |
338 } | 351 } |
339 | 352 |
340 if (!context_) { | 353 if (!context_) { |
341 LOG(ERROR) << "eglCreateContext failed with error " | 354 LOG(ERROR) << "eglCreateContext failed with error " |
342 << GetLastEGLErrorString(); | 355 << GetLastEGLErrorString(); |
343 Destroy(); | 356 Destroy(); |
344 return false; | 357 return false; |
345 } | 358 } |
346 | 359 |
347 return true; | 360 return true; |
348 } | 361 } |
349 | 362 |
350 void SecondaryEGLContext::Destroy() { | 363 void SecondaryEGLContext::Destroy() { |
351 if (own_surface_) { | |
352 if (!eglDestroySurface(g_display, surface_)) { | |
353 LOG(ERROR) << "eglDestroySurface failed with error " | |
354 << GetLastEGLErrorString(); | |
355 } | |
356 | |
357 own_surface_ = false; | |
358 } | |
359 surface_ = NULL; | |
360 | |
361 if (context_) { | 364 if (context_) { |
362 if (!eglDestroyContext(g_display, context_)) { | 365 if (!eglDestroyContext(g_display, context_)) { |
363 LOG(ERROR) << "eglDestroyContext failed with error " | 366 LOG(ERROR) << "eglDestroyContext failed with error " |
364 << GetLastEGLErrorString(); | 367 << GetLastEGLErrorString(); |
365 } | 368 } |
366 | 369 |
367 context_ = NULL; | 370 context_ = NULL; |
368 } | 371 } |
| 372 |
| 373 surface_ = NULL; |
369 } | 374 } |
370 | 375 |
371 bool SecondaryEGLContext::MakeCurrent() { | 376 bool SecondaryEGLContext::MakeCurrent() { |
372 DCHECK(context_); | 377 DCHECK(context_); |
373 if (!eglMakeCurrent(g_display, | 378 if (!eglMakeCurrent(g_display, |
374 surface_, surface_, | 379 surface_->egl_surface(), |
| 380 surface_->egl_surface(), |
375 context_)) { | 381 context_)) { |
376 VLOG(1) << "eglMakeCurrent failed with error " | 382 VLOG(1) << "eglMakeCurrent failed with error " |
377 << GetLastEGLErrorString(); | 383 << GetLastEGLErrorString(); |
378 return false; | 384 return false; |
379 } | 385 } |
380 | 386 |
381 return true; | 387 return true; |
382 } | 388 } |
383 | 389 |
384 bool SecondaryEGLContext::IsCurrent() { | 390 bool SecondaryEGLContext::IsCurrent() { |
(...skipping 17 matching lines...) Expand all Loading... |
402 | 408 |
403 void* SecondaryEGLContext::GetHandle() { | 409 void* SecondaryEGLContext::GetHandle() { |
404 return context_; | 410 return context_; |
405 } | 411 } |
406 | 412 |
407 void SecondaryEGLContext::SetSwapInterval(int interval) { | 413 void SecondaryEGLContext::SetSwapInterval(int interval) { |
408 DCHECK(IsCurrent()); | 414 DCHECK(IsCurrent()); |
409 NOTREACHED() << "Attempt to call SetSwapInterval on a SecondaryEGLContext."; | 415 NOTREACHED() << "Attempt to call SetSwapInterval on a SecondaryEGLContext."; |
410 } | 416 } |
411 | 417 |
412 EGLSurface SecondaryEGLContext::GetSurface() { | 418 SharedEGLSurface* SecondaryEGLContext::GetSurface() { |
413 return surface_; | 419 return surface_; |
414 } | 420 } |
415 | 421 |
416 } // namespace gfx | 422 } // namespace gfx |
OLD | NEW |