Chromium Code Reviews| 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 |