1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/gl/gl_fence_android_native_fence_sync.h"
#include <sync/sync.h>
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/gfx/gpu_fence_handle.h"
#include "ui/gl/gl_surface_egl.h"
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#include <unistd.h>
#include "base/posix/eintr_wrapper.h"
#endif
namespace gl {
GLFenceAndroidNativeFenceSync::GLFenceAndroidNativeFenceSync() = default;
GLFenceAndroidNativeFenceSync::~GLFenceAndroidNativeFenceSync() = default;
// static
std::unique_ptr<GLFenceAndroidNativeFenceSync>
GLFenceAndroidNativeFenceSync::CreateInternal(EGLenum type, EGLint* attribs) {
DCHECK(GLSurfaceEGL::GetGLDisplayEGL()->IsAndroidNativeFenceSyncSupported());
// Can't use MakeUnique, the no-args constructor is private.
auto fence = base::WrapUnique(new GLFenceAndroidNativeFenceSync());
if (!fence->InitializeInternal(type, attribs)) {
return nullptr;
}
return fence;
}
// static
std::unique_ptr<GLFenceAndroidNativeFenceSync>
GLFenceAndroidNativeFenceSync::CreateForGpuFence() {
return CreateInternal(EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
}
// static
std::unique_ptr<GLFenceAndroidNativeFenceSync>
GLFenceAndroidNativeFenceSync::CreateFromGpuFence(
const gfx::GpuFence& gpu_fence) {
gfx::GpuFenceHandle handle = gpu_fence.GetGpuFenceHandle().Clone();
DCHECK_GE(handle.Peek(), 0);
EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID,
handle.Release().release(), EGL_NONE};
return CreateInternal(EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
}
std::unique_ptr<gfx::GpuFence> GLFenceAndroidNativeFenceSync::GetGpuFence() {
DCHECK(GLSurfaceEGL::GetGLDisplayEGL()->IsAndroidNativeFenceSyncSupported());
const EGLint sync_fd = eglDupNativeFenceFDANDROID(display_, sync_);
if (sync_fd < 0) {
LOG(ERROR)
<< "eglDupNativeFenceFDANDROID duplication failure. Returned error="
<< sync_fd;
return nullptr;
}
gfx::GpuFenceHandle handle;
handle.Adopt(base::ScopedFD(sync_fd));
return std::make_unique<gfx::GpuFence>(std::move(handle));
}
base::TimeTicks GLFenceAndroidNativeFenceSync::GetStatusChangeTime() {
EGLint sync_fd = eglDupNativeFenceFDANDROID(display_, sync_);
if (sync_fd < 0)
return base::TimeTicks();
base::ScopedFD scoped_fd(sync_fd);
base::TimeTicks time;
gfx::GpuFence::GetStatusChangeTime(sync_fd, &time);
return time;
}
} // namespace gl
|