diff options
Diffstat (limited to 'chromium/ui/gfx/gpu_fence.cc')
-rw-r--r-- | chromium/ui/gfx/gpu_fence.cc | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/chromium/ui/gfx/gpu_fence.cc b/chromium/ui/gfx/gpu_fence.cc index 7d38c0eb906..87fc6d10761 100644 --- a/chromium/ui/gfx/gpu_fence.cc +++ b/chromium/ui/gfx/gpu_fence.cc @@ -5,6 +5,8 @@ #include "ui/gfx/gpu_fence.h" #include "base/logging.h" +#include "base/notreached.h" +#include "base/time/time.h" #if defined(OS_LINUX) || defined(OS_ANDROID) #include <sync/sync.h> @@ -73,4 +75,49 @@ void GpuFence::Wait() { } } +// static +GpuFence::FenceStatus GpuFence::GetStatusChangeTime(int fd, + base::TimeTicks* time) { + DCHECK_NE(fd, -1); +#if defined(OS_LINUX) || defined(OS_ANDROID) + auto info = + std::unique_ptr<sync_fence_info_data, void (*)(sync_fence_info_data*)>{ + sync_fence_info(fd), sync_fence_info_free}; + if (!info) { + LOG(ERROR) << "sync_fence_info returned null for fd : " << fd; + return FenceStatus::kInvalid; + } + + // Not signalled yet. + if (info->status != 1) { + return FenceStatus::kNotSignaled; + } + + uint64_t timestamp_ns = 0u; + struct sync_pt_info* pt_info = nullptr; + while ((pt_info = sync_pt_info(info.get(), pt_info))) + timestamp_ns = std::max(timestamp_ns, pt_info->timestamp_ns); + + if (timestamp_ns == 0u) { + LOG(ERROR) << "No timestamp provided from sync_pt_info for fd : " << fd; + return FenceStatus::kInvalid; + } + *time = base::TimeTicks() + base::TimeDelta::FromNanoseconds(timestamp_ns); + return FenceStatus::kSignaled; +#endif + NOTREACHED(); + return FenceStatus::kInvalid; +} + +base::TimeTicks GpuFence::GetMaxTimestamp() const { + base::TimeTicks timestamp; +#if defined(OS_LINUX) || defined(OS_ANDROID) + FenceStatus status = GetStatusChangeTime(owned_fd_.get(), ×tamp); + DCHECK_EQ(status, FenceStatus::kSignaled); + return timestamp; +#endif + NOTREACHED(); + return timestamp; +} + } // namespace gfx |