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) 13 : buffer_(buffer), acquire_fence_(std::move(acquire_fence)) {} 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 : buffer_(std::move(other.buffer_)), 36 acquire_fence_(std::move(other.acquire_fence_)) {} 37 38AcquiredBuffer::~AcquiredBuffer() { Release(LocalHandle(kEmptyFence)); } 39 40AcquiredBuffer& 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 50bool 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 72LocalHandle AcquiredBuffer::ClaimAcquireFence() { 73 return std::move(acquire_fence_); 74} 75 76std::shared_ptr<BufferConsumer> AcquiredBuffer::ClaimBuffer() { 77 return std::move(buffer_); 78} 79 80int 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