blob: b8a5d5c1fb53f545f3db52a5f6573c84fd2af38f [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
Pablo Ceballos88f69282016-02-11 18:01:49 -080029#include <binder/IPCThreadState.h>
30#include <binder/PermissionCache.h>
31#include <private/android_filesystem_config.h>
32
Dan Stoza289ade12014-02-28 11:17:17 -080033namespace android {
34
35BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
36 mCore(core),
37 mSlots(core->mSlots),
38 mConsumerName() {}
39
40BufferQueueConsumer::~BufferQueueConsumer() {}
41
42status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
43 nsecs_t expectedPresent) {
44 ATRACE_CALL();
45 Mutex::Autolock lock(mCore->mMutex);
46
47 // Check that the consumer doesn't currently have the maximum number of
48 // buffers acquired. We allow the max buffer count to be exceeded by one
49 // buffer so that the consumer can successfully set up the newly acquired
50 // buffer before releasing the old one.
51 int numAcquiredBuffers = 0;
Dan Stoza3e96f192014-03-03 10:16:19 -080052 for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
Dan Stoza289ade12014-02-28 11:17:17 -080053 if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) {
54 ++numAcquiredBuffers;
55 }
56 }
57 if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
58 BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)",
59 numAcquiredBuffers, mCore->mMaxAcquiredBufferCount);
60 return INVALID_OPERATION;
61 }
62
63 // Check if the queue is empty.
64 // In asynchronous mode the list is guaranteed to be one buffer deep,
65 // while in synchronous mode we use the oldest buffer.
66 if (mCore->mQueue.empty()) {
67 return NO_BUFFER_AVAILABLE;
68 }
69
70 BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
71
72 // If expectedPresent is specified, we may not want to return a buffer yet.
73 // If it's specified and there's more than one buffer queued, we may want
74 // to drop a buffer.
75 if (expectedPresent != 0) {
76 const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second
77
78 // The 'expectedPresent' argument indicates when the buffer is expected
79 // to be presented on-screen. If the buffer's desired present time is
80 // earlier (less) than expectedPresent -- meaning it will be displayed
81 // on time or possibly late if we show it as soon as possible -- we
82 // acquire and return it. If we don't want to display it until after the
83 // expectedPresent time, we return PRESENT_LATER without acquiring it.
84 //
85 // To be safe, we don't defer acquisition if expectedPresent is more
86 // than one second in the future beyond the desired present time
87 // (i.e., we'd be holding the buffer for a long time).
88 //
89 // NOTE: Code assumes monotonic time values from the system clock
90 // are positive.
91
92 // Start by checking to see if we can drop frames. We skip this check if
93 // the timestamps are being auto-generated by Surface. If the app isn't
94 // generating timestamps explicitly, it probably doesn't want frames to
95 // be discarded based on them.
96 while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) {
97 // If entry[1] is timely, drop entry[0] (and repeat). We apply an
98 // additional criterion here: we only drop the earlier buffer if our
99 // desiredPresent falls within +/- 1 second of the expected present.
100 // Otherwise, bogus desiredPresent times (e.g., 0 or a small
101 // relative timestamp), which normally mean "ignore the timestamp
102 // and acquire immediately", would cause us to drop frames.
103 //
104 // We may want to add an additional criterion: don't drop the
105 // earlier buffer if entry[1]'s fence hasn't signaled yet.
106 const BufferItem& bufferItem(mCore->mQueue[1]);
107 nsecs_t desiredPresent = bufferItem.mTimestamp;
108 if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC ||
109 desiredPresent > expectedPresent) {
110 // This buffer is set to display in the near future, or
111 // desiredPresent is garbage. Either way we don't want to drop
112 // the previous buffer just to get this on the screen sooner.
Mark Salyzyn8f515ce2014-06-09 14:32:04 -0700113 BQ_LOGV("acquireBuffer: nodrop desire=%" PRId64 " expect=%"
114 PRId64 " (%" PRId64 ") now=%" PRId64,
115 desiredPresent, expectedPresent,
Dan Stoza289ade12014-02-28 11:17:17 -0800116 desiredPresent - expectedPresent,
117 systemTime(CLOCK_MONOTONIC));
118 break;
119 }
120
Mark Salyzyn8f515ce2014-06-09 14:32:04 -0700121 BQ_LOGV("acquireBuffer: drop desire=%" PRId64 " expect=%" PRId64
122 " size=%zu",
Dan Stoza289ade12014-02-28 11:17:17 -0800123 desiredPresent, expectedPresent, mCore->mQueue.size());
124 if (mCore->stillTracking(front)) {
125 // Front buffer is still in mSlots, so mark the slot as free
126 mSlots[front->mSlot].mBufferState = BufferSlot::FREE;
Dan Stoza0de7ea72015-04-23 13:20:51 -0700127 mCore->mFreeBuffers.push_back(front->mSlot);
Dan Stoza289ade12014-02-28 11:17:17 -0800128 }
129 mCore->mQueue.erase(front);
130 front = mCore->mQueue.begin();
131 }
132
133 // See if the front buffer is due
134 nsecs_t desiredPresent = front->mTimestamp;
135 if (desiredPresent > expectedPresent &&
136 desiredPresent < expectedPresent + MAX_REASONABLE_NSEC) {
Mark Salyzyn8f515ce2014-06-09 14:32:04 -0700137 BQ_LOGV("acquireBuffer: defer desire=%" PRId64 " expect=%" PRId64
138 " (%" PRId64 ") now=%" PRId64,
139 desiredPresent, expectedPresent,
Dan Stoza289ade12014-02-28 11:17:17 -0800140 desiredPresent - expectedPresent,
141 systemTime(CLOCK_MONOTONIC));
142 return PRESENT_LATER;
143 }
144
Mark Salyzyn8f515ce2014-06-09 14:32:04 -0700145 BQ_LOGV("acquireBuffer: accept desire=%" PRId64 " expect=%" PRId64 " "
146 "(%" PRId64 ") now=%" PRId64, desiredPresent, expectedPresent,
Dan Stoza289ade12014-02-28 11:17:17 -0800147 desiredPresent - expectedPresent,
148 systemTime(CLOCK_MONOTONIC));
149 }
150
151 int slot = front->mSlot;
152 *outBuffer = *front;
153 ATRACE_BUFFER_INDEX(slot);
154
Mark Salyzyn8f515ce2014-06-09 14:32:04 -0700155 BQ_LOGV("acquireBuffer: acquiring { slot=%d/%" PRIu64 " buffer=%p }",
Dan Stoza289ade12014-02-28 11:17:17 -0800156 slot, front->mFrameNumber, front->mGraphicBuffer->handle);
157 // If the front buffer is still being tracked, update its slot state
158 if (mCore->stillTracking(front)) {
159 mSlots[slot].mAcquireCalled = true;
160 mSlots[slot].mNeedsCleanupOnRelease = false;
161 mSlots[slot].mBufferState = BufferSlot::ACQUIRED;
162 mSlots[slot].mFence = Fence::NO_FENCE;
163 }
164
165 // If the buffer has previously been acquired by the consumer, set
166 // mGraphicBuffer to NULL to avoid unnecessarily remapping this buffer
167 // on the consumer side
168 if (outBuffer->mAcquireCalled) {
169 outBuffer->mGraphicBuffer = NULL;
170 }
171
172 mCore->mQueue.erase(front);
Dan Stozaae3c3682014-04-18 15:43:35 -0700173
174 // We might have freed a slot while dropping old buffers, or the producer
175 // may be blocked waiting for the number of buffers in the queue to
176 // decrease.
Dan Stoza289ade12014-02-28 11:17:17 -0800177 mCore->mDequeueCondition.broadcast();
178
179 ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
180
Dan Stoza0de7ea72015-04-23 13:20:51 -0700181 mCore->validateConsistencyLocked();
182
Dan Stoza289ade12014-02-28 11:17:17 -0800183 return NO_ERROR;
184}
185
Dan Stoza9f3053d2014-03-06 15:14:33 -0800186status_t BufferQueueConsumer::detachBuffer(int slot) {
187 ATRACE_CALL();
188 ATRACE_BUFFER_INDEX(slot);
189 BQ_LOGV("detachBuffer(C): slot %d", slot);
190 Mutex::Autolock lock(mCore->mMutex);
191
192 if (mCore->mIsAbandoned) {
193 BQ_LOGE("detachBuffer(C): BufferQueue has been abandoned");
194 return NO_INIT;
195 }
196
197 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
198 BQ_LOGE("detachBuffer(C): slot index %d out of range [0, %d)",
199 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
200 return BAD_VALUE;
201 } else if (mSlots[slot].mBufferState != BufferSlot::ACQUIRED) {
202 BQ_LOGE("detachBuffer(C): slot %d is not owned by the consumer "
203 "(state = %d)", slot, mSlots[slot].mBufferState);
204 return BAD_VALUE;
205 }
206
207 mCore->freeBufferLocked(slot);
208 mCore->mDequeueCondition.broadcast();
Dan Stoza0de7ea72015-04-23 13:20:51 -0700209 mCore->validateConsistencyLocked();
Dan Stoza9f3053d2014-03-06 15:14:33 -0800210
211 return NO_ERROR;
212}
213
214status_t BufferQueueConsumer::attachBuffer(int* outSlot,
215 const sp<android::GraphicBuffer>& buffer) {
216 ATRACE_CALL();
217
218 if (outSlot == NULL) {
219 BQ_LOGE("attachBuffer(P): outSlot must not be NULL");
220 return BAD_VALUE;
221 } else if (buffer == NULL) {
222 BQ_LOGE("attachBuffer(P): cannot attach NULL buffer");
223 return BAD_VALUE;
224 }
225
226 Mutex::Autolock lock(mCore->mMutex);
227
Dan Stoza0de7ea72015-04-23 13:20:51 -0700228 // Make sure we don't have too many acquired buffers
Dan Stoza9f3053d2014-03-06 15:14:33 -0800229 int numAcquiredBuffers = 0;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800230 for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
231 if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) {
232 ++numAcquiredBuffers;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800233 }
234 }
235
236 if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
237 BQ_LOGE("attachBuffer(P): max acquired buffer count reached: %d "
238 "(max %d)", numAcquiredBuffers,
239 mCore->mMaxAcquiredBufferCount);
240 return INVALID_OPERATION;
241 }
Dan Stoza0de7ea72015-04-23 13:20:51 -0700242
243 // Find a free slot to put the buffer into
244 int found = BufferQueueCore::INVALID_BUFFER_SLOT;
245 if (!mCore->mFreeSlots.empty()) {
246 auto slot = mCore->mFreeSlots.begin();
247 found = *slot;
248 mCore->mFreeSlots.erase(slot);
249 } else if (!mCore->mFreeBuffers.empty()) {
250 found = mCore->mFreeBuffers.front();
251 mCore->mFreeBuffers.remove(found);
252 }
Dan Stoza9f3053d2014-03-06 15:14:33 -0800253 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
254 BQ_LOGE("attachBuffer(P): could not find free buffer slot");
255 return NO_MEMORY;
256 }
257
258 *outSlot = found;
259 ATRACE_BUFFER_INDEX(*outSlot);
260 BQ_LOGV("attachBuffer(C): returning slot %d", *outSlot);
261
262 mSlots[*outSlot].mGraphicBuffer = buffer;
263 mSlots[*outSlot].mBufferState = BufferSlot::ACQUIRED;
264 mSlots[*outSlot].mAttachedByConsumer = true;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800265 mSlots[*outSlot].mNeedsCleanupOnRelease = false;
266 mSlots[*outSlot].mFence = Fence::NO_FENCE;
267 mSlots[*outSlot].mFrameNumber = 0;
268
Dan Stoza99b18b42014-03-28 15:34:33 -0700269 // mAcquireCalled tells BufferQueue that it doesn't need to send a valid
270 // GraphicBuffer pointer on the next acquireBuffer call, which decreases
271 // Binder traffic by not un/flattening the GraphicBuffer. However, it
272 // requires that the consumer maintain a cached copy of the slot <--> buffer
273 // mappings, which is why the consumer doesn't need the valid pointer on
274 // acquire.
275 //
276 // The StreamSplitter is one of the primary users of the attach/detach
277 // logic, and while it is running, all buffers it acquires are immediately
278 // detached, and all buffers it eventually releases are ones that were
279 // attached (as opposed to having been obtained from acquireBuffer), so it
280 // doesn't make sense to maintain the slot/buffer mappings, which would
281 // become invalid for every buffer during detach/attach. By setting this to
282 // false, the valid GraphicBuffer pointer will always be sent with acquire
283 // for attached buffers.
284 mSlots[*outSlot].mAcquireCalled = false;
285
Dan Stoza0de7ea72015-04-23 13:20:51 -0700286 mCore->validateConsistencyLocked();
287
Dan Stoza9f3053d2014-03-06 15:14:33 -0800288 return NO_ERROR;
289}
290
Dan Stoza289ade12014-02-28 11:17:17 -0800291status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
292 const sp<Fence>& releaseFence, EGLDisplay eglDisplay,
293 EGLSyncKHR eglFence) {
294 ATRACE_CALL();
295 ATRACE_BUFFER_INDEX(slot);
296
Dan Stoza9f3053d2014-03-06 15:14:33 -0800297 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS ||
298 releaseFence == NULL) {
Dan Stoza289ade12014-02-28 11:17:17 -0800299 return BAD_VALUE;
300 }
301
Dan Stozad1c10362014-03-28 15:19:08 -0700302 sp<IProducerListener> listener;
303 { // Autolock scope
304 Mutex::Autolock lock(mCore->mMutex);
Dan Stoza289ade12014-02-28 11:17:17 -0800305
Dan Stozad1c10362014-03-28 15:19:08 -0700306 // If the frame number has changed because the buffer has been reallocated,
307 // we can ignore this releaseBuffer for the old buffer
308 if (frameNumber != mSlots[slot].mFrameNumber) {
309 return STALE_BUFFER_SLOT;
310 }
Dan Stoza289ade12014-02-28 11:17:17 -0800311
Dan Stozad1c10362014-03-28 15:19:08 -0700312 // Make sure this buffer hasn't been queued while acquired by the consumer
313 BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
314 while (current != mCore->mQueue.end()) {
315 if (current->mSlot == slot) {
316 BQ_LOGE("releaseBuffer: buffer slot %d pending release is "
317 "currently queued", slot);
318 return BAD_VALUE;
319 }
320 ++current;
321 }
322
323 if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
324 mSlots[slot].mEglDisplay = eglDisplay;
325 mSlots[slot].mEglFence = eglFence;
326 mSlots[slot].mFence = releaseFence;
327 mSlots[slot].mBufferState = BufferSlot::FREE;
Dan Stoza0de7ea72015-04-23 13:20:51 -0700328 mCore->mFreeBuffers.push_back(slot);
Dan Stozad1c10362014-03-28 15:19:08 -0700329 listener = mCore->mConnectedProducerListener;
330 BQ_LOGV("releaseBuffer: releasing slot %d", slot);
331 } else if (mSlots[slot].mNeedsCleanupOnRelease) {
332 BQ_LOGV("releaseBuffer: releasing a stale buffer slot %d "
333 "(state = %d)", slot, mSlots[slot].mBufferState);
334 mSlots[slot].mNeedsCleanupOnRelease = false;
335 return STALE_BUFFER_SLOT;
336 } else {
337 BQ_LOGV("releaseBuffer: attempted to release buffer slot %d "
338 "but its state was %d", slot, mSlots[slot].mBufferState);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800339 return BAD_VALUE;
Dan Stoza289ade12014-02-28 11:17:17 -0800340 }
Dan Stoza289ade12014-02-28 11:17:17 -0800341
Dan Stozad1c10362014-03-28 15:19:08 -0700342 mCore->mDequeueCondition.broadcast();
Dan Stoza0de7ea72015-04-23 13:20:51 -0700343 mCore->validateConsistencyLocked();
Dan Stozad1c10362014-03-28 15:19:08 -0700344 } // Autolock scope
Dan Stoza289ade12014-02-28 11:17:17 -0800345
Dan Stozad1c10362014-03-28 15:19:08 -0700346 // Call back without lock held
347 if (listener != NULL) {
348 listener->onBufferReleased();
349 }
Dan Stoza289ade12014-02-28 11:17:17 -0800350
351 return NO_ERROR;
352}
353
354status_t BufferQueueConsumer::connect(
355 const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
356 ATRACE_CALL();
357
358 if (consumerListener == NULL) {
359 BQ_LOGE("connect(C): consumerListener may not be NULL");
360 return BAD_VALUE;
361 }
362
363 BQ_LOGV("connect(C): controlledByApp=%s",
364 controlledByApp ? "true" : "false");
365
366 Mutex::Autolock lock(mCore->mMutex);
367
368 if (mCore->mIsAbandoned) {
369 BQ_LOGE("connect(C): BufferQueue has been abandoned");
370 return NO_INIT;
371 }
372
373 mCore->mConsumerListener = consumerListener;
374 mCore->mConsumerControlledByApp = controlledByApp;
375
376 return NO_ERROR;
377}
378
379status_t BufferQueueConsumer::disconnect() {
380 ATRACE_CALL();
381
382 BQ_LOGV("disconnect(C)");
383
384 Mutex::Autolock lock(mCore->mMutex);
385
386 if (mCore->mConsumerListener == NULL) {
387 BQ_LOGE("disconnect(C): no consumer is connected");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800388 return BAD_VALUE;
Dan Stoza289ade12014-02-28 11:17:17 -0800389 }
390
391 mCore->mIsAbandoned = true;
392 mCore->mConsumerListener = NULL;
393 mCore->mQueue.clear();
394 mCore->freeAllBuffersLocked();
395 mCore->mDequeueCondition.broadcast();
396 return NO_ERROR;
397}
398
Dan Stozafebd4f42014-04-09 16:14:51 -0700399status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) {
Dan Stoza289ade12014-02-28 11:17:17 -0800400 ATRACE_CALL();
401
402 if (outSlotMask == NULL) {
403 BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL");
404 return BAD_VALUE;
405 }
406
407 Mutex::Autolock lock(mCore->mMutex);
408
409 if (mCore->mIsAbandoned) {
410 BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned");
411 return NO_INIT;
412 }
413
Dan Stozafebd4f42014-04-09 16:14:51 -0700414 uint64_t mask = 0;
Dan Stoza3e96f192014-03-03 10:16:19 -0800415 for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
Dan Stoza289ade12014-02-28 11:17:17 -0800416 if (!mSlots[s].mAcquireCalled) {
Dan Stozafebd4f42014-04-09 16:14:51 -0700417 mask |= (1ULL << s);
Dan Stoza289ade12014-02-28 11:17:17 -0800418 }
419 }
420
421 // Remove from the mask queued buffers for which acquire has been called,
422 // since the consumer will not receive their buffer addresses and so must
423 // retain their cached information
424 BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
425 while (current != mCore->mQueue.end()) {
426 if (current->mAcquireCalled) {
Dan Stozafebd4f42014-04-09 16:14:51 -0700427 mask &= ~(1ULL << current->mSlot);
Dan Stoza289ade12014-02-28 11:17:17 -0800428 }
429 ++current;
430 }
431
Dan Stozafebd4f42014-04-09 16:14:51 -0700432 BQ_LOGV("getReleasedBuffers: returning mask %#" PRIx64, mask);
Dan Stoza289ade12014-02-28 11:17:17 -0800433 *outSlotMask = mask;
434 return NO_ERROR;
435}
436
437status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width,
438 uint32_t height) {
439 ATRACE_CALL();
440
441 if (width == 0 || height == 0) {
442 BQ_LOGV("setDefaultBufferSize: dimensions cannot be 0 (width=%u "
443 "height=%u)", width, height);
444 return BAD_VALUE;
445 }
446
447 BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height);
448
449 Mutex::Autolock lock(mCore->mMutex);
450 mCore->mDefaultWidth = width;
451 mCore->mDefaultHeight = height;
452 return NO_ERROR;
453}
454
455status_t BufferQueueConsumer::setDefaultMaxBufferCount(int bufferCount) {
456 ATRACE_CALL();
457 Mutex::Autolock lock(mCore->mMutex);
458 return mCore->setDefaultMaxBufferCountLocked(bufferCount);
459}
460
461status_t BufferQueueConsumer::disableAsyncBuffer() {
462 ATRACE_CALL();
463
464 Mutex::Autolock lock(mCore->mMutex);
465
466 if (mCore->mConsumerListener != NULL) {
467 BQ_LOGE("disableAsyncBuffer: consumer already connected");
468 return INVALID_OPERATION;
469 }
470
471 BQ_LOGV("disableAsyncBuffer");
472 mCore->mUseAsyncBuffer = false;
473 return NO_ERROR;
474}
475
476status_t BufferQueueConsumer::setMaxAcquiredBufferCount(
477 int maxAcquiredBuffers) {
478 ATRACE_CALL();
479
480 if (maxAcquiredBuffers < 1 ||
481 maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) {
482 BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d",
483 maxAcquiredBuffers);
484 return BAD_VALUE;
485 }
486
487 Mutex::Autolock lock(mCore->mMutex);
488
489 if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
490 BQ_LOGE("setMaxAcquiredBufferCount: producer is already connected");
491 return INVALID_OPERATION;
492 }
493
494 BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
495 mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
496 return NO_ERROR;
497}
498
499void BufferQueueConsumer::setConsumerName(const String8& name) {
500 ATRACE_CALL();
501 BQ_LOGV("setConsumerName: '%s'", name.string());
502 Mutex::Autolock lock(mCore->mMutex);
503 mCore->mConsumerName = name;
504 mConsumerName = name;
505}
506
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800507status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
Dan Stoza289ade12014-02-28 11:17:17 -0800508 ATRACE_CALL();
509 BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat);
510 Mutex::Autolock lock(mCore->mMutex);
511 mCore->mDefaultBufferFormat = defaultFormat;
512 return NO_ERROR;
513}
514
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800515status_t BufferQueueConsumer::setDefaultBufferDataSpace(
516 android_dataspace defaultDataSpace) {
517 ATRACE_CALL();
518 BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace);
519 Mutex::Autolock lock(mCore->mMutex);
520 mCore->mDefaultBufferDataSpace = defaultDataSpace;
521 return NO_ERROR;
522}
523
Dan Stoza289ade12014-02-28 11:17:17 -0800524status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) {
525 ATRACE_CALL();
526 BQ_LOGV("setConsumerUsageBits: %#x", usage);
527 Mutex::Autolock lock(mCore->mMutex);
528 mCore->mConsumerUsageBits = usage;
529 return NO_ERROR;
530}
531
532status_t BufferQueueConsumer::setTransformHint(uint32_t hint) {
533 ATRACE_CALL();
534 BQ_LOGV("setTransformHint: %#x", hint);
535 Mutex::Autolock lock(mCore->mMutex);
536 mCore->mTransformHint = hint;
537 return NO_ERROR;
538}
539
Jesse Hall399184a2014-03-03 15:42:54 -0800540sp<NativeHandle> BufferQueueConsumer::getSidebandStream() const {
541 return mCore->mSidebandStream;
542}
543
Dan Stoza289ade12014-02-28 11:17:17 -0800544void BufferQueueConsumer::dump(String8& result, const char* prefix) const {
Pablo Ceballos88f69282016-02-11 18:01:49 -0800545 const IPCThreadState* ipc = IPCThreadState::self();
546 const pid_t pid = ipc->getCallingPid();
547 const uid_t uid = ipc->getCallingUid();
548 if ((uid != AID_SHELL)
549 && !PermissionCache::checkPermission(String16(
550 "android.permission.DUMP"), pid, uid)) {
551 result.appendFormat("Permission Denial: can't dump BufferQueueConsumer "
552 "from pid=%d, uid=%d\n", pid, uid);
Pablo Ceballosd46695b2016-02-20 11:26:13 -0800553 android_errorWriteWithInfoLog(0x534e4554, "27046057", uid, NULL, 0);
Pablo Ceballos88f69282016-02-11 18:01:49 -0800554 } else {
555 mCore->dump(result, prefix);
556 }
Dan Stoza289ade12014-02-28 11:17:17 -0800557}
558
559} // namespace android