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