OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/gl/gl_surface_egl.h" | 5 #include "ui/gl/gl_surface_egl.h" |
6 | 6 |
7 #if defined(OS_ANDROID) | 7 #if defined(OS_ANDROID) |
8 #include <android/native_window_jni.h> | 8 #include <android/native_window_jni.h> |
9 #endif | 9 #endif |
10 | 10 |
11 #include "base/debug/trace_event.h" | |
11 #include "base/logging.h" | 12 #include "base/logging.h" |
12 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
13 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
14 #include "build/build_config.h" | 15 #include "build/build_config.h" |
15 #include "ui/gl/egl_util.h" | 16 #include "ui/gl/egl_util.h" |
16 #include "ui/gl/gl_context.h" | 17 #include "ui/gl/gl_context.h" |
17 | 18 |
18 #if defined(USE_X11) | 19 #if defined(USE_X11) |
19 extern "C" { | 20 extern "C" { |
20 #include <X11/Xlib.h> | 21 #include <X11/Xlib.h> |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
214 return g_egl_create_context_robustness_supported; | 215 return g_egl_create_context_robustness_supported; |
215 } | 216 } |
216 | 217 |
217 GLSurfaceEGL::~GLSurfaceEGL() {} | 218 GLSurfaceEGL::~GLSurfaceEGL() {} |
218 | 219 |
219 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(bool software, | 220 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(bool software, |
220 gfx::AcceleratedWidget window) | 221 gfx::AcceleratedWidget window) |
221 : window_(window), | 222 : window_(window), |
222 surface_(NULL), | 223 surface_(NULL), |
223 supports_post_sub_buffer_(false), | 224 supports_post_sub_buffer_(false), |
224 config_(NULL) { | 225 config_(NULL), |
226 max_frame_latency_(0) { | |
225 software_ = software; | 227 software_ = software; |
226 #if defined(OS_ANDROID) | 228 #if defined(OS_ANDROID) |
227 if (window) | 229 if (window) |
228 ANativeWindow_acquire(window); | 230 ANativeWindow_acquire(window); |
229 #endif | 231 #endif |
230 } | 232 } |
231 | 233 |
232 bool NativeViewGLSurfaceEGL::Initialize() { | 234 bool NativeViewGLSurfaceEGL::Initialize() { |
233 DCHECK(!surface_); | 235 DCHECK(!surface_); |
234 | 236 |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
361 } | 363 } |
362 return config_; | 364 return config_; |
363 #endif | 365 #endif |
364 } | 366 } |
365 | 367 |
366 bool NativeViewGLSurfaceEGL::IsOffscreen() { | 368 bool NativeViewGLSurfaceEGL::IsOffscreen() { |
367 return false; | 369 return false; |
368 } | 370 } |
369 | 371 |
370 bool NativeViewGLSurfaceEGL::SwapBuffers() { | 372 bool NativeViewGLSurfaceEGL::SwapBuffers() { |
373 // Create a fence for this frame. | |
374 if (max_frame_latency_ > 0) { | |
375 DCHECK_LE(frame_fences_.size(), max_frame_latency_ - 1); | |
376 EGLSyncKHR fence = eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, NULL); | |
Sami
2013/04/24 10:44:18
I remember one driver where sync object creation w
epennerAtGoogle
2013/04/24 19:33:38
Will do.
| |
377 frame_fences_.push_back(fence); | |
378 } | |
379 | |
371 if (!eglSwapBuffers(GetDisplay(), surface_)) { | 380 if (!eglSwapBuffers(GetDisplay(), surface_)) { |
372 DVLOG(1) << "eglSwapBuffers failed with error " | 381 DVLOG(1) << "eglSwapBuffers failed with error " |
373 << GetLastEGLErrorString(); | 382 << GetLastEGLErrorString(); |
374 return false; | 383 return false; |
375 } | 384 } |
376 | 385 |
386 // SwapBuffers above will block above according to the driver's | |
387 // maximum latency. We now block again according to our own. | |
388 DCHECK_LE(frame_fences_.size(), max_frame_latency_); | |
389 if (frame_fences_.size() == max_frame_latency_) { | |
390 TRACE_EVENT0("cc", "NativeViewGLSurfaceEGL eglClientWaitSyncKHR"); | |
391 // We shouldn't need the flush flag, as SwapBuffers | |
392 // always triggers a flush. | |
393 EGLint flags = 0; //EGL_SYNC_FLUSH_COMMANDS_BIT_KHR; | |
394 EGLTimeKHR time = EGL_FOREVER_KHR; | |
395 EGLSyncKHR fence = frame_fences_.front(); | |
396 eglClientWaitSyncKHR(GetDisplay(), fence, flags, time); | |
Sami
2013/04/24 10:44:18
Call eglDestroySyncKHR after waiting here to avoid
epennerAtGoogle
2013/04/24 19:33:38
Oops! Thanks!
| |
397 frame_fences_.pop_front(); | |
398 } | |
399 | |
377 return true; | 400 return true; |
378 } | 401 } |
379 | 402 |
380 gfx::Size NativeViewGLSurfaceEGL::GetSize() { | 403 gfx::Size NativeViewGLSurfaceEGL::GetSize() { |
381 EGLint width; | 404 EGLint width; |
382 EGLint height; | 405 EGLint height; |
383 if (!eglQuerySurface(GetDisplay(), surface_, EGL_WIDTH, &width) || | 406 if (!eglQuerySurface(GetDisplay(), surface_, EGL_WIDTH, &width) || |
384 !eglQuerySurface(GetDisplay(), surface_, EGL_HEIGHT, &height)) { | 407 !eglQuerySurface(GetDisplay(), surface_, EGL_HEIGHT, &height)) { |
385 NOTREACHED() << "eglQuerySurface failed with error " | 408 NOTREACHED() << "eglQuerySurface failed with error " |
386 << GetLastEGLErrorString(); | 409 << GetLastEGLErrorString(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
432 << GetLastEGLErrorString(); | 455 << GetLastEGLErrorString(); |
433 return false; | 456 return false; |
434 } | 457 } |
435 return true; | 458 return true; |
436 } | 459 } |
437 | 460 |
438 VSyncProvider* NativeViewGLSurfaceEGL::GetVSyncProvider() { | 461 VSyncProvider* NativeViewGLSurfaceEGL::GetVSyncProvider() { |
439 return vsync_provider_.get(); | 462 return vsync_provider_.get(); |
440 } | 463 } |
441 | 464 |
465 void NativeViewGLSurfaceEGL::SetMaximumFrameLatency(unsigned int frames) { | |
466 while (frame_fences_.size() > frames) { | |
467 eglDestroySyncKHR(GetDisplay(), frame_fences_.front()); | |
468 frame_fences_.pop_front(); | |
469 } | |
470 max_frame_latency_ = frames; | |
471 } | |
472 | |
442 NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() { | 473 NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() { |
474 SetMaximumFrameLatency(0); | |
475 DCHECK(!frame_fences_.size()); | |
476 | |
443 Destroy(); | 477 Destroy(); |
444 #if defined(OS_ANDROID) | 478 #if defined(OS_ANDROID) |
445 if (window_) | 479 if (window_) |
446 ANativeWindow_release(window_); | 480 ANativeWindow_release(window_); |
447 #endif | 481 #endif |
448 } | 482 } |
449 | 483 |
450 void NativeViewGLSurfaceEGL::SetHandle(EGLSurface surface) { | 484 void NativeViewGLSurfaceEGL::SetHandle(EGLSurface surface) { |
451 surface_ = surface; | 485 surface_ = surface; |
452 } | 486 } |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
570 | 604 |
571 return handle; | 605 return handle; |
572 #endif | 606 #endif |
573 } | 607 } |
574 | 608 |
575 PbufferGLSurfaceEGL::~PbufferGLSurfaceEGL() { | 609 PbufferGLSurfaceEGL::~PbufferGLSurfaceEGL() { |
576 Destroy(); | 610 Destroy(); |
577 } | 611 } |
578 | 612 |
579 } // namespace gfx | 613 } // namespace gfx |
OLD | NEW |