blob: c7d5e003268a8ed5eab16709e075ce753f9e81c3 [file] [log] [blame]
Dan Stoza289ade12014-02-28 11:17:17 -08001/*
2 * Copyright 2014 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
Mark Salyzyn8f515ce2014-06-09 14:32:04 -070017#include <inttypes.h>
18
Dan Stoza3e96f192014-03-03 10:16:19 -080019#define LOG_TAG "BufferQueueConsumer"
20#define ATRACE_TAG ATRACE_TAG_GRAPHICS
21//#define LOG_NDEBUG 0
22
Dan Stoza289ade12014-02-28 11:17:17 -080023#include <gui/BufferItem.h>
24#include <gui/BufferQueueConsumer.h>
25#include <gui/BufferQueueCore.h>
26#include <gui/IConsumerListener.h>
Dan Stozad1c10362014-03-28 15:19:08 -070027#include <gui/IProducerListener.h>
Dan Stoza289ade12014-02-28 11:17:17 -080028
29namespace android {
30
31BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
32 mCore(core),
33 mSlots(core->mSlots),
34 mConsumerName() {}
35
36BufferQueueConsumer::~BufferQueueConsumer() {}
37
38status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
39 nsecs_t expectedPresent) {
40 ATRACE_CALL();
41 Mutex::Autolock lock(mCore->mMutex);
42
43 // Check that the consumer doesn't currently have the maximum number of
44 // buffers acquired. We allow the max buffer count to be exceeded by one
45 // buffer so that the consumer can successfully set up the newly acquired
46 // buffer before releasing the old one.
47 int numAcquiredBuffers = 0;
Dan Stoza3e96f192014-03-03 10:16:19 -080048 for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
Dan Stoza289ade12014-02-28 11:17:17 -080049 if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) {
50 ++numAcquiredBuffers;
51 }
52 }
53 if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
54 BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)",
55 numAcquiredBuffers, mCore->mMaxAcquiredBufferCount);
56 return INVALID_OPERATION;
57 }
58
59 // Check if the queue is empty.
60 // In asynchronous mode the list is guaranteed to be one buffer deep,
61 // while in synchronous mode we use the oldest buffer.
62 if (mCore->mQueue.empty()) {
63 return NO_BUFFER_AVAILABLE;
64 }
65
66 BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
67
68 // If expectedPresent is specified, we may not want to return a buffer yet.
69 // If it's specified and there's more than one buffer queued, we may want
70 // to drop a buffer.
71 if (expectedPresent != 0) {
72 const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second
73
74 // The 'expectedPresent' argument indicates when the buffer is expected
75 // to be presented on-screen. If the buffer's desired present time is
76 // earlier (less) than expectedPresent -- meaning it will be displayed
77 // on time or possibly late if we show it as soon as possible -- we
78 // acquire and return it. If we don't want to display it until after the
79 // expectedPresent time, we return PRESENT_LATER without acquiring it.
80 //
81 // To be safe, we don't defer acquisition if expectedPresent is more
82 // than one second in the future beyond the desired present time
83 // (i.e., we'd be holding the buffer for a long time).
84 //
85 // NOTE: Code assumes monotonic time values from the system clock
86 // are positive.
87
88 // Start by checking to see if we can drop frames. We skip this check if
89 // the timestamps are being auto-generated by Surface. If the app isn't
90 // generating timestamps explicitly, it probably doesn't want frames to
91 // be discarded based on them.
92 while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) {
93 // If entry[1] is timely, drop entry[0] (and repeat). We apply an
94 // additional criterion here: we only drop the earlier buffer if our
95 // desiredPresent falls within +/- 1 second of the expected present.
96 // Otherwise, bogus desiredPresent times (e.g., 0 or a small
97 // relative timestamp), which normally mean "ignore the timestamp
98 // and acquire immediately", would cause us to drop frames.
99 //
100 // We may want to add an additional criterion: don't drop the
101 // earlier buffer if entry[1]'s fence hasn't signaled yet.
102 const BufferItem& bufferItem(mCore->mQueue[1]);
103 nsecs_t desiredPresent = bufferItem.mTimestamp;
104 if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC ||
105 desiredPresent > expectedPresent) {
106 // This buffer is set to display in the near future, or
107 // desiredPresent is garbage. Either way we don't want to drop
108 // the previous buffer just to get this on the screen sooner.
Mark Salyzyn8f515ce2014-06-09 14:32:04 -0700109 BQ_LOGV("acquireBuffer: nodrop desire=%" PRId64 " expect=%"
110 PRId64 " (%" PRId64 ") now=%" PRId64,
111 desiredPresent, expectedPresent,
Dan Stoza289ade12014-02-28 11:17:17 -0800112 desiredPresent - expectedPresent,
113 systemTime(CLOCK_MONOTONIC));
114 break;
115 }
116
Mark Salyzyn8f515ce2014-06-09 14:32:04 -0700117 BQ_LOGV("acquireBuffer: drop desire=%" PRId64 " expect=%" PRId64
118 " size=%zu",
Dan Stoza289ade12014-02-28 11:17:17 -0800119 desiredPresent, expectedPresent, mCore->mQueue.size());
120 if (mCore->stillTracking(front)) {
121 // Front buffer is still in mSlots, so mark the slot as free
122 mSlots[front->mSlot].mBufferState = BufferSlot::FREE;
Dan Stoza0de7ea72015-04-23 13:20:51 -0700123 mCore->mFreeBuffers.push_back(front->mSlot);
Dan Stoza289ade12014-02-28 11:17:17 -0800124 }
125 mCore->mQueue.erase(front);
126 front = mCore->mQueue.begin();
127 }
128
129 // See if the front buffer is due
130 nsecs_t desiredPresent = front->mTimestamp;
131 if (desiredPresent > expectedPresent &&
132 desiredPresent < expectedPresent + MAX_REASONABLE_NSEC) {
Mark Salyzyn8f515ce2014-06-09 14:32:04 -0700133 BQ_LOGV("acquireBuffer: defer desire=%" PRId64 " expect=%" PRId64
134 " (%" PRId64 ") now=%" PRId64,
135 desiredPresent, expectedPresent,
Dan Stoza289ade12014-02-28 11:17:17 -0800136 desiredPresent - expectedPresent,
137 systemTime(CLOCK_MONOTONIC));
138 return PRESENT_LATER;
139 }
140
Mark Salyzyn8f515ce2014-06-09 14:32:04 -0700141 BQ_LOGV("acquireBuffer: accept desire=%" PRId64 " expect=%" PRId64 " "
142 "(%" PRId64 ") now=%" PRId64, desiredPresent, expectedPresent,
Dan Stoza289ade12014-02-28 11:17:17 -0800143 desiredPresent - expectedPresent,
144 systemTime(CLOCK_MONOTONIC));
145 }
146
147 int slot = front->mSlot;
148 *outBuffer = *front;
149 ATRACE_BUFFER_INDEX(slot);
150
Mark Salyzyn8f515ce2014-06-09 14:32:04 -0700151 BQ_LOGV("acquireBuffer: acquiring { slot=%d/%" PRIu64 " buffer=%p }",
Dan Stoza289ade12014-02-28 11:17:17 -0800152 slot, front->mFrameNumber, front->mGraphicBuffer->handle);
153 // If the front buffer is still being tracked, update its slot state
154 if (mCore->stillTracking(front)) {
155 mSlots[slot].mAcquireCalled = true;
156 mSlots[slot].mNeedsCleanupOnRelease = false;
157 mSlots[slot].mBufferState = BufferSlot::ACQUIRED;
158 mSlots[slot].mFence = Fence::NO_FENCE;
159 }
160
161 // If the buffer has previously been acquired by the consumer, set
162 // mGraphicBuffer to NULL to avoid unnecessarily remapping this buffer
163 // on the consumer side
164 if (outBuffer->mAcquireCalled) {
165 outBuffer->mGraphicBuffer = NULL;
166 }
167
168 mCore->mQueue.erase(front);
Dan Stozaae3c3682014-04-18 15:43:35 -0700169
170 // We might have freed a slot while dropping old buffers, or the producer
171 // may be blocked waiting for the number of buffers in the queue to
172 // decrease.
Dan Stoza289ade12014-02-28 11:17:17 -0800173 mCore->mDequeueCondition.broadcast();
174
175 ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
176
Dan Stoza0de7ea72015-04-23 13:20:51 -0700177 mCore->validateConsistencyLocked();
178
Dan Stoza289ade12014-02-28 11:17:17 -0800179 return NO_ERROR;
180}
181
Dan Stoza9f3053d2014-03-06 15:14:33 -0800182status_t BufferQueueConsumer::detachBuffer(int slot) {
183 ATRACE_CALL();
184 ATRACE_BUFFER_INDEX(slot);
185 BQ_LOGV("detachBuffer(C): slot %d", slot);
186 Mutex::Autolock lock(mCore->mMutex);
187
188 if (mCore->mIsAbandoned) {
189 BQ_LOGE("detachBuffer(C): BufferQueue has been abandoned");
190 return NO_INIT;
191 }
192
193 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
194 BQ_LOGE("detachBuffer(C): slot index %d out of range [0, %d)",
195 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
196 return BAD_VALUE;
197 } else if (mSlots[slot].mBufferState != BufferSlot::ACQUIRED) {
198 BQ_LOGE("detachBuffer(C): slot %d is not owned by the consumer "
199 "(state = %d)", slot, mSlots[slot].mBufferState);
200 return BAD_VALUE;
201 }
202
203 mCore->freeBufferLocked(slot);
204 mCore->mDequeueCondition.broadcast();
Dan Stoza0de7ea72015-04-23 13:20:51 -0700205 mCore->validateConsistencyLocked();
Dan Stoza9f3053d2014-03-06 15:14:33 -0800206
207 return NO_ERROR;
208}
209
210status_t BufferQueueConsumer::attachBuffer(int* outSlot,
211 const sp<android::GraphicBuffer>& buffer) {
212 ATRACE_CALL();
213
214 if (outSlot == NULL) {
215 BQ_LOGE("attachBuffer(P): outSlot must not be NULL");
216 return BAD_VALUE;
217 } else if (buffer == NULL) {
218 BQ_LOGE("attachBuffer(P): cannot attach NULL buffer");
219 return BAD_VALUE;
220 }
221
222 Mutex::Autolock lock(mCore->mMutex);
223
Dan Stoza0de7ea72015-04-23 13:20:51 -0700224 // Make sure we don't have too many acquired buffers
Dan Stoza9f3053d2014-03-06 15:14:33 -0800225 int numAcquiredBuffers = 0;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800226 for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
227 if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) {
228 ++numAcquiredBuffers;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800229 }
230 }
231
232 if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
233 BQ_LOGE("attachBuffer(P): max acquired buffer count reached: %d "
234 "(max %d)", numAcquiredBuffers,
235 mCore->mMaxAcquiredBufferCount);
236 return INVALID_OPERATION;
237 }
Dan Stoza0de7ea72015-04-23 13:20:51 -0700238
239 // Find a free slot to put the buffer into
240 int found = BufferQueueCore::INVALID_BUFFER_SLOT;
241 if (!mCore->mFreeSlots.empty()) {
242 auto slot = mCore->mFreeSlots.begin();
243 found = *slot;
244 mCore->mFreeSlots.erase(slot);
245 } else if (!mCore->mFreeBuffers.empty()) {
246 found = mCore->mFreeBuffers.front();
247 mCore->mFreeBuffers.remove(found);
248 }
Dan Stoza9f3053d2014-03-06 15:14:33 -0800249 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
250 BQ_LOGE("attachBuffer(P): could not find free buffer slot");
251 return NO_MEMORY;
252 }
253
254 *outSlot = found;
255 ATRACE_BUFFER_INDEX(*outSlot);
256 BQ_LOGV("attachBuffer(C): returning slot %d", *outSlot);
257
258 mSlots[*outSlot].mGraphicBuffer = buffer;
259 mSlots[*outSlot].mBufferState = BufferSlot::ACQUIRED;
260 mSlots[*outSlot].mAttachedByConsumer = true;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800261 mSlots[*outSlot].mNeedsCleanupOnRelease = false;
262 mSlots[*outSlot].mFence = Fence::NO_FENCE;
263 mSlots[*outSlot].mFrameNumber = 0;
264
Dan Stoza99b18b42014-03-28 15:34:33 -0700265 // mAcquireCalled tells BufferQueue that it doesn't need to send a valid
266 // GraphicBuffer pointer on the next acquireBuffer call, which decreases
267 // Binder traffic by not un/flattening the GraphicBuffer. However, it
268 // requires that the consumer maintain a cached copy of the slot <--> buffer
269 // mappings, which is why the consumer doesn't need the valid pointer on
270 // acquire.
271 //
272 // The StreamSplitter is one of the primary users of the attach/detach
273 // logic, and while it is running, all buffers it acquires are immediately
274 // detached, and all buffers it eventually releases are ones that were
275 // attached (as opposed to having been obtained from acquireBuffer), so it
276 // doesn't make sense to maintain the slot/buffer mappings, which would
277 // become invalid for every buffer during detach/attach. By setting this to
278 // false, the valid GraphicBuffer pointer will always be sent with acquire
279 // for attached buffers.
280 mSlots[*outSlot].mAcquireCalled = false;
281
Dan Stoza0de7ea72015-04-23 13:20:51 -0700282 mCore->validateConsistencyLocked();
283
Dan Stoza9f3053d2014-03-06 15:14:33 -0800284 return NO_ERROR;
285}
286
Dan Stoza289ade12014-02-28 11:17:17 -0800287status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
288 const sp<Fence>& releaseFence, EGLDisplay eglDisplay,
289 EGLSyncKHR eglFence) {
290 ATRACE_CALL();
291 ATRACE_BUFFER_INDEX(slot);
292
Dan Stoza9f3053d2014-03-06 15:14:33 -0800293 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS ||
294 releaseFence == NULL) {
Dan Stoza289ade12014-02-28 11:17:17 -0800295 return BAD_VALUE;
296 }
297
Dan Stozad1c10362014-03-28 15:19:08 -0700298 sp<IProducerListener> listener;
299 { // Autolock scope
300 Mutex::Autolock lock(mCore->mMutex);
Dan Stoza289ade12014-02-28 11:17:17 -0800301
Dan Stozad1c10362014-03-28 15:19:08 -0700302 // If the frame number has changed because the buffer has been reallocated,
303 // we can ignore this releaseBuffer for the old buffer
304 if (frameNumber != mSlots[slot].mFrameNumber) {
305 return STALE_BUFFER_SLOT;
306 }
Dan Stoza289ade12014-02-28 11:17:17 -0800307
Dan Stozad1c10362014-03-28 15:19:08 -0700308 // Make sure this buffer hasn't been queued while acquired by the consumer
309 BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
310 while (current != mCore->mQueue.end()) {
311 if (current->mSlot == slot) {
312 BQ_LOGE("releaseBuffer: buffer slot %d pending release is "
313 "currently queued", slot);
314 return BAD_VALUE;
315 }
316 ++current;
317 }
318
319 if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
320 mSlots[slot].mEglDisplay = eglDisplay;
321 mSlots[slot].mEglFence = eglFence;
322 mSlots[slot].mFence = releaseFence;
323 mSlots[slot].mBufferState = BufferSlot::FREE;
Dan Stoza0de7ea72015-04-23 13:20:51 -0700324 mCore->mFreeBuffers.push_back(slot);
Dan Stozad1c10362014-03-28 15:19:08 -0700325 listener = mCore->mConnectedProducerListener;
326 BQ_LOGV("releaseBuffer: releasing slot %d", slot);
327 } else if (mSlots[slot].mNeedsCleanupOnRelease) {
328 BQ_LOGV("releaseBuffer: releasing a stale buffer slot %d "
329 "(state = %d)", slot, mSlots[slot].mBufferState);
330 mSlots[slot].mNeedsCleanupOnRelease = false;
331 return STALE_BUFFER_SLOT;
332 } else {
333 BQ_LOGV("releaseBuffer: attempted to release buffer slot %d "
334 "but its state was %d", slot, mSlots[slot].mBufferState);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800335 return BAD_VALUE;
Dan Stoza289ade12014-02-28 11:17:17 -0800336 }
Dan Stoza289ade12014-02-28 11:17:17 -0800337
Dan Stozad1c10362014-03-28 15:19:08 -0700338 mCore->mDequeueCondition.broadcast();
Dan Stoza0de7ea72015-04-23 13:20:51 -0700339 mCore->validateConsistencyLocked();
Dan Stozad1c10362014-03-28 15:19:08 -0700340 } // Autolock scope
Dan Stoza289ade12014-02-28 11:17:17 -0800341
Dan Stozad1c10362014-03-28 15:19:08 -0700342 // Call back without lock held
343 if (listener != NULL) {
344 listener->onBufferReleased();
345 }
Dan Stoza289ade12014-02-28 11:17:17 -0800346
347 return NO_ERROR;
348}
349
350status_t BufferQueueConsumer::connect(
351 const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
352 ATRACE_CALL();
353
354 if (consumerListener == NULL) {
355 BQ_LOGE("connect(C): consumerListener may not be NULL");
356 return BAD_VALUE;
357 }
358
359 BQ_LOGV("connect(C): controlledByApp=%s",
360 controlledByApp ? "true" : "false");
361
362 Mutex::Autolock lock(mCore->mMutex);
363
364 if (mCore->mIsAbandoned) {
365 BQ_LOGE("connect(C): BufferQueue has been abandoned");
366 return NO_INIT;
367 }
368
369 mCore->mConsumerListener = consumerListener;
370 mCore->mConsumerControlledByApp = controlledByApp;
371
372 return NO_ERROR;
373}
374
375status_t BufferQueueConsumer::disconnect() {
376 ATRACE_CALL();
377
378 BQ_LOGV("disconnect(C)");
379
380 Mutex::Autolock lock(mCore->mMutex);
381
382 if (mCore->mConsumerListener == NULL) {
383 BQ_LOGE("disconnect(C): no consumer is connected");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800384 return BAD_VALUE;
Dan Stoza289ade12014-02-28 11:17:17 -0800385 }
386
387 mCore->mIsAbandoned = true;
388 mCore->mConsumerListener = NULL;
389 mCore->mQueue.clear();
390 mCore->freeAllBuffersLocked();
391 mCore->mDequeueCondition.broadcast();
392 return NO_ERROR;
393}
394
Dan Stozafebd4f42014-04-09 16:14:51 -0700395status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) {
Dan Stoza289ade12014-02-28 11:17:17 -0800396 ATRACE_CALL();
397
398 if (outSlotMask == NULL) {
399 BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL");
400 return BAD_VALUE;
401 }
402
403 Mutex::Autolock lock(mCore->mMutex);
404
405 if (mCore->mIsAbandoned) {
406 BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned");
407 return NO_INIT;
408 }
409
Dan Stozafebd4f42014-04-09 16:14:51 -0700410 uint64_t mask = 0;
Dan Stoza3e96f192014-03-03 10:16:19 -0800411 for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
Dan Stoza289ade12014-02-28 11:17:17 -0800412 if (!mSlots[s].mAcquireCalled) {
Dan Stozafebd4f42014-04-09 16:14:51 -0700413 mask |= (1ULL << s);
Dan Stoza289ade12014-02-28 11:17:17 -0800414 }
415 }
416
417 // Remove from the mask queued buffers for which acquire has been called,
418 // since the consumer will not receive their buffer addresses and so must
419 // retain their cached information
420 BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
421 while (current != mCore->mQueue.end()) {
422 if (current->mAcquireCalled) {
Dan Stozafebd4f42014-04-09 16:14:51 -0700423 mask &= ~(1ULL << current->mSlot);
Dan Stoza289ade12014-02-28 11:17:17 -0800424 }
425 ++current;
426 }
427
Dan Stozafebd4f42014-04-09 16:14:51 -0700428 BQ_LOGV("getReleasedBuffers: returning mask %#" PRIx64, mask);
Dan Stoza289ade12014-02-28 11:17:17 -0800429 *outSlotMask = mask;
430 return NO_ERROR;
431}
432
433status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width,
434 uint32_t height) {
435 ATRACE_CALL();
436
437 if (width == 0 || height == 0) {
438 BQ_LOGV("setDefaultBufferSize: dimensions cannot be 0 (width=%u "
439 "height=%u)", width, height);
440 return BAD_VALUE;
441 }
442
443 BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height);
444
445 Mutex::Autolock lock(mCore->mMutex);
446 mCore->mDefaultWidth = width;
447 mCore->mDefaultHeight = height;
448 return NO_ERROR;
449}
450
451status_t BufferQueueConsumer::setDefaultMaxBufferCount(int bufferCount) {
452 ATRACE_CALL();
453 Mutex::Autolock lock(mCore->mMutex);
454 return mCore->setDefaultMaxBufferCountLocked(bufferCount);
455}
456
457status_t BufferQueueConsumer::disableAsyncBuffer() {
458 ATRACE_CALL();
459
460 Mutex::Autolock lock(mCore->mMutex);
461
462 if (mCore->mConsumerListener != NULL) {
463 BQ_LOGE("disableAsyncBuffer: consumer already connected");
464 return INVALID_OPERATION;
465 }
466
467 BQ_LOGV("disableAsyncBuffer");
468 mCore->mUseAsyncBuffer = false;
469 return NO_ERROR;
470}
471
472status_t BufferQueueConsumer::setMaxAcquiredBufferCount(
473 int maxAcquiredBuffers) {
474 ATRACE_CALL();
475
476 if (maxAcquiredBuffers < 1 ||
477 maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) {
478 BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d",
479 maxAcquiredBuffers);
480 return BAD_VALUE;
481 }
482
483 Mutex::Autolock lock(mCore->mMutex);
484
485 if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
486 BQ_LOGE("setMaxAcquiredBufferCount: producer is already connected");
487 return INVALID_OPERATION;
488 }
489
490 BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
491 mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
492 return NO_ERROR;
493}
494
495void BufferQueueConsumer::setConsumerName(const String8& name) {
496 ATRACE_CALL();
497 BQ_LOGV("setConsumerName: '%s'", name.string());
498 Mutex::Autolock lock(mCore->mMutex);
499 mCore->mConsumerName = name;
500 mConsumerName = name;
501}
502
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800503status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
Dan Stoza289ade12014-02-28 11:17:17 -0800504 ATRACE_CALL();
505 BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat);
506 Mutex::Autolock lock(mCore->mMutex);
507 mCore->mDefaultBufferFormat = defaultFormat;
508 return NO_ERROR;
509}
510
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800511status_t BufferQueueConsumer::setDefaultBufferDataSpace(
512 android_dataspace defaultDataSpace) {
513 ATRACE_CALL();
514 BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace);
515 Mutex::Autolock lock(mCore->mMutex);
516 mCore->mDefaultBufferDataSpace = defaultDataSpace;
517 return NO_ERROR;
518}
519
Dan Stoza289ade12014-02-28 11:17:17 -0800520status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) {
521 ATRACE_CALL();
522 BQ_LOGV("setConsumerUsageBits: %#x", usage);
523 Mutex::Autolock lock(mCore->mMutex);
524 mCore->mConsumerUsageBits = usage;
525 return NO_ERROR;
526}
527
528status_t BufferQueueConsumer::setTransformHint(uint32_t hint) {
529 ATRACE_CALL();
530 BQ_LOGV("setTransformHint: %#x", hint);
531 Mutex::Autolock lock(mCore->mMutex);
532 mCore->mTransformHint = hint;
533 return NO_ERROR;
534}
535
Jesse Hall399184a2014-03-03 15:42:54 -0800536sp<NativeHandle> BufferQueueConsumer::getSidebandStream() const {
537 return mCore->mSidebandStream;
538}
539
Dan Stoza289ade12014-02-28 11:17:17 -0800540void BufferQueueConsumer::dump(String8& result, const char* prefix) const {
541 mCore->dump(result, prefix);
542}
543
544} // namespace android