blob: c383f40355d4cf4d0c3c6dfd68dc446b571630be [file] [log] [blame]
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -08001/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080017#if defined(__clang__)
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Weverything"
20#endif
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080021
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080022// The following headers are included without checking every warning.
23// TODO(b/72172820): Remove the workaround once we have enforced -Weverything
24// in these headers and their dependencies.
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070025#include <dvr/dvr_api.h>
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080026#include <gui/BufferHubProducer.h>
27
28#if defined(__clang__)
29#pragma clang diagnostic pop
30#endif
31
Alex Vakulenko4fe60582017-02-02 11:35:59 -080032#include <inttypes.h>
33#include <log/log.h>
Mathias Agopian6a3c05b2017-04-27 20:06:55 -070034#include <system/window.h>
Alex Vakulenko4fe60582017-02-02 11:35:59 -080035
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080036namespace android {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080037
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -080038using namespace dvr;
39
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070040/* static */
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -080041sp<BufferHubProducer> BufferHubProducer::Create(const std::shared_ptr<ProducerQueue>& queue) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080042 if (queue->metadata_size() != sizeof(DvrNativeBufferMetadata)) {
43 ALOGE("BufferHubProducer::Create producer's metadata size is different "
44 "than the size of DvrNativeBufferMetadata");
45 return nullptr;
46 }
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070047
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080048 sp<BufferHubProducer> producer = new BufferHubProducer;
49 producer->queue_ = queue;
50 return producer;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070051}
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080052
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -080053/* static */
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -080054sp<BufferHubProducer> BufferHubProducer::Create(ProducerQueueParcelable parcelable) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080055 if (!parcelable.IsValid()) {
56 ALOGE("BufferHubProducer::Create: Invalid producer parcelable.");
57 return nullptr;
58 }
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -080059
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080060 sp<BufferHubProducer> producer = new BufferHubProducer;
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -080061 producer->queue_ = ProducerQueue::Import(parcelable.TakeChannelHandle());
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080062 return producer;
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -080063}
64
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080065status_t BufferHubProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080066 ALOGV("requestBuffer: slot=%d", slot);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080067
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080068 std::unique_lock<std::mutex> lock(mutex_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080069
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080070 if (connected_api_ == kNoConnectedApi) {
71 ALOGE("requestBuffer: BufferHubProducer has no connected producer");
72 return NO_INIT;
73 }
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -070074
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080075 if (slot < 0 || slot >= max_buffer_count_) {
76 ALOGE("requestBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
77 return BAD_VALUE;
78 } else if (!buffers_[slot].mBufferState.isDequeued()) {
79 ALOGE("requestBuffer: slot %d is not owned by the producer (state = %s)", slot,
80 buffers_[slot].mBufferState.string());
81 return BAD_VALUE;
82 } else if (buffers_[slot].mGraphicBuffer != nullptr) {
83 ALOGE("requestBuffer: slot %d is not empty.", slot);
84 return BAD_VALUE;
85 } else if (buffers_[slot].mBufferProducer == nullptr) {
86 ALOGE("requestBuffer: slot %d is not dequeued.", slot);
87 return BAD_VALUE;
88 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080089
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080090 const auto& buffer_producer = buffers_[slot].mBufferProducer;
91 sp<GraphicBuffer> graphic_buffer = buffer_producer->buffer()->buffer();
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -070092
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080093 buffers_[slot].mGraphicBuffer = graphic_buffer;
94 buffers_[slot].mRequestBufferCalled = true;
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -070095
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080096 *buf = graphic_buffer;
97 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080098}
99
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800100status_t BufferHubProducer::setMaxDequeuedBufferCount(int max_dequeued_buffers) {
101 ALOGV("setMaxDequeuedBufferCount: max_dequeued_buffers=%d", max_dequeued_buffers);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800102
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800103 std::unique_lock<std::mutex> lock(mutex_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800104
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800105 if (max_dequeued_buffers <= 0 ||
106 max_dequeued_buffers >
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -0800107 int(BufferHubQueue::kMaxQueueCapacity - kDefaultUndequeuedBuffers)) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800108 ALOGE("setMaxDequeuedBufferCount: %d out of range (0, %zu]", max_dequeued_buffers,
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -0800109 BufferHubQueue::kMaxQueueCapacity);
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800110 return BAD_VALUE;
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700111 }
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700112
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800113 // The new dequeued_buffers count should not be violated by the number
114 // of currently dequeued buffers.
115 int dequeued_count = 0;
116 for (const auto& buf : buffers_) {
117 if (buf.mBufferState.isDequeued()) {
118 dequeued_count++;
119 }
120 }
121 if (dequeued_count > max_dequeued_buffers) {
122 ALOGE("setMaxDequeuedBufferCount: the requested dequeued_buffers"
123 "count (%d) exceeds the current dequeued buffer count (%d)",
124 max_dequeued_buffers, dequeued_count);
125 return BAD_VALUE;
126 }
127
128 max_dequeued_buffer_count_ = max_dequeued_buffers;
129 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800130}
131
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800132status_t BufferHubProducer::setAsyncMode(bool async) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800133 if (async) {
134 // TODO(b/36724099) BufferHubQueue's consumer end always acquires the buffer
135 // automatically and behaves differently from IGraphicBufferConsumer. Thus,
136 // android::BufferQueue's async mode (a.k.a. allocating an additional buffer
137 // to prevent dequeueBuffer from being blocking) technically does not apply
138 // here.
139 //
140 // In Daydream, non-blocking producer side dequeue is guaranteed by careful
141 // buffer consumer implementations. In another word, BufferHubQueue based
142 // dequeueBuffer should never block whether setAsyncMode(true) is set or
143 // not.
144 //
145 // See: IGraphicBufferProducer::setAsyncMode and
146 // BufferQueueProducer::setAsyncMode for more about original implementation.
147 ALOGW("BufferHubProducer::setAsyncMode: BufferHubQueue should always be "
148 "asynchronous. This call makes no effact.");
149 return NO_ERROR;
150 }
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700151 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800152}
153
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800154status_t BufferHubProducer::dequeueBuffer(int* out_slot, sp<Fence>* out_fence, uint32_t width,
155 uint32_t height, PixelFormat format, uint64_t usage,
156 uint64_t* /*outBufferAge*/,
157 FrameEventHistoryDelta* /* out_timestamps */) {
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -0800158 ALOGW("dequeueBuffer: w=%u, h=%u, format=%d, usage=%" PRIu64, width, height, format, usage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800159
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800160 status_t ret;
161 std::unique_lock<std::mutex> lock(mutex_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800162
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800163 if (connected_api_ == kNoConnectedApi) {
164 ALOGE("dequeueBuffer: BufferQueue has no connected producer");
165 return NO_INIT;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800166 }
167
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800168 const uint32_t kLayerCount = 1;
169 if (int32_t(queue_->capacity()) < max_dequeued_buffer_count_ + kDefaultUndequeuedBuffers) {
170 // Lazy allocation. When the capacity of |queue_| has not reached
171 // |max_dequeued_buffer_count_|, allocate new buffer.
172 // TODO(jwcai) To save memory, the really reasonable thing to do is to go
173 // over existing slots and find first existing one to dequeue.
174 ret = AllocateBuffer(width, height, kLayerCount, format, usage);
175 if (ret < 0) return ret;
176 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800177
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800178 size_t slot = 0;
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -0800179 std::shared_ptr<BufferProducer> buffer_producer;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800180
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -0800181 for (size_t retry = 0; retry < BufferHubQueue::kMaxQueueCapacity; retry++) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800182 LocalHandle fence;
183 auto buffer_status = queue_->Dequeue(dequeue_timeout_ms_, &slot, &fence);
184 if (!buffer_status) return NO_MEMORY;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800185
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800186 buffer_producer = buffer_status.take();
187 if (!buffer_producer) return NO_MEMORY;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800188
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800189 if (width == buffer_producer->width() && height == buffer_producer->height() &&
190 uint32_t(format) == buffer_producer->format()) {
191 // The producer queue returns a buffer producer matches the request.
192 break;
193 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800194
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800195 // Needs reallocation.
196 // TODO(jwcai) Consider use VLOG instead if we find this log is not useful.
197 ALOGI("dequeueBuffer: requested buffer (w=%u, h=%u, format=%u) is different "
198 "from the buffer returned at slot: %zu (w=%u, h=%u, format=%u). Need "
199 "re-allocattion.",
200 width, height, format, slot, buffer_producer->width(), buffer_producer->height(),
201 buffer_producer->format());
202 // Mark the slot as reallocating, so that later we can set
203 // BUFFER_NEEDS_REALLOCATION when the buffer actually get dequeued.
204 buffers_[slot].mIsReallocating = true;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800205
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800206 // Remove the old buffer once the allocation before allocating its
207 // replacement.
208 RemoveBuffer(slot);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800209
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800210 // Allocate a new producer buffer with new buffer configs. Note that if
211 // there are already multiple buffers in the queue, the next one returned
212 // from |queue_->Dequeue| may not be the new buffer we just reallocated.
213 // Retry up to BufferHubQueue::kMaxQueueCapacity times.
214 ret = AllocateBuffer(width, height, kLayerCount, format, usage);
215 if (ret < 0) return ret;
216 }
217
218 // With the BufferHub backed solution. Buffer slot returned from
219 // |queue_->Dequeue| is guaranteed to avaiable for producer's use.
220 // It's either in free state (if the buffer has never been used before) or
221 // in queued state (if the buffer has been dequeued and queued back to
222 // BufferHubQueue).
223 LOG_ALWAYS_FATAL_IF((!buffers_[slot].mBufferState.isFree() &&
224 !buffers_[slot].mBufferState.isQueued()),
225 "dequeueBuffer: slot %zu is not free or queued, actual state: %s.", slot,
226 buffers_[slot].mBufferState.string());
227
228 buffers_[slot].mBufferState.freeQueued();
229 buffers_[slot].mBufferState.dequeue();
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -0800230 ALOGW("dequeueBuffer: slot=%zu", slot);
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800231
232 // TODO(jwcai) Handle fence properly. |BufferHub| has full fence support, we
233 // just need to exopose that through |BufferHubQueue| once we need fence.
234 *out_fence = Fence::NO_FENCE;
235 *out_slot = int(slot);
236 ret = NO_ERROR;
237
238 if (buffers_[slot].mIsReallocating) {
239 ret |= BUFFER_NEEDS_REALLOCATION;
240 buffers_[slot].mIsReallocating = false;
241 }
242
243 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800244}
245
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800246status_t BufferHubProducer::detachBuffer(int /* slot */) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800247 ALOGE("BufferHubProducer::detachBuffer not implemented.");
248 return INVALID_OPERATION;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800249}
250
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800251status_t BufferHubProducer::detachNextBuffer(sp<GraphicBuffer>* /* out_buffer */,
252 sp<Fence>* /* out_fence */) {
253 ALOGE("BufferHubProducer::detachNextBuffer not implemented.");
254 return INVALID_OPERATION;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800255}
256
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800257status_t BufferHubProducer::attachBuffer(int* /* out_slot */,
258 const sp<GraphicBuffer>& /* buffer */) {
259 // With this BufferHub backed implementation, we assume (for now) all buffers
260 // are allocated and owned by the BufferHub. Thus the attempt of transfering
261 // ownership of a buffer to the buffer queue is intentionally unsupported.
262 LOG_ALWAYS_FATAL("BufferHubProducer::attachBuffer not supported.");
263 return INVALID_OPERATION;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800264}
265
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800266status_t BufferHubProducer::queueBuffer(int slot, const QueueBufferInput& input,
267 QueueBufferOutput* output) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800268 ALOGV("queueBuffer: slot %d", slot);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800269
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800270 if (output == nullptr) {
271 return BAD_VALUE;
272 }
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700273
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800274 int64_t timestamp;
275 bool is_auto_timestamp;
276 android_dataspace dataspace;
277 Rect crop(Rect::EMPTY_RECT);
278 int scaling_mode;
279 uint32_t transform;
280 sp<Fence> fence;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800281
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800282 input.deflate(&timestamp, &is_auto_timestamp, &dataspace, &crop, &scaling_mode, &transform,
283 &fence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800284
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800285 // Check input scaling mode is valid.
286 switch (scaling_mode) {
287 case NATIVE_WINDOW_SCALING_MODE_FREEZE:
288 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
289 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
290 case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
291 break;
292 default:
293 ALOGE("queueBuffer: unknown scaling mode %d", scaling_mode);
294 return BAD_VALUE;
295 }
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700296
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800297 // Check input fence is valid.
298 if (fence == nullptr) {
299 ALOGE("queueBuffer: fence is NULL");
300 return BAD_VALUE;
301 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800302
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800303 std::unique_lock<std::mutex> lock(mutex_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800304
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800305 if (connected_api_ == kNoConnectedApi) {
306 ALOGE("queueBuffer: BufferQueue has no connected producer");
307 return NO_INIT;
308 }
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700309
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800310 if (slot < 0 || slot >= max_buffer_count_) {
311 ALOGE("queueBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
312 return BAD_VALUE;
313 } else if (!buffers_[slot].mBufferState.isDequeued()) {
314 ALOGE("queueBuffer: slot %d is not owned by the producer (state = %s)", slot,
315 buffers_[slot].mBufferState.string());
316 return BAD_VALUE;
317 } else if ((!buffers_[slot].mRequestBufferCalled || buffers_[slot].mGraphicBuffer == nullptr)) {
318 ALOGE("queueBuffer: slot %d is not requested (mRequestBufferCalled=%d, "
319 "mGraphicBuffer=%p)",
320 slot, buffers_[slot].mRequestBufferCalled, buffers_[slot].mGraphicBuffer.get());
321 return BAD_VALUE;
322 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800323
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800324 // Post the buffer producer with timestamp in the metadata.
325 const auto& buffer_producer = buffers_[slot].mBufferProducer;
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700326
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800327 // Check input crop is not out of boundary of current buffer.
328 Rect buffer_rect(buffer_producer->width(), buffer_producer->height());
329 Rect cropped_rect(Rect::EMPTY_RECT);
330 crop.intersect(buffer_rect, &cropped_rect);
331 if (cropped_rect != crop) {
332 ALOGE("queueBuffer: slot %d has out-of-boundary crop.", slot);
333 return BAD_VALUE;
334 }
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700335
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800336 LocalHandle fence_fd(fence->isValid() ? fence->dup() : -1);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800337
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800338 DvrNativeBufferMetadata meta_data;
339 meta_data.timestamp = timestamp;
340 meta_data.is_auto_timestamp = int32_t(is_auto_timestamp);
341 meta_data.dataspace = int32_t(dataspace);
342 meta_data.crop_left = crop.left;
343 meta_data.crop_top = crop.top;
344 meta_data.crop_right = crop.right;
345 meta_data.crop_bottom = crop.bottom;
346 meta_data.scaling_mode = int32_t(scaling_mode);
347 meta_data.transform = int32_t(transform);
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700348
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800349 buffer_producer->PostAsync(&meta_data, fence_fd);
350 buffers_[slot].mBufferState.queue();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800351
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800352 output->width = buffer_producer->width();
353 output->height = buffer_producer->height();
354 output->transformHint = 0; // default value, we don't use it yet.
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700355
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800356 // |numPendingBuffers| counts of the number of buffers that has been enqueued
357 // by the producer but not yet acquired by the consumer. Due to the nature
358 // of BufferHubQueue design, this is hard to trace from the producer's client
359 // side, but it's safe to assume it's zero.
360 output->numPendingBuffers = 0;
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700361
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800362 // Note that we are not setting nextFrameNumber here as it seems to be only
363 // used by surface flinger. See more at b/22802885, ag/791760.
364 output->nextFrameNumber = 0;
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700365
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800366 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800367}
368
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800369status_t BufferHubProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800370 ALOGV(__FUNCTION__);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800371
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800372 std::unique_lock<std::mutex> lock(mutex_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800373
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800374 if (connected_api_ == kNoConnectedApi) {
375 ALOGE("cancelBuffer: BufferQueue has no connected producer");
376 return NO_INIT;
377 }
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700378
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800379 if (slot < 0 || slot >= max_buffer_count_) {
380 ALOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
381 return BAD_VALUE;
382 } else if (!buffers_[slot].mBufferState.isDequeued()) {
383 ALOGE("cancelBuffer: slot %d is not owned by the producer (state = %s)", slot,
384 buffers_[slot].mBufferState.string());
385 return BAD_VALUE;
386 } else if (fence == nullptr) {
387 ALOGE("cancelBuffer: fence is NULL");
388 return BAD_VALUE;
389 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800390
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800391 auto buffer_producer = buffers_[slot].mBufferProducer;
392 queue_->Enqueue(buffer_producer, size_t(slot), 0ULL);
393 buffers_[slot].mBufferState.cancel();
394 buffers_[slot].mFence = fence;
395 ALOGV("cancelBuffer: slot %d", slot);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800396
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800397 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800398}
399
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800400status_t BufferHubProducer::query(int what, int* out_value) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800401 ALOGV(__FUNCTION__);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800402
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800403 std::unique_lock<std::mutex> lock(mutex_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800404
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800405 if (out_value == nullptr) {
406 ALOGE("query: out_value was NULL");
407 return BAD_VALUE;
408 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800409
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800410 int value = 0;
411 switch (what) {
412 case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
413 // TODO(b/36187402) This should be the maximum number of buffers that this
414 // producer queue's consumer can acquire. Set to be at least one. Need to
415 // find a way to set from the consumer side.
416 value = kDefaultUndequeuedBuffers;
417 break;
418 case NATIVE_WINDOW_BUFFER_AGE:
419 value = 0;
420 break;
421 case NATIVE_WINDOW_WIDTH:
422 value = int32_t(queue_->default_width());
423 break;
424 case NATIVE_WINDOW_HEIGHT:
425 value = int32_t(queue_->default_height());
426 break;
427 case NATIVE_WINDOW_FORMAT:
428 value = int32_t(queue_->default_format());
429 break;
430 case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
431 // BufferHubQueue is always operating in async mode, thus semantically
432 // consumer can never be running behind. See BufferQueueCore.cpp core
433 // for more information about the original meaning of this flag.
434 value = 0;
435 break;
436 case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
437 // TODO(jwcai) This is currently not implement as we don't need
438 // IGraphicBufferConsumer parity.
439 value = 0;
440 break;
441 case NATIVE_WINDOW_DEFAULT_DATASPACE:
442 // TODO(jwcai) Return the default value android::BufferQueue is using as
443 // there is no way dvr::ConsumerQueue can set it.
444 value = 0; // HAL_DATASPACE_UNKNOWN
445 break;
446 case NATIVE_WINDOW_STICKY_TRANSFORM:
447 // TODO(jwcai) Return the default value android::BufferQueue is using as
448 // there is no way dvr::ConsumerQueue can set it.
449 value = 0;
450 break;
451 case NATIVE_WINDOW_CONSUMER_IS_PROTECTED:
452 // In Daydream's implementation, the consumer end (i.e. VR Compostior)
453 // knows how to handle protected buffers.
454 value = 1;
455 break;
456 default:
457 return BAD_VALUE;
458 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800459
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800460 ALOGV("query: key=%d, v=%d", what, value);
461 *out_value = value;
462 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800463}
464
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800465status_t BufferHubProducer::connect(const sp<IProducerListener>& /* listener */, int api,
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800466 bool /* producer_controlled_by_app */,
467 QueueBufferOutput* output) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800468 // Consumer interaction are actually handled by buffer hub, and we need
469 // to maintain consumer operations here. We only need to perform basic input
470 // parameter checks here.
471 ALOGV(__FUNCTION__);
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700472
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800473 if (output == nullptr) {
474 return BAD_VALUE;
475 }
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700476
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800477 std::unique_lock<std::mutex> lock(mutex_);
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700478
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800479 if (connected_api_ != kNoConnectedApi) {
480 return BAD_VALUE;
481 }
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700482
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800483 if (!queue_->is_connected()) {
484 ALOGE("BufferHubProducer::connect: This BufferHubProducer is not "
485 "connected to bufferhud. Has it been taken out as a parcelable?");
486 return BAD_VALUE;
487 }
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800488
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800489 switch (api) {
490 case NATIVE_WINDOW_API_EGL:
491 case NATIVE_WINDOW_API_CPU:
492 case NATIVE_WINDOW_API_MEDIA:
493 case NATIVE_WINDOW_API_CAMERA:
494 connected_api_ = api;
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700495
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800496 output->width = queue_->default_width();
497 output->height = queue_->default_height();
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700498
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800499 // default values, we don't use them yet.
500 output->transformHint = 0;
501 output->numPendingBuffers = 0;
502 output->nextFrameNumber = 0;
503 output->bufferReplaced = false;
Jiwen 'Steve' Caicb4751c2017-04-14 17:56:55 -0700504
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800505 break;
506 default:
507 ALOGE("BufferHubProducer::connect: unknow API %d", api);
508 return BAD_VALUE;
509 }
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700510
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800511 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800512}
513
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800514status_t BufferHubProducer::disconnect(int api, DisconnectMode /*mode*/) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800515 // Consumer interaction are actually handled by buffer hub, and we need
516 // to maintain consumer operations here. We only need to perform basic input
517 // parameter checks here.
518 ALOGV(__FUNCTION__);
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700519
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800520 std::unique_lock<std::mutex> lock(mutex_);
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700521
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800522 if (kNoConnectedApi == connected_api_) {
523 return NO_INIT;
524 } else if (api != connected_api_) {
525 return BAD_VALUE;
526 }
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700527
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800528 FreeAllBuffers();
529 connected_api_ = kNoConnectedApi;
530 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800531}
532
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800533status_t BufferHubProducer::setSidebandStream(const sp<NativeHandle>& stream) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800534 if (stream != nullptr) {
535 // TODO(jwcai) Investigate how is is used, maybe use BufferHubBuffer's
536 // metadata.
537 ALOGE("SidebandStream is not currently supported.");
538 return INVALID_OPERATION;
539 }
540 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800541}
542
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800543void BufferHubProducer::allocateBuffers(uint32_t /* width */, uint32_t /* height */,
544 PixelFormat /* format */, uint64_t /* usage */) {
545 // TODO(jwcai) |allocateBuffers| aims to preallocate up to the maximum number
546 // of buffers permitted by the current BufferQueue configuration (aka
547 // |max_buffer_count_|).
548 ALOGE("BufferHubProducer::allocateBuffers not implemented.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800549}
550
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800551status_t BufferHubProducer::allowAllocation(bool /* allow */) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800552 ALOGE("BufferHubProducer::allowAllocation not implemented.");
553 return INVALID_OPERATION;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800554}
555
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800556status_t BufferHubProducer::setGenerationNumber(uint32_t generation_number) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800557 ALOGV(__FUNCTION__);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800558
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800559 std::unique_lock<std::mutex> lock(mutex_);
560 generation_number_ = generation_number;
561 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800562}
563
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800564String8 BufferHubProducer::getConsumerName() const {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800565 // BufferHub based implementation could have one to many producer/consumer
566 // relationship, thus |getConsumerName| from the producer side does not
567 // make any sense.
568 ALOGE("BufferHubProducer::getConsumerName not supported.");
569 return String8("BufferHubQueue::DummyConsumer");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800570}
571
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800572status_t BufferHubProducer::setSharedBufferMode(bool shared_buffer_mode) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800573 if (shared_buffer_mode) {
574 ALOGE("BufferHubProducer::setSharedBufferMode(true) is not supported.");
575 // TODO(b/36373181) Front buffer mode for buffer hub queue as ANativeWindow.
576 return INVALID_OPERATION;
577 }
578 // Setting to default should just work as a no-op.
579 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800580}
581
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800582status_t BufferHubProducer::setAutoRefresh(bool auto_refresh) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800583 if (auto_refresh) {
584 ALOGE("BufferHubProducer::setAutoRefresh(true) is not supported.");
585 return INVALID_OPERATION;
586 }
587 // Setting to default should just work as a no-op.
588 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800589}
590
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800591status_t BufferHubProducer::setDequeueTimeout(nsecs_t timeout) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800592 ALOGV(__FUNCTION__);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800593
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800594 std::unique_lock<std::mutex> lock(mutex_);
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -0800595 dequeue_timeout_ms_ = static_cast<int>(timeout / (1000 * 1000));
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800596 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800597}
598
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800599status_t BufferHubProducer::getLastQueuedBuffer(sp<GraphicBuffer>* /* out_buffer */,
600 sp<Fence>* /* out_fence */,
601 float /*out_transform_matrix*/[16]) {
602 ALOGE("BufferHubProducer::getLastQueuedBuffer not implemented.");
603 return INVALID_OPERATION;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800604}
605
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800606void BufferHubProducer::getFrameTimestamps(FrameEventHistoryDelta* /*outDelta*/) {
607 ALOGE("BufferHubProducer::getFrameTimestamps not implemented.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800608}
609
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800610status_t BufferHubProducer::getUniqueId(uint64_t* out_id) const {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800611 ALOGV(__FUNCTION__);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800612
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800613 *out_id = unique_id_;
614 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800615}
616
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800617status_t BufferHubProducer::getConsumerUsage(uint64_t* out_usage) const {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800618 ALOGV(__FUNCTION__);
Chia-I Wue2786ea2017-08-07 10:36:08 -0700619
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800620 // same value as returned by querying NATIVE_WINDOW_CONSUMER_USAGE_BITS
621 *out_usage = 0;
622 return NO_ERROR;
Chia-I Wue2786ea2017-08-07 10:36:08 -0700623}
624
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -0800625status_t BufferHubProducer::TakeAsParcelable(ProducerQueueParcelable* out_parcelable) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800626 if (!out_parcelable || out_parcelable->IsValid()) return BAD_VALUE;
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800627
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800628 if (connected_api_ != kNoConnectedApi) {
629 ALOGE("BufferHubProducer::TakeAsParcelable: BufferHubProducer has "
630 "connected client. Must disconnect first.");
631 return BAD_VALUE;
632 }
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800633
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800634 if (!queue_->is_connected()) {
635 ALOGE("BufferHubProducer::TakeAsParcelable: This BufferHubProducer "
636 "is not connected to bufferhud. Has it been taken out as a "
637 "parcelable?");
638 return BAD_VALUE;
639 }
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800640
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800641 auto status = queue_->TakeAsParcelable();
642 if (!status) {
643 ALOGE("BufferHubProducer::TakeAsParcelable: Failed to take out "
644 "ProducuerQueueParcelable from the producer queue, error: %s.",
645 status.GetErrorMessage().c_str());
646 return BAD_VALUE;
647 }
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800648
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800649 *out_parcelable = status.take();
650 return NO_ERROR;
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800651}
652
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800653status_t BufferHubProducer::AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count,
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800654 PixelFormat format, uint64_t usage) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800655 auto status = queue_->AllocateBuffer(width, height, layer_count, uint32_t(format), usage);
656 if (!status) {
657 ALOGE("BufferHubProducer::AllocateBuffer: Failed to allocate buffer: %s",
658 status.GetErrorMessage().c_str());
659 return NO_MEMORY;
660 }
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700661
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800662 size_t slot = status.get();
663 auto buffer_producer = queue_->GetBuffer(slot);
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700664
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800665 LOG_ALWAYS_FATAL_IF(buffer_producer == nullptr, "Failed to get buffer producer at slot: %zu",
666 slot);
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700667
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800668 buffers_[slot].mBufferProducer = buffer_producer;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700669
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800670 return NO_ERROR;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700671}
672
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800673status_t BufferHubProducer::RemoveBuffer(size_t slot) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800674 auto status = queue_->RemoveBuffer(slot);
675 if (!status) {
676 ALOGE("BufferHubProducer::RemoveBuffer: Failed to remove buffer: %s",
677 status.GetErrorMessage().c_str());
678 return INVALID_OPERATION;
679 }
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700680
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800681 // Reset in memory objects related the the buffer.
682 buffers_[slot].mBufferProducer = nullptr;
683 buffers_[slot].mGraphicBuffer = nullptr;
684 buffers_[slot].mBufferState.detachProducer();
685 return NO_ERROR;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800686}
687
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800688status_t BufferHubProducer::FreeAllBuffers() {
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -0800689 for (size_t slot = 0; slot < BufferHubQueue::kMaxQueueCapacity; slot++) {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800690 // Reset in memory objects related the the buffer.
691 buffers_[slot].mGraphicBuffer = nullptr;
692 buffers_[slot].mBufferState.reset();
693 buffers_[slot].mRequestBufferCalled = false;
694 buffers_[slot].mBufferProducer = nullptr;
695 buffers_[slot].mFence = Fence::NO_FENCE;
696 }
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700697
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800698 auto status = queue_->FreeAllBuffers();
699 if (!status) {
700 ALOGE("BufferHubProducer::FreeAllBuffers: Failed to free all buffers on "
701 "the queue: %s",
702 status.GetErrorMessage().c_str());
703 }
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700704
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800705 if (queue_->capacity() != 0 || queue_->count() != 0) {
706 LOG_ALWAYS_FATAL("BufferHubProducer::FreeAllBuffers: Not all buffers are freed.");
707 }
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700708
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800709 return NO_ERROR;
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700710}
711
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -0800712status_t BufferHubProducer::exportToParcel(Parcel* parcel) {
713 status_t res = TakeAsParcelable(&pending_producer_parcelable_);
714 if (res != NO_ERROR) return res;
715
716 if (!pending_producer_parcelable_.IsValid()) {
717 ALOGE("BufferHubProducer::exportToParcel: Invalid parcelable object.");
718 return BAD_VALUE;
719 }
720
721 res = parcel->writeUint32(USE_BUFFER_HUB);
722 if (res != NO_ERROR) {
723 ALOGE("BufferHubProducer::exportToParcel: Cannot write magic, res=%d.", res);
724 return res;
725 }
726
727 return pending_producer_parcelable_.writeToParcel(parcel);
728}
729
730IBinder* BufferHubProducer::onAsBinder() {
731 ALOGE("BufferHubProducer::onAsBinder: BufferHubProducer should never be used as an Binder "
732 "object.");
733 return nullptr;
734}
735
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800736} // namespace android