blob: 7e76fab292fb030d20c8b5ec84ce55eb4d2847e2 [file] [log] [blame]
Klaus Weidnere66cc7d2017-12-09 17:26:301// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ui/gfx/gpu_fence.h"
6
7#include "base/logging.h"
Hans Wennborg3930cf32020-06-17 16:29:528#include "base/notreached.h"
Daniele Castagna3bbaa0e62020-06-25 14:54:279#include "base/time/time.h"
Xiaohan Wangd1b0e6b2022-01-20 21:40:2010#include "build/build_config.h"
Klaus Weidnere66cc7d2017-12-09 17:26:3011
Xiaohan Wangd1b0e6b2022-01-20 21:40:2012#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
Alexandros Frantzis922160ed2018-05-16 21:19:1013#include <sync/sync.h>
14#endif
15
Klaus Weidnere66cc7d2017-12-09 17:26:3016namespace gfx {
17
Rafael Cintronaac6e732020-09-17 20:11:5018GpuFence::GpuFence(GpuFenceHandle fence_handle)
19 : fence_handle_(std::move(fence_handle)) {}
Klaus Weidnere66cc7d2017-12-09 17:26:3020
21GpuFence::~GpuFence() = default;
22
Emircan Uysaler04a56b02020-10-30 18:43:2923GpuFence::GpuFence(GpuFence&& other) = default;
24
25GpuFence& GpuFence::operator=(GpuFence&& other) = default;
26
Rafael Cintronaac6e732020-09-17 20:11:5027const GpuFenceHandle& GpuFence::GetGpuFenceHandle() const {
28 return fence_handle_;
Klaus Weidnere66cc7d2017-12-09 17:26:3029}
30
31ClientGpuFence GpuFence::AsClientGpuFence() {
32 return reinterpret_cast<ClientGpuFence>(this);
33}
34
35// static
36GpuFence* GpuFence::FromClientGpuFence(ClientGpuFence gpu_fence) {
37 return reinterpret_cast<GpuFence*>(gpu_fence);
38}
39
Alexandros Frantzis922160ed2018-05-16 21:19:1040void GpuFence::Wait() {
Rafael Cintron16519e52020-09-24 01:06:2841 if (fence_handle_.is_null()) {
42 return;
Alexandros Frantzis922160ed2018-05-16 21:19:1043 }
Rafael Cintron16519e52020-09-24 01:06:2844
Xiaohan Wangd1b0e6b2022-01-20 21:40:2045#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
Rafael Cintron16519e52020-09-24 01:06:2846 static const int kInfiniteSyncWaitTimeout = -1;
47 DCHECK_GE(fence_handle_.owned_fd.get(), 0);
48 if (sync_wait(fence_handle_.owned_fd.get(), kInfiniteSyncWaitTimeout) < 0) {
49 LOG(FATAL) << "Failed while waiting for gpu fence fd";
50 }
51#else
52 NOTREACHED();
53#endif
Alexandros Frantzis922160ed2018-05-16 21:19:1054}
55
Daniele Castagna3bbaa0e62020-06-25 14:54:2756// static
57GpuFence::FenceStatus GpuFence::GetStatusChangeTime(int fd,
58 base::TimeTicks* time) {
59 DCHECK_NE(fd, -1);
Xiaohan Wangd1b0e6b2022-01-20 21:40:2060#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
Daniele Castagna3bbaa0e62020-06-25 14:54:2761 auto info =
62 std::unique_ptr<sync_fence_info_data, void (*)(sync_fence_info_data*)>{
63 sync_fence_info(fd), sync_fence_info_free};
64 if (!info) {
65 LOG(ERROR) << "sync_fence_info returned null for fd : " << fd;
66 return FenceStatus::kInvalid;
67 }
68
69 // Not signalled yet.
70 if (info->status != 1) {
71 return FenceStatus::kNotSignaled;
72 }
73
74 uint64_t timestamp_ns = 0u;
75 struct sync_pt_info* pt_info = nullptr;
76 while ((pt_info = sync_pt_info(info.get(), pt_info)))
77 timestamp_ns = std::max(timestamp_ns, pt_info->timestamp_ns);
78
79 if (timestamp_ns == 0u) {
80 LOG(ERROR) << "No timestamp provided from sync_pt_info for fd : " << fd;
81 return FenceStatus::kInvalid;
82 }
Peter Kastinge5a38ed2021-10-02 03:06:3583 *time = base::TimeTicks() + base::Nanoseconds(timestamp_ns);
Daniele Castagna3bbaa0e62020-06-25 14:54:2784 return FenceStatus::kSignaled;
85#endif
86 NOTREACHED();
87 return FenceStatus::kInvalid;
88}
89
90base::TimeTicks GpuFence::GetMaxTimestamp() const {
91 base::TimeTicks timestamp;
Xiaohan Wangd1b0e6b2022-01-20 21:40:2092#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
Rafael Cintronaac6e732020-09-17 20:11:5093 FenceStatus status =
94 GetStatusChangeTime(fence_handle_.owned_fd.get(), &timestamp);
Daniele Castagna3bbaa0e62020-06-25 14:54:2795 DCHECK_EQ(status, FenceStatus::kSignaled);
96 return timestamp;
97#endif
98 NOTREACHED();
99 return timestamp;
100}
101
Klaus Weidnere66cc7d2017-12-09 17:26:30102} // namespace gfx