blob: 9614c6d3064c8640ff0964a02c77bc97b12cf075 [file] [log] [blame]
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001#include "acquired_buffer.h"
2
3#include <log/log.h>
4#include <sync/sync.h>
5
6using android::pdx::LocalHandle;
7
8namespace android {
9namespace dvr {
10
11AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer,
Corey Tabaka0d07cdd2017-09-28 11:15:50 -070012 LocalHandle acquire_fence, std::size_t slot)
13 : buffer_(buffer), acquire_fence_(std::move(acquire_fence)), slot_(slot) {}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080014
15AcquiredBuffer::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
Corey Tabaka0d07cdd2017-09-28 11:15:50 -070034AcquiredBuffer::AcquiredBuffer(AcquiredBuffer&& other) {
35 *this = std::move(other);
36}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080037
38AcquiredBuffer::~AcquiredBuffer() { Release(LocalHandle(kEmptyFence)); }
39
40AcquiredBuffer& AcquiredBuffer::operator=(AcquiredBuffer&& other) {
41 if (this != &other) {
Corey Tabaka0d07cdd2017-09-28 11:15:50 -070042 Release();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080043
Corey Tabaka0d07cdd2017-09-28 11:15:50 -070044 using std::swap;
45 swap(buffer_, other.buffer_);
46 swap(acquire_fence_, other.acquire_fence_);
47 swap(slot_, other.slot_);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080048 }
49 return *this;
50}
51
52bool AcquiredBuffer::IsAvailable() const {
53 if (IsEmpty())
54 return false;
55
56 // Only check the fence if the acquire fence is not empty.
57 if (acquire_fence_) {
58 const int ret = sync_wait(acquire_fence_.Get(), 0);
59 ALOGD_IF(TRACE || (ret < 0 && errno != ETIME),
Corey Tabaka0b485c92017-05-19 12:02:58 -070060 "AcquiredBuffer::IsAvailable: buffer_id=%d acquire_fence=%d "
61 "sync_wait()=%d errno=%d.",
62 buffer_->id(), acquire_fence_.Get(), ret, ret < 0 ? errno : 0);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080063 if (ret == 0) {
64 // The fence is completed, so to avoid further calls to sync_wait we close
65 // it here.
66 acquire_fence_.Close();
67 }
68 return ret == 0;
69 } else {
70 return true;
71 }
72}
73
74LocalHandle AcquiredBuffer::ClaimAcquireFence() {
75 return std::move(acquire_fence_);
76}
77
78std::shared_ptr<BufferConsumer> AcquiredBuffer::ClaimBuffer() {
79 return std::move(buffer_);
80}
81
82int AcquiredBuffer::Release(LocalHandle release_fence) {
Corey Tabaka0b485c92017-05-19 12:02:58 -070083 ALOGD_IF(TRACE, "AcquiredBuffer::Release: buffer_id=%d release_fence=%d",
84 buffer_ ? buffer_->id() : -1, release_fence.Get());
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080085 if (buffer_) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080086 const int ret = buffer_->ReleaseAsync();
87 if (ret < 0) {
88 ALOGE("AcquiredBuffer::Release: Failed to release buffer %d: %s",
89 buffer_->id(), strerror(-ret));
90 if (ret != -ESHUTDOWN)
91 return ret;
92 }
93
94 buffer_ = nullptr;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080095 }
96
Corey Tabaka0d07cdd2017-09-28 11:15:50 -070097 acquire_fence_.Close();
98 slot_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080099 return 0;
100}
101
102} // namespace dvr
103} // namespace android