1#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, 12 LocalHandle acquire_fence, std::size_t slot) 13 : buffer_(buffer), acquire_fence_(std::move(acquire_fence)), slot_(slot) {} 14 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 34AcquiredBuffer::AcquiredBuffer(AcquiredBuffer&& other) { 35 *this = std::move(other); 36} 37 38AcquiredBuffer::~AcquiredBuffer() { Release(LocalHandle(kEmptyFence)); } 39 40AcquiredBuffer& AcquiredBuffer::operator=(AcquiredBuffer&& other) { 41 if (this != &other) { 42 Release(); 43 44 using std::swap; 45 swap(buffer_, other.buffer_); 46 swap(acquire_fence_, other.acquire_fence_); 47 swap(slot_, other.slot_); 48 } 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), 60 "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); 63 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) { 83 ALOGD_IF(TRACE, "AcquiredBuffer::Release: buffer_id=%d release_fence=%d", 84 buffer_ ? buffer_->id() : -1, release_fence.Get()); 85 if (buffer_) { 86 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; 95 } 96 97 acquire_fence_.Close(); 98 slot_ = 0; 99 return 0; 100} 101 102} // namespace dvr 103} // namespace android 104