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#if DEBUG_ONLY_CODE
24#define VALIDATE_CONSISTENCY() do { mCore->validateConsistencyLocked(); } while (0)
25#else
26#define VALIDATE_CONSISTENCY()
27#endif
28
29#include <gui/BufferItem.h>
30#include <gui/BufferQueueConsumer.h>
31#include <gui/BufferQueueCore.h>
32#include <gui/IConsumerListener.h>
33#include <gui/IProducerListener.h>
34
35#include <binder/IPCThreadState.h>
36#include <binder/PermissionCache.h>
37#include <private/android_filesystem_config.h>
38
39namespace android {
40
41BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
42    mCore(core),
43    mSlots(core->mSlots),
44    mConsumerName() {}
45
46BufferQueueConsumer::~BufferQueueConsumer() {}
47
48status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
49        nsecs_t expectedPresent, uint64_t maxFrameNumber) {
50    ATRACE_CALL();
51
52    int numDroppedBuffers = 0;
53    sp<IProducerListener> listener;
54    {
55        Mutex::Autolock lock(mCore->mMutex);
56
57        // Check that the consumer doesn't currently have the maximum number of
58        // buffers acquired. We allow the max buffer count to be exceeded by one
59        // buffer so that the consumer can successfully set up the newly acquired
60        // buffer before releasing the old one.
61        int numAcquiredBuffers = 0;
62        for (int s : mCore->mActiveBuffers) {
63            if (mSlots[s].mBufferState.isAcquired()) {
64                ++numAcquiredBuffers;
65            }
66        }
67        if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
68            BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)",
69                    numAcquiredBuffers, mCore->mMaxAcquiredBufferCount);
70            return INVALID_OPERATION;
71        }
72
73        bool sharedBufferAvailable = mCore->mSharedBufferMode &&
74                mCore->mAutoRefresh && mCore->mSharedBufferSlot !=
75                BufferQueueCore::INVALID_BUFFER_SLOT;
76
77        // In asynchronous mode the list is guaranteed to be one buffer deep,
78        // while in synchronous mode we use the oldest buffer.
79        if (mCore->mQueue.empty() && !sharedBufferAvailable) {
80            return NO_BUFFER_AVAILABLE;
81        }
82
83        BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
84
85        // If expectedPresent is specified, we may not want to return a buffer yet.
86        // If it's specified and there's more than one buffer queued, we may want
87        // to drop a buffer.
88        // Skip this if we're in shared buffer mode and the queue is empty,
89        // since in that case we'll just return the shared buffer.
90        if (expectedPresent != 0 && !mCore->mQueue.empty()) {
91            const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second
92
93            // The 'expectedPresent' argument indicates when the buffer is expected
94            // to be presented on-screen. If the buffer's desired present time is
95            // earlier (less) than expectedPresent -- meaning it will be displayed
96            // on time or possibly late if we show it as soon as possible -- we
97            // acquire and return it. If we don't want to display it until after the
98            // expectedPresent time, we return PRESENT_LATER without acquiring it.
99            //
100            // To be safe, we don't defer acquisition if expectedPresent is more
101            // than one second in the future beyond the desired present time
102            // (i.e., we'd be holding the buffer for a long time).
103            //
104            // NOTE: Code assumes monotonic time values from the system clock
105            // are positive.
106
107            // Start by checking to see if we can drop frames. We skip this check if
108            // the timestamps are being auto-generated by Surface. If the app isn't
109            // generating timestamps explicitly, it probably doesn't want frames to
110            // be discarded based on them.
111            while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) {
112                const BufferItem& bufferItem(mCore->mQueue[1]);
113
114                // If dropping entry[0] would leave us with a buffer that the
115                // consumer is not yet ready for, don't drop it.
116                if (maxFrameNumber && bufferItem.mFrameNumber > maxFrameNumber) {
117                    break;
118                }
119
120                // If entry[1] is timely, drop entry[0] (and repeat). We apply an
121                // additional criterion here: we only drop the earlier buffer if our
122                // desiredPresent falls within +/- 1 second of the expected present.
123                // Otherwise, bogus desiredPresent times (e.g., 0 or a small
124                // relative timestamp), which normally mean "ignore the timestamp
125                // and acquire immediately", would cause us to drop frames.
126                //
127                // We may want to add an additional criterion: don't drop the
128                // earlier buffer if entry[1]'s fence hasn't signaled yet.
129                nsecs_t desiredPresent = bufferItem.mTimestamp;
130                if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC ||
131                        desiredPresent > expectedPresent) {
132                    // This buffer is set to display in the near future, or
133                    // desiredPresent is garbage. Either way we don't want to drop
134                    // the previous buffer just to get this on the screen sooner.
135                    BQ_LOGV("acquireBuffer: nodrop desire=%" PRId64 " expect=%"
136                            PRId64 " (%" PRId64 ") now=%" PRId64,
137                            desiredPresent, expectedPresent,
138                            desiredPresent - expectedPresent,
139                            systemTime(CLOCK_MONOTONIC));
140                    break;
141                }
142
143                BQ_LOGV("acquireBuffer: drop desire=%" PRId64 " expect=%" PRId64
144                        " size=%zu",
145                        desiredPresent, expectedPresent, mCore->mQueue.size());
146
147                if (!front->mIsStale) {
148                    // Front buffer is still in mSlots, so mark the slot as free
149                    mSlots[front->mSlot].mBufferState.freeQueued();
150
151                    // After leaving shared buffer mode, the shared buffer will
152                    // still be around. Mark it as no longer shared if this
153                    // operation causes it to be free.
154                    if (!mCore->mSharedBufferMode &&
155                            mSlots[front->mSlot].mBufferState.isFree()) {
156                        mSlots[front->mSlot].mBufferState.mShared = false;
157                    }
158
159                    // Don't put the shared buffer on the free list
160                    if (!mSlots[front->mSlot].mBufferState.isShared()) {
161                        mCore->mActiveBuffers.erase(front->mSlot);
162                        mCore->mFreeBuffers.push_back(front->mSlot);
163                    }
164
165                    listener = mCore->mConnectedProducerListener;
166                    ++numDroppedBuffers;
167                }
168
169                mCore->mQueue.erase(front);
170                front = mCore->mQueue.begin();
171            }
172
173            // See if the front buffer is ready to be acquired
174            nsecs_t desiredPresent = front->mTimestamp;
175            bool bufferIsDue = desiredPresent <= expectedPresent ||
176                    desiredPresent > expectedPresent + MAX_REASONABLE_NSEC;
177            bool consumerIsReady = maxFrameNumber > 0 ?
178                    front->mFrameNumber <= maxFrameNumber : true;
179            if (!bufferIsDue || !consumerIsReady) {
180                BQ_LOGV("acquireBuffer: defer desire=%" PRId64 " expect=%" PRId64
181                        " (%" PRId64 ") now=%" PRId64 " frame=%" PRIu64
182                        " consumer=%" PRIu64,
183                        desiredPresent, expectedPresent,
184                        desiredPresent - expectedPresent,
185                        systemTime(CLOCK_MONOTONIC),
186                        front->mFrameNumber, maxFrameNumber);
187                return PRESENT_LATER;
188            }
189
190            BQ_LOGV("acquireBuffer: accept desire=%" PRId64 " expect=%" PRId64 " "
191                    "(%" PRId64 ") now=%" PRId64, desiredPresent, expectedPresent,
192                    desiredPresent - expectedPresent,
193                    systemTime(CLOCK_MONOTONIC));
194        }
195
196        int slot = BufferQueueCore::INVALID_BUFFER_SLOT;
197
198        if (sharedBufferAvailable && mCore->mQueue.empty()) {
199            // make sure the buffer has finished allocating before acquiring it
200            mCore->waitWhileAllocatingLocked();
201
202            slot = mCore->mSharedBufferSlot;
203
204            // Recreate the BufferItem for the shared buffer from the data that
205            // was cached when it was last queued.
206            outBuffer->mGraphicBuffer = mSlots[slot].mGraphicBuffer;
207            outBuffer->mFence = Fence::NO_FENCE;
208            outBuffer->mFenceTime = FenceTime::NO_FENCE;
209            outBuffer->mCrop = mCore->mSharedBufferCache.crop;
210            outBuffer->mTransform = mCore->mSharedBufferCache.transform &
211                    ~static_cast<uint32_t>(
212                    NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
213            outBuffer->mScalingMode = mCore->mSharedBufferCache.scalingMode;
214            outBuffer->mDataSpace = mCore->mSharedBufferCache.dataspace;
215            outBuffer->mFrameNumber = mCore->mFrameCounter;
216            outBuffer->mSlot = slot;
217            outBuffer->mAcquireCalled = mSlots[slot].mAcquireCalled;
218            outBuffer->mTransformToDisplayInverse =
219                    (mCore->mSharedBufferCache.transform &
220                    NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
221            outBuffer->mSurfaceDamage = Region::INVALID_REGION;
222            outBuffer->mQueuedBuffer = false;
223            outBuffer->mIsStale = false;
224            outBuffer->mAutoRefresh = mCore->mSharedBufferMode &&
225                    mCore->mAutoRefresh;
226        } else {
227            slot = front->mSlot;
228            *outBuffer = *front;
229        }
230
231        ATRACE_BUFFER_INDEX(slot);
232
233        BQ_LOGV("acquireBuffer: acquiring { slot=%d/%" PRIu64 " buffer=%p }",
234                slot, outBuffer->mFrameNumber, outBuffer->mGraphicBuffer->handle);
235
236        if (!outBuffer->mIsStale) {
237            mSlots[slot].mAcquireCalled = true;
238            // Don't decrease the queue count if the BufferItem wasn't
239            // previously in the queue. This happens in shared buffer mode when
240            // the queue is empty and the BufferItem is created above.
241            if (mCore->mQueue.empty()) {
242                mSlots[slot].mBufferState.acquireNotInQueue();
243            } else {
244                mSlots[slot].mBufferState.acquire();
245            }
246            mSlots[slot].mFence = Fence::NO_FENCE;
247        }
248
249        // If the buffer has previously been acquired by the consumer, set
250        // mGraphicBuffer to NULL to avoid unnecessarily remapping this buffer
251        // on the consumer side
252        if (outBuffer->mAcquireCalled) {
253            outBuffer->mGraphicBuffer = NULL;
254        }
255
256        mCore->mQueue.erase(front);
257
258        // We might have freed a slot while dropping old buffers, or the producer
259        // may be blocked waiting for the number of buffers in the queue to
260        // decrease.
261        mCore->mDequeueCondition.broadcast();
262
263        ATRACE_INT(mCore->mConsumerName.string(),
264                static_cast<int32_t>(mCore->mQueue.size()));
265        mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size());
266
267        VALIDATE_CONSISTENCY();
268    }
269
270    if (listener != NULL) {
271        for (int i = 0; i < numDroppedBuffers; ++i) {
272            listener->onBufferReleased();
273        }
274    }
275
276    return NO_ERROR;
277}
278
279status_t BufferQueueConsumer::detachBuffer(int slot) {
280    ATRACE_CALL();
281    ATRACE_BUFFER_INDEX(slot);
282    BQ_LOGV("detachBuffer: slot %d", slot);
283    Mutex::Autolock lock(mCore->mMutex);
284
285    if (mCore->mIsAbandoned) {
286        BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
287        return NO_INIT;
288    }
289
290    if (mCore->mSharedBufferMode || slot == mCore->mSharedBufferSlot) {
291        BQ_LOGE("detachBuffer: detachBuffer not allowed in shared buffer mode");
292        return BAD_VALUE;
293    }
294
295    if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
296        BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
297                slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
298        return BAD_VALUE;
299    } else if (!mSlots[slot].mBufferState.isAcquired()) {
300        BQ_LOGE("detachBuffer: slot %d is not owned by the consumer "
301                "(state = %s)", slot, mSlots[slot].mBufferState.string());
302        return BAD_VALUE;
303    }
304
305    mSlots[slot].mBufferState.detachConsumer();
306    mCore->mActiveBuffers.erase(slot);
307    mCore->mFreeSlots.insert(slot);
308    mCore->clearBufferSlotLocked(slot);
309    mCore->mDequeueCondition.broadcast();
310    VALIDATE_CONSISTENCY();
311
312    return NO_ERROR;
313}
314
315status_t BufferQueueConsumer::attachBuffer(int* outSlot,
316        const sp<android::GraphicBuffer>& buffer) {
317    ATRACE_CALL();
318
319    if (outSlot == NULL) {
320        BQ_LOGE("attachBuffer: outSlot must not be NULL");
321        return BAD_VALUE;
322    } else if (buffer == NULL) {
323        BQ_LOGE("attachBuffer: cannot attach NULL buffer");
324        return BAD_VALUE;
325    }
326
327    Mutex::Autolock lock(mCore->mMutex);
328
329    if (mCore->mSharedBufferMode) {
330        BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
331        return BAD_VALUE;
332    }
333
334    // Make sure we don't have too many acquired buffers
335    int numAcquiredBuffers = 0;
336    for (int s : mCore->mActiveBuffers) {
337        if (mSlots[s].mBufferState.isAcquired()) {
338            ++numAcquiredBuffers;
339        }
340    }
341
342    if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
343        BQ_LOGE("attachBuffer: max acquired buffer count reached: %d "
344                "(max %d)", numAcquiredBuffers,
345                mCore->mMaxAcquiredBufferCount);
346        return INVALID_OPERATION;
347    }
348
349    if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
350        BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
351                "[queue %u]", buffer->getGenerationNumber(),
352                mCore->mGenerationNumber);
353        return BAD_VALUE;
354    }
355
356    // Find a free slot to put the buffer into
357    int found = BufferQueueCore::INVALID_BUFFER_SLOT;
358    if (!mCore->mFreeSlots.empty()) {
359        auto slot = mCore->mFreeSlots.begin();
360        found = *slot;
361        mCore->mFreeSlots.erase(slot);
362    } else if (!mCore->mFreeBuffers.empty()) {
363        found = mCore->mFreeBuffers.front();
364        mCore->mFreeBuffers.remove(found);
365    }
366    if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
367        BQ_LOGE("attachBuffer: could not find free buffer slot");
368        return NO_MEMORY;
369    }
370
371    mCore->mActiveBuffers.insert(found);
372    *outSlot = found;
373    ATRACE_BUFFER_INDEX(*outSlot);
374    BQ_LOGV("attachBuffer: returning slot %d", *outSlot);
375
376    mSlots[*outSlot].mGraphicBuffer = buffer;
377    mSlots[*outSlot].mBufferState.attachConsumer();
378    mSlots[*outSlot].mNeedsReallocation = true;
379    mSlots[*outSlot].mFence = Fence::NO_FENCE;
380    mSlots[*outSlot].mFrameNumber = 0;
381
382    // mAcquireCalled tells BufferQueue that it doesn't need to send a valid
383    // GraphicBuffer pointer on the next acquireBuffer call, which decreases
384    // Binder traffic by not un/flattening the GraphicBuffer. However, it
385    // requires that the consumer maintain a cached copy of the slot <--> buffer
386    // mappings, which is why the consumer doesn't need the valid pointer on
387    // acquire.
388    //
389    // The StreamSplitter is one of the primary users of the attach/detach
390    // logic, and while it is running, all buffers it acquires are immediately
391    // detached, and all buffers it eventually releases are ones that were
392    // attached (as opposed to having been obtained from acquireBuffer), so it
393    // doesn't make sense to maintain the slot/buffer mappings, which would
394    // become invalid for every buffer during detach/attach. By setting this to
395    // false, the valid GraphicBuffer pointer will always be sent with acquire
396    // for attached buffers.
397    mSlots[*outSlot].mAcquireCalled = false;
398
399    VALIDATE_CONSISTENCY();
400
401    return NO_ERROR;
402}
403
404status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
405        const sp<Fence>& releaseFence, EGLDisplay eglDisplay,
406        EGLSyncKHR eglFence) {
407    ATRACE_CALL();
408    ATRACE_BUFFER_INDEX(slot);
409
410    if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS ||
411            releaseFence == NULL) {
412        BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot,
413                releaseFence.get());
414        return BAD_VALUE;
415    }
416
417    sp<IProducerListener> listener;
418    { // Autolock scope
419        Mutex::Autolock lock(mCore->mMutex);
420
421        // If the frame number has changed because the buffer has been reallocated,
422        // we can ignore this releaseBuffer for the old buffer.
423        // Ignore this for the shared buffer where the frame number can easily
424        // get out of sync due to the buffer being queued and acquired at the
425        // same time.
426        if (frameNumber != mSlots[slot].mFrameNumber &&
427                !mSlots[slot].mBufferState.isShared()) {
428            return STALE_BUFFER_SLOT;
429        }
430
431        if (!mSlots[slot].mBufferState.isAcquired()) {
432            BQ_LOGE("releaseBuffer: attempted to release buffer slot %d "
433                    "but its state was %s", slot,
434                    mSlots[slot].mBufferState.string());
435            return BAD_VALUE;
436        }
437
438        mSlots[slot].mEglDisplay = eglDisplay;
439        mSlots[slot].mEglFence = eglFence;
440        mSlots[slot].mFence = releaseFence;
441        mSlots[slot].mBufferState.release();
442
443        // After leaving shared buffer mode, the shared buffer will
444        // still be around. Mark it as no longer shared if this
445        // operation causes it to be free.
446        if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
447            mSlots[slot].mBufferState.mShared = false;
448        }
449        // Don't put the shared buffer on the free list.
450        if (!mSlots[slot].mBufferState.isShared()) {
451            mCore->mActiveBuffers.erase(slot);
452            mCore->mFreeBuffers.push_back(slot);
453        }
454
455        listener = mCore->mConnectedProducerListener;
456        BQ_LOGV("releaseBuffer: releasing slot %d", slot);
457
458        mCore->mDequeueCondition.broadcast();
459        VALIDATE_CONSISTENCY();
460    } // Autolock scope
461
462    // Call back without lock held
463    if (listener != NULL) {
464        listener->onBufferReleased();
465    }
466
467    return NO_ERROR;
468}
469
470status_t BufferQueueConsumer::connect(
471        const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
472    ATRACE_CALL();
473
474    if (consumerListener == NULL) {
475        BQ_LOGE("connect: consumerListener may not be NULL");
476        return BAD_VALUE;
477    }
478
479    BQ_LOGV("connect: controlledByApp=%s",
480            controlledByApp ? "true" : "false");
481
482    Mutex::Autolock lock(mCore->mMutex);
483
484    if (mCore->mIsAbandoned) {
485        BQ_LOGE("connect: BufferQueue has been abandoned");
486        return NO_INIT;
487    }
488
489    mCore->mConsumerListener = consumerListener;
490    mCore->mConsumerControlledByApp = controlledByApp;
491
492    return NO_ERROR;
493}
494
495status_t BufferQueueConsumer::disconnect() {
496    ATRACE_CALL();
497
498    BQ_LOGV("disconnect");
499
500    Mutex::Autolock lock(mCore->mMutex);
501
502    if (mCore->mConsumerListener == NULL) {
503        BQ_LOGE("disconnect: no consumer is connected");
504        return BAD_VALUE;
505    }
506
507    mCore->mIsAbandoned = true;
508    mCore->mConsumerListener = NULL;
509    mCore->mQueue.clear();
510    mCore->freeAllBuffersLocked();
511    mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
512    mCore->mDequeueCondition.broadcast();
513    return NO_ERROR;
514}
515
516status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) {
517    ATRACE_CALL();
518
519    if (outSlotMask == NULL) {
520        BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL");
521        return BAD_VALUE;
522    }
523
524    Mutex::Autolock lock(mCore->mMutex);
525
526    if (mCore->mIsAbandoned) {
527        BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned");
528        return NO_INIT;
529    }
530
531    uint64_t mask = 0;
532    for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
533        if (!mSlots[s].mAcquireCalled) {
534            mask |= (1ULL << s);
535        }
536    }
537
538    // Remove from the mask queued buffers for which acquire has been called,
539    // since the consumer will not receive their buffer addresses and so must
540    // retain their cached information
541    BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
542    while (current != mCore->mQueue.end()) {
543        if (current->mAcquireCalled) {
544            mask &= ~(1ULL << current->mSlot);
545        }
546        ++current;
547    }
548
549    BQ_LOGV("getReleasedBuffers: returning mask %#" PRIx64, mask);
550    *outSlotMask = mask;
551    return NO_ERROR;
552}
553
554status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width,
555        uint32_t height) {
556    ATRACE_CALL();
557
558    if (width == 0 || height == 0) {
559        BQ_LOGV("setDefaultBufferSize: dimensions cannot be 0 (width=%u "
560                "height=%u)", width, height);
561        return BAD_VALUE;
562    }
563
564    BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height);
565
566    Mutex::Autolock lock(mCore->mMutex);
567    mCore->mDefaultWidth = width;
568    mCore->mDefaultHeight = height;
569    return NO_ERROR;
570}
571
572status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) {
573    ATRACE_CALL();
574
575    if (bufferCount < 1 || bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
576        BQ_LOGE("setMaxBufferCount: invalid count %d", bufferCount);
577        return BAD_VALUE;
578    }
579
580    Mutex::Autolock lock(mCore->mMutex);
581
582    if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
583        BQ_LOGE("setMaxBufferCount: producer is already connected");
584        return INVALID_OPERATION;
585    }
586
587    if (bufferCount < mCore->mMaxAcquiredBufferCount) {
588        BQ_LOGE("setMaxBufferCount: invalid buffer count (%d) less than"
589                "mMaxAcquiredBufferCount (%d)", bufferCount,
590                mCore->mMaxAcquiredBufferCount);
591        return BAD_VALUE;
592    }
593
594    int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
595            mCore->mDequeueBufferCannotBlock, bufferCount) -
596            mCore->getMaxBufferCountLocked();
597    if (!mCore->adjustAvailableSlotsLocked(delta)) {
598        BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number of "
599                "available slots. Delta = %d", delta);
600        return BAD_VALUE;
601    }
602
603    mCore->mMaxBufferCount = bufferCount;
604    return NO_ERROR;
605}
606
607status_t BufferQueueConsumer::setMaxAcquiredBufferCount(
608        int maxAcquiredBuffers) {
609    ATRACE_CALL();
610
611    if (maxAcquiredBuffers < 1 ||
612            maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) {
613        BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d",
614                maxAcquiredBuffers);
615        return BAD_VALUE;
616    }
617
618    sp<IConsumerListener> listener;
619    { // Autolock scope
620        Mutex::Autolock lock(mCore->mMutex);
621        mCore->waitWhileAllocatingLocked();
622
623        if (mCore->mIsAbandoned) {
624            BQ_LOGE("setMaxAcquiredBufferCount: consumer is abandoned");
625            return NO_INIT;
626        }
627
628        if (maxAcquiredBuffers == mCore->mMaxAcquiredBufferCount) {
629            return NO_ERROR;
630        }
631
632        // The new maxAcquiredBuffers count should not be violated by the number
633        // of currently acquired buffers
634        int acquiredCount = 0;
635        for (int slot : mCore->mActiveBuffers) {
636            if (mSlots[slot].mBufferState.isAcquired()) {
637                acquiredCount++;
638            }
639        }
640        if (acquiredCount > maxAcquiredBuffers) {
641            BQ_LOGE("setMaxAcquiredBufferCount: the requested maxAcquiredBuffer"
642                    "count (%d) exceeds the current acquired buffer count (%d)",
643                    maxAcquiredBuffers, acquiredCount);
644            return BAD_VALUE;
645        }
646
647        if ((maxAcquiredBuffers + mCore->mMaxDequeuedBufferCount +
648                (mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock ? 1 : 0))
649                > mCore->mMaxBufferCount) {
650            BQ_LOGE("setMaxAcquiredBufferCount: %d acquired buffers would "
651                    "exceed the maxBufferCount (%d) (maxDequeued %d async %d)",
652                    maxAcquiredBuffers, mCore->mMaxBufferCount,
653                    mCore->mMaxDequeuedBufferCount, mCore->mAsyncMode ||
654                    mCore->mDequeueBufferCannotBlock);
655            return BAD_VALUE;
656        }
657
658        int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount;
659        if (!mCore->adjustAvailableSlotsLocked(delta)) {
660            return BAD_VALUE;
661        }
662
663        BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
664        mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
665        VALIDATE_CONSISTENCY();
666        if (delta < 0) {
667            listener = mCore->mConsumerListener;
668        }
669    }
670    // Call back without lock held
671    if (listener != NULL) {
672        listener->onBuffersReleased();
673    }
674
675    return NO_ERROR;
676}
677
678status_t BufferQueueConsumer::setConsumerName(const String8& name) {
679    ATRACE_CALL();
680    BQ_LOGV("setConsumerName: '%s'", name.string());
681    Mutex::Autolock lock(mCore->mMutex);
682    mCore->mConsumerName = name;
683    mConsumerName = name;
684    return NO_ERROR;
685}
686
687status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
688    ATRACE_CALL();
689    BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat);
690    Mutex::Autolock lock(mCore->mMutex);
691    mCore->mDefaultBufferFormat = defaultFormat;
692    return NO_ERROR;
693}
694
695status_t BufferQueueConsumer::setDefaultBufferDataSpace(
696        android_dataspace defaultDataSpace) {
697    ATRACE_CALL();
698    BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace);
699    Mutex::Autolock lock(mCore->mMutex);
700    mCore->mDefaultBufferDataSpace = defaultDataSpace;
701    return NO_ERROR;
702}
703
704status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) {
705    ATRACE_CALL();
706    BQ_LOGV("setConsumerUsageBits: %#x", usage);
707    Mutex::Autolock lock(mCore->mMutex);
708    mCore->mConsumerUsageBits = usage;
709    return NO_ERROR;
710}
711
712status_t BufferQueueConsumer::setConsumerIsProtected(bool isProtected) {
713    ATRACE_CALL();
714    BQ_LOGV("setConsumerIsProtected: %s", isProtected ? "true" : "false");
715    Mutex::Autolock lock(mCore->mMutex);
716    mCore->mConsumerIsProtected = isProtected;
717    return NO_ERROR;
718}
719
720status_t BufferQueueConsumer::setTransformHint(uint32_t hint) {
721    ATRACE_CALL();
722    BQ_LOGV("setTransformHint: %#x", hint);
723    Mutex::Autolock lock(mCore->mMutex);
724    mCore->mTransformHint = hint;
725    return NO_ERROR;
726}
727
728status_t BufferQueueConsumer::getSidebandStream(sp<NativeHandle>* outStream) const {
729    Mutex::Autolock lock(mCore->mMutex);
730    *outStream = mCore->mSidebandStream;
731    return NO_ERROR;
732}
733
734status_t BufferQueueConsumer::getOccupancyHistory(bool forceFlush,
735        std::vector<OccupancyTracker::Segment>* outHistory) {
736    Mutex::Autolock lock(mCore->mMutex);
737    *outHistory = mCore->mOccupancyTracker.getSegmentHistory(forceFlush);
738    return NO_ERROR;
739}
740
741status_t BufferQueueConsumer::discardFreeBuffers() {
742    Mutex::Autolock lock(mCore->mMutex);
743    mCore->discardFreeBuffersLocked();
744    return NO_ERROR;
745}
746
747status_t BufferQueueConsumer::dumpState(const String8& prefix, String8* outResult) const {
748    const IPCThreadState* ipc = IPCThreadState::self();
749    const pid_t pid = ipc->getCallingPid();
750    const uid_t uid = ipc->getCallingUid();
751    if ((uid != AID_SHELL)
752            && !PermissionCache::checkPermission(String16(
753            "android.permission.DUMP"), pid, uid)) {
754        outResult->appendFormat("Permission Denial: can't dump BufferQueueConsumer "
755                "from pid=%d, uid=%d\n", pid, uid);
756        android_errorWriteWithInfoLog(0x534e4554, "27046057",
757                static_cast<int32_t>(uid), NULL, 0);
758        return PERMISSION_DENIED;
759    }
760
761    mCore->dumpState(prefix, outResult);
762    return NO_ERROR;
763}
764
765} // namespace android
766