1 #include "acquired_buffer.h"
2 
3 #include <log/log.h>
4 #include <sync/sync.h>
5 
6 using android::pdx::LocalHandle;
7 
8 namespace android {
9 namespace dvr {
10 
AcquiredBuffer(const std::shared_ptr<BufferConsumer> & buffer,LocalHandle acquire_fence)11 AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer,
12                                LocalHandle acquire_fence)
13     : buffer_(buffer), acquire_fence_(std::move(acquire_fence)) {}
14 
AcquiredBuffer(const std::shared_ptr<BufferConsumer> & buffer,int * error)15 AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer,
16                                int* error) {
17   LocalHandle fence;
18   const int ret = buffer->Acquire(&fence);
19 
20   if (error)
21     *error = ret;
22 
23   if (ret < 0) {
24     ALOGW("AcquiredBuffer::AcquiredBuffer: Failed to acquire buffer: %s",
25           strerror(-ret));
26     buffer_ = nullptr;
27     // Default construct sets acquire_fence_ to empty.
28   } else {
29     buffer_ = buffer;
30     acquire_fence_ = std::move(fence);
31   }
32 }
33 
AcquiredBuffer(AcquiredBuffer && other)34 AcquiredBuffer::AcquiredBuffer(AcquiredBuffer&& other)
35     : buffer_(std::move(other.buffer_)),
36       acquire_fence_(std::move(other.acquire_fence_)) {}
37 
~AcquiredBuffer()38 AcquiredBuffer::~AcquiredBuffer() { Release(LocalHandle(kEmptyFence)); }
39 
operator =(AcquiredBuffer && other)40 AcquiredBuffer& AcquiredBuffer::operator=(AcquiredBuffer&& other) {
41   if (this != &other) {
42     Release(LocalHandle(kEmptyFence));
43 
44     buffer_ = std::move(other.buffer_);
45     acquire_fence_ = std::move(other.acquire_fence_);
46   }
47   return *this;
48 }
49 
IsAvailable() const50 bool AcquiredBuffer::IsAvailable() const {
51   if (IsEmpty())
52     return false;
53 
54   // Only check the fence if the acquire fence is not empty.
55   if (acquire_fence_) {
56     const int ret = sync_wait(acquire_fence_.Get(), 0);
57     ALOGD_IF(TRACE || (ret < 0 && errno != ETIME),
58              "AcquiredBuffer::IsAvailable: acquire_fence_=%d sync_wait()=%d "
59              "errno=%d.",
60              acquire_fence_.Get(), ret, ret < 0 ? errno : 0);
61     if (ret == 0) {
62       // The fence is completed, so to avoid further calls to sync_wait we close
63       // it here.
64       acquire_fence_.Close();
65     }
66     return ret == 0;
67   } else {
68     return true;
69   }
70 }
71 
ClaimAcquireFence()72 LocalHandle AcquiredBuffer::ClaimAcquireFence() {
73   return std::move(acquire_fence_);
74 }
75 
ClaimBuffer()76 std::shared_ptr<BufferConsumer> AcquiredBuffer::ClaimBuffer() {
77   return std::move(buffer_);
78 }
79 
Release(LocalHandle release_fence)80 int AcquiredBuffer::Release(LocalHandle release_fence) {
81   if (buffer_) {
82     // Close the release fence since we can't transfer it with an async release.
83     release_fence.Close();
84     const int ret = buffer_->ReleaseAsync();
85     if (ret < 0) {
86       ALOGE("AcquiredBuffer::Release: Failed to release buffer %d: %s",
87             buffer_->id(), strerror(-ret));
88       if (ret != -ESHUTDOWN)
89         return ret;
90     }
91 
92     buffer_ = nullptr;
93     acquire_fence_.Close();
94   }
95 
96   return 0;
97 }
98 
99 }  // namespace dvr
100 }  // namespace android
101