| Index: ui/gl/gl_surface_egl.cc
|
| diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc
|
| index 1b82c97888c590d26f12d6cc28d7b792a5aa5cea..bce36821f57e4d95369228cf61fa86b8f0d40dcd 100644
|
| --- a/ui/gl/gl_surface_egl.cc
|
| +++ b/ui/gl/gl_surface_egl.cc
|
| @@ -18,6 +18,7 @@
|
| #include "base/metrics/histogram_macros.h"
|
| #include "base/strings/string_number_conversions.h"
|
| #include "base/sys_info.h"
|
| +#include "base/threading/thread.h"
|
| #include "base/trace_event/trace_event.h"
|
| #include "build/build_config.h"
|
| #include "ui/gfx/geometry/rect.h"
|
| @@ -353,6 +354,11 @@ EGLConfig ChooseConfig(GLSurface::Format format) {
|
| return nullptr;
|
| }
|
|
|
| +void WaitForSyncFence(EGLDisplay display, EGLSyncKHR fence) {
|
| + eglClientWaitSyncKHR(display, fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
|
| + EGL_FOREVER_KHR);
|
| +}
|
| +
|
| } // namespace
|
|
|
| void GetEGLInitDisplays(bool supports_angle_d3d,
|
| @@ -1154,12 +1160,48 @@ PbufferGLSurfaceEGL::~PbufferGLSurfaceEGL() {
|
| Destroy();
|
| }
|
|
|
| +class SurfacelessEGL::EGLWaitSyncFenceThread
|
| + : public base::Thread,
|
| + public base::NonThreadSafe,
|
| + public base::RefCounted<EGLWaitSyncFenceThread> {
|
| + public:
|
| + static scoped_refptr<EGLWaitSyncFenceThread> Create() {
|
| + if (!g_wait_sync_fence_thread) {
|
| + g_wait_sync_fence_thread = new EGLWaitSyncFenceThread;
|
| + g_wait_sync_fence_thread->Start();
|
| + }
|
| + return g_wait_sync_fence_thread;
|
| + }
|
| +
|
| + private:
|
| + friend class base::RefCounted<EGLWaitSyncFenceThread>;
|
| +
|
| + EGLWaitSyncFenceThread() : base::Thread("EGLWaitSyncFence") {
|
| + DCHECK(CalledOnValidThread());
|
| + }
|
| + ~EGLWaitSyncFenceThread() override {
|
| + DCHECK(CalledOnValidThread());
|
| + g_wait_sync_fence_thread = nullptr;
|
| + Stop();
|
| + }
|
| +
|
| + static EGLWaitSyncFenceThread* g_wait_sync_fence_thread;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(EGLWaitSyncFenceThread);
|
| +};
|
| +
|
| +SurfacelessEGL::EGLWaitSyncFenceThread*
|
| + SurfacelessEGL::EGLWaitSyncFenceThread::g_wait_sync_fence_thread = nullptr;
|
| +
|
| SurfacelessEGL::SurfacelessEGL(const gfx::Size& size)
|
| - : size_(size) {
|
| + : size_(size), weak_ptr_factory_(this) {
|
| format_ = GLSurface::SURFACE_SURFACELESS;
|
| }
|
|
|
| bool SurfacelessEGL::Initialize() {
|
| + wait_sync_fence_thread_ = EGLWaitSyncFenceThread::Create();
|
| + if (!wait_sync_fence_thread_)
|
| + return false;
|
| return Initialize(SURFACE_SURFACELESS);
|
| }
|
|
|
| @@ -1203,6 +1245,35 @@ void* SurfacelessEGL::GetShareHandle() {
|
| return NULL;
|
| }
|
|
|
| +bool SurfacelessEGL::SupportsInsertFence() {
|
| + return true;
|
| +}
|
| +
|
| +void SurfacelessEGL::InsertFence(const base::Closure& callback) {
|
| + bool rv = InsertSyncFence(nullptr, callback);
|
| + LOG_IF(ERROR, !rv) << "InsertFence failed";
|
| +}
|
| +
|
| +bool SurfacelessEGL::InsertSyncFence(const EGLint* attribs,
|
| + const base::Closure& callback) {
|
| + EGLSyncKHR fence =
|
| + eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attribs);
|
| + if (!fence)
|
| + return false;
|
| +
|
| + wait_sync_fence_thread_->task_runner()->PostTaskAndReply(
|
| + FROM_HERE, base::Bind(&WaitForSyncFence, GetDisplay(), fence),
|
| + base::Bind(&SurfacelessEGL::FenceRetired, weak_ptr_factory_.GetWeakPtr(),
|
| + fence, callback));
|
| + return true;
|
| +}
|
| +
|
| +void SurfacelessEGL::FenceRetired(EGLSyncKHR fence,
|
| + const base::Closure& callback) {
|
| + eglDestroySyncKHR(GetDisplay(), fence);
|
| + callback.Run();
|
| +}
|
| +
|
| SurfacelessEGL::~SurfacelessEGL() {
|
| }
|
|
|
|
|