gpu_fence.cc 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // 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. #include "ui/gfx/gpu_fence.h"
  5. #include "base/logging.h"
  6. #include "base/notreached.h"
  7. #include "base/time/time.h"
  8. #include "build/build_config.h"
  9. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
  10. #include <sync/sync.h>
  11. #endif
  12. namespace gfx {
  13. GpuFence::GpuFence(GpuFenceHandle fence_handle)
  14. : fence_handle_(std::move(fence_handle)) {}
  15. GpuFence::~GpuFence() = default;
  16. GpuFence::GpuFence(GpuFence&& other) = default;
  17. GpuFence& GpuFence::operator=(GpuFence&& other) = default;
  18. const GpuFenceHandle& GpuFence::GetGpuFenceHandle() const {
  19. return fence_handle_;
  20. }
  21. ClientGpuFence GpuFence::AsClientGpuFence() {
  22. return reinterpret_cast<ClientGpuFence>(this);
  23. }
  24. // static
  25. GpuFence* GpuFence::FromClientGpuFence(ClientGpuFence gpu_fence) {
  26. return reinterpret_cast<GpuFence*>(gpu_fence);
  27. }
  28. void GpuFence::Wait() {
  29. if (fence_handle_.is_null()) {
  30. return;
  31. }
  32. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
  33. static const int kInfiniteSyncWaitTimeout = -1;
  34. DCHECK_GE(fence_handle_.owned_fd.get(), 0);
  35. if (sync_wait(fence_handle_.owned_fd.get(), kInfiniteSyncWaitTimeout) < 0) {
  36. LOG(FATAL) << "Failed while waiting for gpu fence fd";
  37. }
  38. #else
  39. NOTREACHED();
  40. #endif
  41. }
  42. // static
  43. GpuFence::FenceStatus GpuFence::GetStatusChangeTime(int fd,
  44. base::TimeTicks* time) {
  45. DCHECK_NE(fd, -1);
  46. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
  47. auto info =
  48. std::unique_ptr<sync_fence_info_data, void (*)(sync_fence_info_data*)>{
  49. sync_fence_info(fd), sync_fence_info_free};
  50. if (!info) {
  51. LOG(ERROR) << "sync_fence_info returned null for fd : " << fd;
  52. return FenceStatus::kInvalid;
  53. }
  54. // Not signalled yet.
  55. if (info->status != 1) {
  56. return FenceStatus::kNotSignaled;
  57. }
  58. uint64_t timestamp_ns = 0u;
  59. struct sync_pt_info* pt_info = nullptr;
  60. while ((pt_info = sync_pt_info(info.get(), pt_info)))
  61. timestamp_ns = std::max(timestamp_ns, pt_info->timestamp_ns);
  62. if (timestamp_ns == 0u) {
  63. LOG(ERROR) << "No timestamp provided from sync_pt_info for fd : " << fd;
  64. return FenceStatus::kInvalid;
  65. }
  66. *time = base::TimeTicks() + base::Nanoseconds(timestamp_ns);
  67. return FenceStatus::kSignaled;
  68. #endif
  69. NOTREACHED();
  70. return FenceStatus::kInvalid;
  71. }
  72. base::TimeTicks GpuFence::GetMaxTimestamp() const {
  73. base::TimeTicks timestamp;
  74. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
  75. FenceStatus status =
  76. GetStatusChangeTime(fence_handle_.owned_fd.get(), &timestamp);
  77. DCHECK_EQ(status, FenceStatus::kSignaled);
  78. return timestamp;
  79. #endif
  80. NOTREACHED();
  81. return timestamp;
  82. }
  83. } // namespace gfx