blob: 43206fafd3ab33255dac49a4fb133741170a7a85 [file] [log] [blame]
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -08001#if defined(__clang__)
2#pragma clang diagnostic push
3#pragma clang diagnostic ignored "-Weverything"
4#endif
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08005
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -08006// The following headers are included without checking every warning.
7// TODO(b/72172820): Remove the workaround once we have enforced -Weverything
8// in these headers and their dependencies.
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -07009#include <dvr/dvr_api.h>
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080010#include <gui/BufferHubProducer.h>
11
12#if defined(__clang__)
13#pragma clang diagnostic pop
14#endif
15
Alex Vakulenko4fe60582017-02-02 11:35:59 -080016#include <inttypes.h>
17#include <log/log.h>
Mathias Agopian6a3c05b2017-04-27 20:06:55 -070018#include <system/window.h>
Alex Vakulenko4fe60582017-02-02 11:35:59 -080019
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080020namespace android {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080021
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070022/* static */
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080023sp<BufferHubProducer> BufferHubProducer::Create(
24 const std::shared_ptr<dvr::ProducerQueue>& queue) {
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070025 if (queue->metadata_size() != sizeof(DvrNativeBufferMetadata)) {
26 ALOGE(
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080027 "BufferHubProducer::Create producer's metadata size is different "
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070028 "than the size of DvrNativeBufferMetadata");
29 return nullptr;
30 }
31
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080032 sp<BufferHubProducer> producer = new BufferHubProducer;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070033 producer->queue_ = queue;
34 return producer;
35}
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080036
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -080037/* static */
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080038sp<BufferHubProducer> BufferHubProducer::Create(
39 dvr::ProducerQueueParcelable parcelable) {
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -080040 if (!parcelable.IsValid()) {
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080041 ALOGE("BufferHubProducer::Create: Invalid producer parcelable.");
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -080042 return nullptr;
43 }
44
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080045 sp<BufferHubProducer> producer = new BufferHubProducer;
46 producer->queue_ = dvr::ProducerQueue::Import(parcelable.TakeChannelHandle());
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -080047 return producer;
48}
49
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080050status_t BufferHubProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
51 ALOGV("requestBuffer: slot=%d", slot);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080052
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070053 std::unique_lock<std::mutex> lock(mutex_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080054
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070055 if (connected_api_ == kNoConnectedApi) {
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080056 ALOGE("requestBuffer: BufferHubProducer has no connected producer");
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -070057 return NO_INIT;
58 }
59
60 if (slot < 0 || slot >= max_buffer_count_) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -080061 ALOGE("requestBuffer: slot index %d out of range [0, %d)", slot,
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -070062 max_buffer_count_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080063 return BAD_VALUE;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070064 } else if (!buffers_[slot].mBufferState.isDequeued()) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -080065 ALOGE("requestBuffer: slot %d is not owned by the producer (state = %s)",
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070066 slot, buffers_[slot].mBufferState.string());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080067 return BAD_VALUE;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070068 } else if (buffers_[slot].mGraphicBuffer != nullptr) {
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -070069 ALOGE("requestBuffer: slot %d is not empty.", slot);
70 return BAD_VALUE;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070071 } else if (buffers_[slot].mBufferProducer == nullptr) {
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -070072 ALOGE("requestBuffer: slot %d is not dequeued.", slot);
73 return BAD_VALUE;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080074 }
75
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070076 const auto& buffer_producer = buffers_[slot].mBufferProducer;
Corey Tabakacd52dd92017-04-07 18:03:57 -070077 sp<GraphicBuffer> graphic_buffer = buffer_producer->buffer()->buffer();
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -070078
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070079 buffers_[slot].mGraphicBuffer = graphic_buffer;
80 buffers_[slot].mRequestBufferCalled = true;
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -070081
82 *buf = graphic_buffer;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080083 return NO_ERROR;
84}
85
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080086status_t BufferHubProducer::setMaxDequeuedBufferCount(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080087 int max_dequeued_buffers) {
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080088 ALOGV("setMaxDequeuedBufferCount: max_dequeued_buffers=%d",
89 max_dequeued_buffers);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080090
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070091 std::unique_lock<std::mutex> lock(mutex_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080092
93 if (max_dequeued_buffers <= 0 ||
94 max_dequeued_buffers >
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080095 int(dvr::BufferHubQueue::kMaxQueueCapacity - kDefaultUndequeuedBuffers)) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -080096 ALOGE("setMaxDequeuedBufferCount: %d out of range (0, %zu]",
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080097 max_dequeued_buffers, dvr::BufferHubQueue::kMaxQueueCapacity);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080098 return BAD_VALUE;
99 }
100
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700101 // The new dequeued_buffers count should not be violated by the number
102 // of currently dequeued buffers.
103 int dequeued_count = 0;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700104 for (const auto& buf : buffers_) {
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700105 if (buf.mBufferState.isDequeued()) {
106 dequeued_count++;
107 }
108 }
109 if (dequeued_count > max_dequeued_buffers) {
110 ALOGE(
111 "setMaxDequeuedBufferCount: the requested dequeued_buffers"
112 "count (%d) exceeds the current dequeued buffer count (%d)",
113 max_dequeued_buffers, dequeued_count);
114 return BAD_VALUE;
115 }
116
117 max_dequeued_buffer_count_ = max_dequeued_buffers;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800118 return NO_ERROR;
119}
120
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800121status_t BufferHubProducer::setAsyncMode(bool async) {
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700122 if (async) {
123 // TODO(b/36724099) BufferHubQueue's consumer end always acquires the buffer
124 // automatically and behaves differently from IGraphicBufferConsumer. Thus,
125 // android::BufferQueue's async mode (a.k.a. allocating an additional buffer
126 // to prevent dequeueBuffer from being blocking) technically does not apply
127 // here.
128 //
129 // In Daydream, non-blocking producer side dequeue is guaranteed by careful
130 // buffer consumer implementations. In another word, BufferHubQueue based
131 // dequeueBuffer should never block whether setAsyncMode(true) is set or
132 // not.
133 //
134 // See: IGraphicBufferProducer::setAsyncMode and
135 // BufferQueueProducer::setAsyncMode for more about original implementation.
136 ALOGW(
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800137 "BufferHubProducer::setAsyncMode: BufferHubQueue should always be "
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700138 "asynchronous. This call makes no effact.");
139 return NO_ERROR;
140 }
141 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800142}
143
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800144status_t BufferHubProducer::dequeueBuffer(
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700145 int* out_slot, sp<Fence>* out_fence, uint32_t width, uint32_t height,
Ian Elliotta2eb34c2017-07-18 11:05:49 -0600146 PixelFormat format, uint64_t usage, uint64_t* /*outBufferAge*/,
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700147 FrameEventHistoryDelta* /* out_timestamps */) {
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800148 ALOGV("dequeueBuffer: w=%u, h=%u, format=%d, usage=%" PRIu64, width, height,
149 format, usage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800150
151 status_t ret;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700152 std::unique_lock<std::mutex> lock(mutex_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800153
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700154 if (connected_api_ == kNoConnectedApi) {
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700155 ALOGE("dequeueBuffer: BufferQueue has no connected producer");
156 return NO_INIT;
157 }
158
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700159 const uint32_t kLayerCount = 1;
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800160 if (int32_t(queue_->capacity()) < max_dequeued_buffer_count_ + kDefaultUndequeuedBuffers) {
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700161 // Lazy allocation. When the capacity of |queue_| has not reached
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700162 // |max_dequeued_buffer_count_|, allocate new buffer.
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800163 // TODO(jwcai) To save memory, the really reasonable thing to do is to go
164 // over existing slots and find first existing one to dequeue.
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700165 ret = AllocateBuffer(width, height, kLayerCount, format, usage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800166 if (ret < 0)
167 return ret;
168 }
169
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800170 size_t slot = 0;
171 std::shared_ptr<dvr::BufferProducer> buffer_producer;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800172
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800173 for (size_t retry = 0; retry < dvr::BufferHubQueue::kMaxQueueCapacity;
174 retry++) {
Jiwen 'Steve' Caied654322017-03-13 17:04:43 -0700175 LocalHandle fence;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700176 auto buffer_status = queue_->Dequeue(dequeue_timeout_ms_, &slot, &fence);
Corey Tabakab7ca5de2017-05-08 18:55:02 -0700177 if (!buffer_status)
178 return NO_MEMORY;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800179
Corey Tabaka9d8bd092017-04-25 16:47:44 -0700180 buffer_producer = buffer_status.take();
Jiwen 'Steve' Caib8508212017-05-08 16:02:36 -0700181 if (!buffer_producer)
182 return NO_MEMORY;
Corey Tabaka9d8bd092017-04-25 16:47:44 -0700183
Corey Tabakacd52dd92017-04-07 18:03:57 -0700184 if (width == buffer_producer->width() &&
185 height == buffer_producer->height() &&
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800186 uint32_t(format) == buffer_producer->format()) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800187 // The producer queue returns a buffer producer matches the request.
188 break;
189 }
190
191 // Needs reallocation.
192 // TODO(jwcai) Consider use VLOG instead if we find this log is not useful.
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800193 ALOGI(
Corey Tabakacd52dd92017-04-07 18:03:57 -0700194 "dequeueBuffer: requested buffer (w=%u, h=%u, format=%u) is different "
195 "from the buffer returned at slot: %zu (w=%u, h=%u, format=%u). Need "
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800196 "re-allocattion.",
197 width, height, format, slot, buffer_producer->width(),
198 buffer_producer->height(), buffer_producer->format());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800199 // Mark the slot as reallocating, so that later we can set
200 // BUFFER_NEEDS_REALLOCATION when the buffer actually get dequeued.
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700201 buffers_[slot].mIsReallocating = true;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800202
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700203 // Remove the old buffer once the allocation before allocating its
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800204 // replacement.
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700205 RemoveBuffer(slot);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800206
207 // Allocate a new producer buffer with new buffer configs. Note that if
208 // there are already multiple buffers in the queue, the next one returned
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700209 // from |queue_->Dequeue| may not be the new buffer we just reallocated.
210 // Retry up to BufferHubQueue::kMaxQueueCapacity times.
211 ret = AllocateBuffer(width, height, kLayerCount, format, usage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800212 if (ret < 0)
213 return ret;
214 }
215
216 // With the BufferHub backed solution. Buffer slot returned from
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700217 // |queue_->Dequeue| is guaranteed to avaiable for producer's use.
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800218 // It's either in free state (if the buffer has never been used before) or
219 // in queued state (if the buffer has been dequeued and queued back to
220 // BufferHubQueue).
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700221 LOG_ALWAYS_FATAL_IF(
222 (!buffers_[slot].mBufferState.isFree() &&
223 !buffers_[slot].mBufferState.isQueued()),
224 "dequeueBuffer: slot %zu is not free or queued, actual state: %s.", slot,
225 buffers_[slot].mBufferState.string());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800226
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700227 buffers_[slot].mBufferState.freeQueued();
228 buffers_[slot].mBufferState.dequeue();
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800229 ALOGV("dequeueBuffer: slot=%zu", slot);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800230
231 // TODO(jwcai) Handle fence properly. |BufferHub| has full fence support, we
232 // just need to exopose that through |BufferHubQueue| once we need fence.
233 *out_fence = Fence::NO_FENCE;
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800234 *out_slot = int(slot);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800235 ret = NO_ERROR;
236
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700237 if (buffers_[slot].mIsReallocating) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800238 ret |= BUFFER_NEEDS_REALLOCATION;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700239 buffers_[slot].mIsReallocating = false;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800240 }
241
242 return ret;
243}
244
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800245status_t BufferHubProducer::detachBuffer(int /* slot */) {
246 ALOGE("BufferHubProducer::detachBuffer not implemented.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800247 return INVALID_OPERATION;
248}
249
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800250status_t BufferHubProducer::detachNextBuffer(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800251 sp<GraphicBuffer>* /* out_buffer */, sp<Fence>* /* out_fence */) {
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800252 ALOGE("BufferHubProducer::detachNextBuffer not implemented.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800253 return INVALID_OPERATION;
254}
255
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800256status_t BufferHubProducer::attachBuffer(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800257 int* /* out_slot */, const sp<GraphicBuffer>& /* buffer */) {
258 // With this BufferHub backed implementation, we assume (for now) all buffers
259 // are allocated and owned by the BufferHub. Thus the attempt of transfering
260 // ownership of a buffer to the buffer queue is intentionally unsupported.
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800261 LOG_ALWAYS_FATAL("BufferHubProducer::attachBuffer not supported.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800262 return INVALID_OPERATION;
263}
264
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800265status_t BufferHubProducer::queueBuffer(int slot, const QueueBufferInput& input,
266 QueueBufferOutput* output) {
267 ALOGV("queueBuffer: slot %d", slot);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800268
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700269 if (output == nullptr) {
270 return BAD_VALUE;
271 }
272
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800273 int64_t timestamp;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800274 bool is_auto_timestamp;
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700275 android_dataspace dataspace;
276 Rect crop(Rect::EMPTY_RECT);
277 int scaling_mode;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800278 uint32_t transform;
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700279 sp<Fence> fence;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800280
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700281 input.deflate(&timestamp, &is_auto_timestamp, &dataspace, &crop,
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800282 &scaling_mode, &transform, &fence);
283
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700284 // Check input scaling mode is valid.
285 switch (scaling_mode) {
286 case NATIVE_WINDOW_SCALING_MODE_FREEZE:
287 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
288 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
289 case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
290 break;
291 default:
292 ALOGE("queueBuffer: unknown scaling mode %d", scaling_mode);
293 return BAD_VALUE;
294 }
295
296 // Check input fence is valid.
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800297 if (fence == nullptr) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800298 ALOGE("queueBuffer: fence is NULL");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800299 return BAD_VALUE;
300 }
301
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700302 std::unique_lock<std::mutex> lock(mutex_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800303
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700304 if (connected_api_ == kNoConnectedApi) {
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700305 ALOGE("queueBuffer: BufferQueue has no connected producer");
306 return NO_INIT;
307 }
308
309 if (slot < 0 || slot >= max_buffer_count_) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800310 ALOGE("queueBuffer: slot index %d out of range [0, %d)", slot,
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700311 max_buffer_count_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800312 return BAD_VALUE;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700313 } else if (!buffers_[slot].mBufferState.isDequeued()) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800314 ALOGE("queueBuffer: slot %d is not owned by the producer (state = %s)",
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700315 slot, buffers_[slot].mBufferState.string());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800316 return BAD_VALUE;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700317 } else if ((!buffers_[slot].mRequestBufferCalled ||
318 buffers_[slot].mGraphicBuffer == nullptr)) {
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700319 ALOGE(
320 "queueBuffer: slot %d is not requested (mRequestBufferCalled=%d, "
321 "mGraphicBuffer=%p)",
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700322 slot, buffers_[slot].mRequestBufferCalled,
323 buffers_[slot].mGraphicBuffer.get());
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700324 return BAD_VALUE;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800325 }
326
327 // Post the buffer producer with timestamp in the metadata.
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700328 const auto& buffer_producer = buffers_[slot].mBufferProducer;
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700329
330 // Check input crop is not out of boundary of current buffer.
331 Rect buffer_rect(buffer_producer->width(), buffer_producer->height());
332 Rect cropped_rect(Rect::EMPTY_RECT);
333 crop.intersect(buffer_rect, &cropped_rect);
334 if (cropped_rect != crop) {
335 ALOGE("queueBuffer: slot %d has out-of-boundary crop.", slot);
336 return BAD_VALUE;
337 }
338
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800339 LocalHandle fence_fd(fence->isValid() ? fence->dup() : -1);
340
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700341 DvrNativeBufferMetadata meta_data;
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700342 meta_data.timestamp = timestamp;
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800343 meta_data.is_auto_timestamp = int32_t(is_auto_timestamp);
344 meta_data.dataspace = int32_t(dataspace);
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700345 meta_data.crop_left = crop.left;
346 meta_data.crop_top = crop.top;
347 meta_data.crop_right = crop.right;
348 meta_data.crop_bottom = crop.bottom;
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800349 meta_data.scaling_mode = int32_t(scaling_mode);
350 meta_data.transform = int32_t(transform);
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700351
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700352 buffer_producer->PostAsync(&meta_data, fence_fd);
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700353 buffers_[slot].mBufferState.queue();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800354
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700355 output->width = buffer_producer->width();
356 output->height = buffer_producer->height();
Corey Tabakacd52dd92017-04-07 18:03:57 -0700357 output->transformHint = 0; // default value, we don't use it yet.
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700358
359 // |numPendingBuffers| counts of the number of buffers that has been enqueued
360 // by the producer but not yet acquired by the consumer. Due to the nature
361 // of BufferHubQueue design, this is hard to trace from the producer's client
362 // side, but it's safe to assume it's zero.
363 output->numPendingBuffers = 0;
364
365 // Note that we are not setting nextFrameNumber here as it seems to be only
366 // used by surface flinger. See more at b/22802885, ag/791760.
367 output->nextFrameNumber = 0;
368
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800369 return NO_ERROR;
370}
371
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800372status_t BufferHubProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
373 ALOGV(__FUNCTION__);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800374
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700375 std::unique_lock<std::mutex> lock(mutex_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800376
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700377 if (connected_api_ == kNoConnectedApi) {
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700378 ALOGE("cancelBuffer: BufferQueue has no connected producer");
379 return NO_INIT;
380 }
381
382 if (slot < 0 || slot >= max_buffer_count_) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800383 ALOGE("cancelBuffer: slot index %d out of range [0, %d)", slot,
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700384 max_buffer_count_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800385 return BAD_VALUE;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700386 } else if (!buffers_[slot].mBufferState.isDequeued()) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800387 ALOGE("cancelBuffer: slot %d is not owned by the producer (state = %s)",
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700388 slot, buffers_[slot].mBufferState.string());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800389 return BAD_VALUE;
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700390 } else if (fence == nullptr) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800391 ALOGE("cancelBuffer: fence is NULL");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800392 return BAD_VALUE;
393 }
394
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700395 auto buffer_producer = buffers_[slot].mBufferProducer;
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800396 queue_->Enqueue(buffer_producer, size_t(slot), 0ULL);
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700397 buffers_[slot].mBufferState.cancel();
398 buffers_[slot].mFence = fence;
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800399 ALOGV("cancelBuffer: slot %d", slot);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800400
401 return NO_ERROR;
402}
403
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800404status_t BufferHubProducer::query(int what, int* out_value) {
405 ALOGV(__FUNCTION__);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800406
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700407 std::unique_lock<std::mutex> lock(mutex_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800408
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700409 if (out_value == nullptr) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800410 ALOGE("query: out_value was NULL");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800411 return BAD_VALUE;
412 }
413
414 int value = 0;
415 switch (what) {
416 case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700417 // TODO(b/36187402) This should be the maximum number of buffers that this
418 // producer queue's consumer can acquire. Set to be at least one. Need to
419 // find a way to set from the consumer side.
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700420 value = kDefaultUndequeuedBuffers;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800421 break;
422 case NATIVE_WINDOW_BUFFER_AGE:
423 value = 0;
424 break;
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700425 case NATIVE_WINDOW_WIDTH:
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800426 value = int32_t(queue_->default_width());
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700427 break;
428 case NATIVE_WINDOW_HEIGHT:
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800429 value = int32_t(queue_->default_height());
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700430 break;
431 case NATIVE_WINDOW_FORMAT:
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800432 value = int32_t(queue_->default_format());
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700433 break;
434 case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
435 // BufferHubQueue is always operating in async mode, thus semantically
436 // consumer can never be running behind. See BufferQueueCore.cpp core
437 // for more information about the original meaning of this flag.
438 value = 0;
439 break;
440 case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
441 // TODO(jwcai) This is currently not implement as we don't need
442 // IGraphicBufferConsumer parity.
443 value = 0;
444 break;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800445 case NATIVE_WINDOW_DEFAULT_DATASPACE:
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700446 // TODO(jwcai) Return the default value android::BufferQueue is using as
447 // there is no way dvr::ConsumerQueue can set it.
448 value = 0; // HAL_DATASPACE_UNKNOWN
449 break;
450 case NATIVE_WINDOW_STICKY_TRANSFORM:
451 // TODO(jwcai) Return the default value android::BufferQueue is using as
452 // there is no way dvr::ConsumerQueue can set it.
453 value = 0;
454 break;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700455 case NATIVE_WINDOW_CONSUMER_IS_PROTECTED:
456 // In Daydream's implementation, the consumer end (i.e. VR Compostior)
457 // knows how to handle protected buffers.
458 value = 1;
459 break;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800460 default:
461 return BAD_VALUE;
462 }
463
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800464 ALOGV("query: key=%d, v=%d", what, value);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800465 *out_value = value;
466 return NO_ERROR;
467}
468
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800469status_t BufferHubProducer::connect(const sp<IProducerListener>& /* listener */,
470 int api,
471 bool /* producer_controlled_by_app */,
472 QueueBufferOutput* output) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800473 // Consumer interaction are actually handled by buffer hub, and we need
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700474 // to maintain consumer operations here. We only need to perform basic input
475 // parameter checks here.
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800476 ALOGV(__FUNCTION__);
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700477
478 if (output == nullptr) {
479 return BAD_VALUE;
480 }
481
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700482 std::unique_lock<std::mutex> lock(mutex_);
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700483
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700484 if (connected_api_ != kNoConnectedApi) {
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700485 return BAD_VALUE;
486 }
487
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800488 if (!queue_->is_connected()) {
489 ALOGE(
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800490 "BufferHubProducer::connect: This BufferHubProducer is not "
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800491 "connected to bufferhud. Has it been taken out as a parcelable?");
492 return BAD_VALUE;
493 }
494
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700495 switch (api) {
496 case NATIVE_WINDOW_API_EGL:
497 case NATIVE_WINDOW_API_CPU:
498 case NATIVE_WINDOW_API_MEDIA:
499 case NATIVE_WINDOW_API_CAMERA:
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700500 connected_api_ = api;
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700501
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700502 output->width = queue_->default_width();
503 output->height = queue_->default_height();
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700504
505 // default values, we don't use them yet.
506 output->transformHint = 0;
507 output->numPendingBuffers = 0;
508 output->nextFrameNumber = 0;
509 output->bufferReplaced = false;
510
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700511 break;
512 default:
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800513 ALOGE("BufferHubProducer::connect: unknow API %d", api);
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700514 return BAD_VALUE;
515 }
516
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800517 return NO_ERROR;
518}
519
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800520status_t BufferHubProducer::disconnect(int api, DisconnectMode /*mode*/) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800521 // Consumer interaction are actually handled by buffer hub, and we need
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700522 // to maintain consumer operations here. We only need to perform basic input
523 // parameter checks here.
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800524 ALOGV(__FUNCTION__);
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700525
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700526 std::unique_lock<std::mutex> lock(mutex_);
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700527
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700528 if (kNoConnectedApi == connected_api_) {
Wonsik Kim3e198b22017-04-07 15:43:16 -0700529 return NO_INIT;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700530 } else if (api != connected_api_) {
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700531 return BAD_VALUE;
532 }
533
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700534 FreeAllBuffers();
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700535 connected_api_ = kNoConnectedApi;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800536 return NO_ERROR;
537}
538
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800539status_t BufferHubProducer::setSidebandStream(const sp<NativeHandle>& stream) {
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700540 if (stream != nullptr) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800541 // TODO(jwcai) Investigate how is is used, maybe use BufferHubBuffer's
542 // metadata.
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800543 ALOGE("SidebandStream is not currently supported.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800544 return INVALID_OPERATION;
545 }
546 return NO_ERROR;
547}
548
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800549void BufferHubProducer::allocateBuffers(uint32_t /* width */,
550 uint32_t /* height */,
551 PixelFormat /* format */,
552 uint64_t /* usage */) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800553 // TODO(jwcai) |allocateBuffers| aims to preallocate up to the maximum number
554 // of buffers permitted by the current BufferQueue configuration (aka
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700555 // |max_buffer_count_|).
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800556 ALOGE("BufferHubProducer::allocateBuffers not implemented.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800557}
558
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800559status_t BufferHubProducer::allowAllocation(bool /* allow */) {
560 ALOGE("BufferHubProducer::allowAllocation not implemented.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800561 return INVALID_OPERATION;
562}
563
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800564status_t BufferHubProducer::setGenerationNumber(uint32_t generation_number) {
565 ALOGV(__FUNCTION__);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800566
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700567 std::unique_lock<std::mutex> lock(mutex_);
568 generation_number_ = generation_number;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800569 return NO_ERROR;
570}
571
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800572String8 BufferHubProducer::getConsumerName() const {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800573 // BufferHub based implementation could have one to many producer/consumer
574 // relationship, thus |getConsumerName| from the producer side does not
575 // make any sense.
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800576 ALOGE("BufferHubProducer::getConsumerName not supported.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800577 return String8("BufferHubQueue::DummyConsumer");
578}
579
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800580status_t BufferHubProducer::setSharedBufferMode(bool shared_buffer_mode) {
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700581 if (shared_buffer_mode) {
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800582 ALOGE("BufferHubProducer::setSharedBufferMode(true) is not supported.");
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700583 // TODO(b/36373181) Front buffer mode for buffer hub queue as ANativeWindow.
584 return INVALID_OPERATION;
585 }
586 // Setting to default should just work as a no-op.
587 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800588}
589
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800590status_t BufferHubProducer::setAutoRefresh(bool auto_refresh) {
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700591 if (auto_refresh) {
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800592 ALOGE("BufferHubProducer::setAutoRefresh(true) is not supported.");
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700593 return INVALID_OPERATION;
594 }
595 // Setting to default should just work as a no-op.
596 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800597}
598
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800599status_t BufferHubProducer::setDequeueTimeout(nsecs_t timeout) {
600 ALOGV(__FUNCTION__);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800601
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700602 std::unique_lock<std::mutex> lock(mutex_);
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800603 dequeue_timeout_ms_ = int(timeout / (1000 * 1000));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800604 return NO_ERROR;
605}
606
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800607status_t BufferHubProducer::getLastQueuedBuffer(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800608 sp<GraphicBuffer>* /* out_buffer */, sp<Fence>* /* out_fence */,
609 float /*out_transform_matrix*/[16]) {
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800610 ALOGE("BufferHubProducer::getLastQueuedBuffer not implemented.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800611 return INVALID_OPERATION;
612}
613
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800614void BufferHubProducer::getFrameTimestamps(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800615 FrameEventHistoryDelta* /*outDelta*/) {
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800616 ALOGE("BufferHubProducer::getFrameTimestamps not implemented.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800617}
618
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800619status_t BufferHubProducer::getUniqueId(uint64_t* out_id) const {
620 ALOGV(__FUNCTION__);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800621
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700622 *out_id = unique_id_;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800623 return NO_ERROR;
624}
625
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800626status_t BufferHubProducer::getConsumerUsage(uint64_t* out_usage) const {
627 ALOGV(__FUNCTION__);
Chia-I Wue2786ea2017-08-07 10:36:08 -0700628
629 // same value as returned by querying NATIVE_WINDOW_CONSUMER_USAGE_BITS
630 *out_usage = 0;
631 return NO_ERROR;
632}
633
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800634status_t BufferHubProducer::TakeAsParcelable(
635 dvr::ProducerQueueParcelable* out_parcelable) {
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800636 if (!out_parcelable || out_parcelable->IsValid())
637 return BAD_VALUE;
638
639 if (connected_api_ != kNoConnectedApi) {
640 ALOGE(
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800641 "BufferHubProducer::TakeAsParcelable: BufferHubProducer has "
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800642 "connected client. Must disconnect first.");
643 return BAD_VALUE;
644 }
645
646 if (!queue_->is_connected()) {
647 ALOGE(
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800648 "BufferHubProducer::TakeAsParcelable: This BufferHubProducer "
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800649 "is not connected to bufferhud. Has it been taken out as a "
650 "parcelable?");
651 return BAD_VALUE;
652 }
653
654 auto status = queue_->TakeAsParcelable();
655 if (!status) {
656 ALOGE(
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800657 "BufferHubProducer::TakeAsParcelable: Failed to take out "
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800658 "ProducuerQueueParcelable from the producer queue, error: %s.",
659 status.GetErrorMessage().c_str());
660 return BAD_VALUE;
661 }
662
663 *out_parcelable = status.take();
664 return NO_ERROR;
665}
666
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800667status_t BufferHubProducer::AllocateBuffer(uint32_t width, uint32_t height,
668 uint32_t layer_count,
669 PixelFormat format, uint64_t usage) {
670 auto status = queue_->AllocateBuffer(width, height, layer_count,
671 uint32_t(format), usage);
Corey Tabakab7ca5de2017-05-08 18:55:02 -0700672 if (!status) {
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800673 ALOGE("BufferHubProducer::AllocateBuffer: Failed to allocate buffer: %s",
674 status.GetErrorMessage().c_str());
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700675 return NO_MEMORY;
676 }
677
Jiwen 'Steve' Cai8fa4e102017-05-24 23:16:54 -0700678 size_t slot = status.get();
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700679 auto buffer_producer = queue_->GetBuffer(slot);
680
681 LOG_ALWAYS_FATAL_IF(buffer_producer == nullptr,
682 "Failed to get buffer producer at slot: %zu", slot);
683
684 buffers_[slot].mBufferProducer = buffer_producer;
685
686 return NO_ERROR;
687}
688
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800689status_t BufferHubProducer::RemoveBuffer(size_t slot) {
Jiwen 'Steve' Caibb701db2017-05-23 11:15:33 -0700690 auto status = queue_->RemoveBuffer(slot);
Corey Tabakab7ca5de2017-05-08 18:55:02 -0700691 if (!status) {
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800692 ALOGE("BufferHubProducer::RemoveBuffer: Failed to remove buffer: %s",
Corey Tabakab7ca5de2017-05-08 18:55:02 -0700693 status.GetErrorMessage().c_str());
694 return INVALID_OPERATION;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700695 }
696
697 // Reset in memory objects related the the buffer.
698 buffers_[slot].mBufferProducer = nullptr;
699 buffers_[slot].mGraphicBuffer = nullptr;
700 buffers_[slot].mBufferState.detachProducer();
701 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800702}
703
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800704status_t BufferHubProducer::FreeAllBuffers() {
705 for (size_t slot = 0; slot < dvr::BufferHubQueue::kMaxQueueCapacity; slot++) {
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700706 // Reset in memory objects related the the buffer.
707 buffers_[slot].mGraphicBuffer = nullptr;
708 buffers_[slot].mBufferState.reset();
709 buffers_[slot].mRequestBufferCalled = false;
710 buffers_[slot].mBufferProducer = nullptr;
711 buffers_[slot].mFence = Fence::NO_FENCE;
712 }
713
714 auto status = queue_->FreeAllBuffers();
715 if (!status) {
716 ALOGE(
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800717 "BufferHubProducer::FreeAllBuffers: Failed to free all buffers on "
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700718 "the queue: %s",
719 status.GetErrorMessage().c_str());
720 }
721
722 if (queue_->capacity() != 0 || queue_->count() != 0) {
723 LOG_ALWAYS_FATAL(
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800724 "BufferHubProducer::FreeAllBuffers: Not all buffers are freed.");
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700725 }
726
727 return NO_ERROR;
728}
729
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800730} // namespace android