• 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 "BufferQueueProducer"
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 #define EGL_EGLEXT_PROTOTYPES
30 
31 #include <gui/BufferItem.h>
32 #include <gui/BufferQueueCore.h>
33 #include <gui/BufferQueueProducer.h>
34 #include <gui/GLConsumer.h>
35 #include <gui/IConsumerListener.h>
36 #include <gui/IGraphicBufferAlloc.h>
37 #include <gui/IProducerListener.h>
38 
39 #include <utils/Log.h>
40 #include <utils/Trace.h>
41 
42 namespace android {
43 
BufferQueueProducer(const sp<BufferQueueCore> & core)44 BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) :
45     mCore(core),
46     mSlots(core->mSlots),
47     mConsumerName(),
48     mStickyTransform(0),
49     mLastQueueBufferFence(Fence::NO_FENCE),
50     mCallbackMutex(),
51     mNextCallbackTicket(0),
52     mCurrentCallbackTicket(0),
53     mCallbackCondition(),
54     mDequeueTimeout(-1) {}
55 
~BufferQueueProducer()56 BufferQueueProducer::~BufferQueueProducer() {}
57 
requestBuffer(int slot,sp<GraphicBuffer> * buf)58 status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
59     ATRACE_CALL();
60     BQ_LOGV("requestBuffer: slot %d", slot);
61     Mutex::Autolock lock(mCore->mMutex);
62 
63     if (mCore->mIsAbandoned) {
64         BQ_LOGE("requestBuffer: BufferQueue has been abandoned");
65         return NO_INIT;
66     }
67 
68     if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
69         BQ_LOGE("requestBuffer: BufferQueue has no connected producer");
70         return NO_INIT;
71     }
72 
73     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
74         BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)",
75                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
76         return BAD_VALUE;
77     } else if (!mSlots[slot].mBufferState.isDequeued()) {
78         BQ_LOGE("requestBuffer: slot %d is not owned by the producer "
79                 "(state = %s)", slot, mSlots[slot].mBufferState.string());
80         return BAD_VALUE;
81     }
82 
83     mSlots[slot].mRequestBufferCalled = true;
84     *buf = mSlots[slot].mGraphicBuffer;
85     return NO_ERROR;
86 }
87 
setMaxDequeuedBufferCount(int maxDequeuedBuffers)88 status_t BufferQueueProducer::setMaxDequeuedBufferCount(
89         int maxDequeuedBuffers) {
90     ATRACE_CALL();
91     BQ_LOGV("setMaxDequeuedBufferCount: maxDequeuedBuffers = %d",
92             maxDequeuedBuffers);
93 
94     sp<IConsumerListener> listener;
95     { // Autolock scope
96         Mutex::Autolock lock(mCore->mMutex);
97         mCore->waitWhileAllocatingLocked();
98 
99         if (mCore->mIsAbandoned) {
100             BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue has been "
101                     "abandoned");
102             return NO_INIT;
103         }
104 
105         if (maxDequeuedBuffers == mCore->mMaxDequeuedBufferCount) {
106             return NO_ERROR;
107         }
108 
109         // The new maxDequeuedBuffer count should not be violated by the number
110         // of currently dequeued buffers
111         int dequeuedCount = 0;
112         for (int s : mCore->mActiveBuffers) {
113             if (mSlots[s].mBufferState.isDequeued()) {
114                 dequeuedCount++;
115             }
116         }
117         if (dequeuedCount > maxDequeuedBuffers) {
118             BQ_LOGE("setMaxDequeuedBufferCount: the requested maxDequeuedBuffer"
119                     "count (%d) exceeds the current dequeued buffer count (%d)",
120                     maxDequeuedBuffers, dequeuedCount);
121             return BAD_VALUE;
122         }
123 
124         int bufferCount = mCore->getMinUndequeuedBufferCountLocked();
125         bufferCount += maxDequeuedBuffers;
126 
127         if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
128             BQ_LOGE("setMaxDequeuedBufferCount: bufferCount %d too large "
129                     "(max %d)", bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS);
130             return BAD_VALUE;
131         }
132 
133         const int minBufferSlots = mCore->getMinMaxBufferCountLocked();
134         if (bufferCount < minBufferSlots) {
135             BQ_LOGE("setMaxDequeuedBufferCount: requested buffer count %d is "
136                     "less than minimum %d", bufferCount, minBufferSlots);
137             return BAD_VALUE;
138         }
139 
140         if (bufferCount > mCore->mMaxBufferCount) {
141             BQ_LOGE("setMaxDequeuedBufferCount: %d dequeued buffers would "
142                     "exceed the maxBufferCount (%d) (maxAcquired %d async %d "
143                     "mDequeuedBufferCannotBlock %d)", maxDequeuedBuffers,
144                     mCore->mMaxBufferCount, mCore->mMaxAcquiredBufferCount,
145                     mCore->mAsyncMode, mCore->mDequeueBufferCannotBlock);
146             return BAD_VALUE;
147         }
148 
149         int delta = maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount;
150         if (!mCore->adjustAvailableSlotsLocked(delta)) {
151             return BAD_VALUE;
152         }
153         mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers;
154         VALIDATE_CONSISTENCY();
155         if (delta < 0) {
156             listener = mCore->mConsumerListener;
157         }
158         mCore->mDequeueCondition.broadcast();
159     } // Autolock scope
160 
161     // Call back without lock held
162     if (listener != NULL) {
163         listener->onBuffersReleased();
164     }
165 
166     return NO_ERROR;
167 }
168 
setAsyncMode(bool async)169 status_t BufferQueueProducer::setAsyncMode(bool async) {
170     ATRACE_CALL();
171     BQ_LOGV("setAsyncMode: async = %d", async);
172 
173     sp<IConsumerListener> listener;
174     { // Autolock scope
175         Mutex::Autolock lock(mCore->mMutex);
176         mCore->waitWhileAllocatingLocked();
177 
178         if (mCore->mIsAbandoned) {
179             BQ_LOGE("setAsyncMode: BufferQueue has been abandoned");
180             return NO_INIT;
181         }
182 
183         if (async == mCore->mAsyncMode) {
184             return NO_ERROR;
185         }
186 
187         if ((mCore->mMaxAcquiredBufferCount + mCore->mMaxDequeuedBufferCount +
188                 (async || mCore->mDequeueBufferCannotBlock ? 1 : 0)) >
189                 mCore->mMaxBufferCount) {
190             BQ_LOGE("setAsyncMode(%d): this call would cause the "
191                     "maxBufferCount (%d) to be exceeded (maxAcquired %d "
192                     "maxDequeued %d mDequeueBufferCannotBlock %d)", async,
193                     mCore->mMaxBufferCount, mCore->mMaxAcquiredBufferCount,
194                     mCore->mMaxDequeuedBufferCount,
195                     mCore->mDequeueBufferCannotBlock);
196             return BAD_VALUE;
197         }
198 
199         int delta = mCore->getMaxBufferCountLocked(async,
200                 mCore->mDequeueBufferCannotBlock, mCore->mMaxBufferCount)
201                 - mCore->getMaxBufferCountLocked();
202 
203         if (!mCore->adjustAvailableSlotsLocked(delta)) {
204             BQ_LOGE("setAsyncMode: BufferQueue failed to adjust the number of "
205                     "available slots. Delta = %d", delta);
206             return BAD_VALUE;
207         }
208         mCore->mAsyncMode = async;
209         VALIDATE_CONSISTENCY();
210         mCore->mDequeueCondition.broadcast();
211         if (delta < 0) {
212             listener = mCore->mConsumerListener;
213         }
214     } // Autolock scope
215 
216     // Call back without lock held
217     if (listener != NULL) {
218         listener->onBuffersReleased();
219     }
220     return NO_ERROR;
221 }
222 
getFreeBufferLocked() const223 int BufferQueueProducer::getFreeBufferLocked() const {
224     if (mCore->mFreeBuffers.empty()) {
225         return BufferQueueCore::INVALID_BUFFER_SLOT;
226     }
227     int slot = mCore->mFreeBuffers.front();
228     mCore->mFreeBuffers.pop_front();
229     return slot;
230 }
231 
getFreeSlotLocked() const232 int BufferQueueProducer::getFreeSlotLocked() const {
233     if (mCore->mFreeSlots.empty()) {
234         return BufferQueueCore::INVALID_BUFFER_SLOT;
235     }
236     int slot = *(mCore->mFreeSlots.begin());
237     mCore->mFreeSlots.erase(slot);
238     return slot;
239 }
240 
waitForFreeSlotThenRelock(FreeSlotCaller caller,int * found) const241 status_t BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller,
242         int* found) const {
243     auto callerString = (caller == FreeSlotCaller::Dequeue) ?
244             "dequeueBuffer" : "attachBuffer";
245     bool tryAgain = true;
246     while (tryAgain) {
247         if (mCore->mIsAbandoned) {
248             BQ_LOGE("%s: BufferQueue has been abandoned", callerString);
249             return NO_INIT;
250         }
251 
252         int dequeuedCount = 0;
253         int acquiredCount = 0;
254         for (int s : mCore->mActiveBuffers) {
255             if (mSlots[s].mBufferState.isDequeued()) {
256                 ++dequeuedCount;
257             }
258             if (mSlots[s].mBufferState.isAcquired()) {
259                 ++acquiredCount;
260             }
261         }
262 
263         // Producers are not allowed to dequeue more than
264         // mMaxDequeuedBufferCount buffers.
265         // This check is only done if a buffer has already been queued
266         if (mCore->mBufferHasBeenQueued &&
267                 dequeuedCount >= mCore->mMaxDequeuedBufferCount) {
268             BQ_LOGE("%s: attempting to exceed the max dequeued buffer count "
269                     "(%d)", callerString, mCore->mMaxDequeuedBufferCount);
270             return INVALID_OPERATION;
271         }
272 
273         *found = BufferQueueCore::INVALID_BUFFER_SLOT;
274 
275         // If we disconnect and reconnect quickly, we can be in a state where
276         // our slots are empty but we have many buffers in the queue. This can
277         // cause us to run out of memory if we outrun the consumer. Wait here if
278         // it looks like we have too many buffers queued up.
279         const int maxBufferCount = mCore->getMaxBufferCountLocked();
280         bool tooManyBuffers = mCore->mQueue.size()
281                             > static_cast<size_t>(maxBufferCount);
282         if (tooManyBuffers) {
283             BQ_LOGV("%s: queue size is %zu, waiting", callerString,
284                     mCore->mQueue.size());
285         } else {
286             // If in shared buffer mode and a shared buffer exists, always
287             // return it.
288             if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot !=
289                     BufferQueueCore::INVALID_BUFFER_SLOT) {
290                 *found = mCore->mSharedBufferSlot;
291             } else {
292                 if (caller == FreeSlotCaller::Dequeue) {
293                     // If we're calling this from dequeue, prefer free buffers
294                     int slot = getFreeBufferLocked();
295                     if (slot != BufferQueueCore::INVALID_BUFFER_SLOT) {
296                         *found = slot;
297                     } else if (mCore->mAllowAllocation) {
298                         *found = getFreeSlotLocked();
299                     }
300                 } else {
301                     // If we're calling this from attach, prefer free slots
302                     int slot = getFreeSlotLocked();
303                     if (slot != BufferQueueCore::INVALID_BUFFER_SLOT) {
304                         *found = slot;
305                     } else {
306                         *found = getFreeBufferLocked();
307                     }
308                 }
309             }
310         }
311 
312         // If no buffer is found, or if the queue has too many buffers
313         // outstanding, wait for a buffer to be acquired or released, or for the
314         // max buffer count to change.
315         tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) ||
316                    tooManyBuffers;
317         if (tryAgain) {
318             // Return an error if we're in non-blocking mode (producer and
319             // consumer are controlled by the application).
320             // However, the consumer is allowed to briefly acquire an extra
321             // buffer (which could cause us to have to wait here), which is
322             // okay, since it is only used to implement an atomic acquire +
323             // release (e.g., in GLConsumer::updateTexImage())
324             if ((mCore->mDequeueBufferCannotBlock || mCore->mAsyncMode) &&
325                     (acquiredCount <= mCore->mMaxAcquiredBufferCount)) {
326                 return WOULD_BLOCK;
327             }
328             if (mDequeueTimeout >= 0) {
329                 status_t result = mCore->mDequeueCondition.waitRelative(
330                         mCore->mMutex, mDequeueTimeout);
331                 if (result == TIMED_OUT) {
332                     return result;
333                 }
334             } else {
335                 mCore->mDequeueCondition.wait(mCore->mMutex);
336             }
337         }
338     } // while (tryAgain)
339 
340     return NO_ERROR;
341 }
342 
dequeueBuffer(int * outSlot,sp<android::Fence> * outFence,uint32_t width,uint32_t height,PixelFormat format,uint32_t usage)343 status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
344         sp<android::Fence> *outFence, uint32_t width, uint32_t height,
345         PixelFormat format, uint32_t usage) {
346     ATRACE_CALL();
347     { // Autolock scope
348         Mutex::Autolock lock(mCore->mMutex);
349         mConsumerName = mCore->mConsumerName;
350 
351         if (mCore->mIsAbandoned) {
352             BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
353             return NO_INIT;
354         }
355 
356         if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
357             BQ_LOGE("dequeueBuffer: BufferQueue has no connected producer");
358             return NO_INIT;
359         }
360     } // Autolock scope
361 
362     BQ_LOGV("dequeueBuffer: w=%u h=%u format=%#x, usage=%#x", width, height,
363             format, usage);
364 
365     if ((width && !height) || (!width && height)) {
366         BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height);
367         return BAD_VALUE;
368     }
369 
370     status_t returnFlags = NO_ERROR;
371     EGLDisplay eglDisplay = EGL_NO_DISPLAY;
372     EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
373     bool attachedByConsumer = false;
374 
375     { // Autolock scope
376         Mutex::Autolock lock(mCore->mMutex);
377         mCore->waitWhileAllocatingLocked();
378 
379         if (format == 0) {
380             format = mCore->mDefaultBufferFormat;
381         }
382 
383         // Enable the usage bits the consumer requested
384         usage |= mCore->mConsumerUsageBits;
385 
386         const bool useDefaultSize = !width && !height;
387         if (useDefaultSize) {
388             width = mCore->mDefaultWidth;
389             height = mCore->mDefaultHeight;
390         }
391 
392         int found = BufferItem::INVALID_BUFFER_SLOT;
393         while (found == BufferItem::INVALID_BUFFER_SLOT) {
394             status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue,
395                     &found);
396             if (status != NO_ERROR) {
397                 return status;
398             }
399 
400             // This should not happen
401             if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
402                 BQ_LOGE("dequeueBuffer: no available buffer slots");
403                 return -EBUSY;
404             }
405 
406             const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
407 
408             // If we are not allowed to allocate new buffers,
409             // waitForFreeSlotThenRelock must have returned a slot containing a
410             // buffer. If this buffer would require reallocation to meet the
411             // requested attributes, we free it and attempt to get another one.
412             if (!mCore->mAllowAllocation) {
413                 if (buffer->needsReallocation(width, height, format, usage)) {
414                     if (mCore->mSharedBufferSlot == found) {
415                         BQ_LOGE("dequeueBuffer: cannot re-allocate a shared"
416                                 "buffer");
417                         return BAD_VALUE;
418                     }
419                     mCore->mFreeSlots.insert(found);
420                     mCore->clearBufferSlotLocked(found);
421                     found = BufferItem::INVALID_BUFFER_SLOT;
422                     continue;
423                 }
424             }
425         }
426 
427         const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
428         if (mCore->mSharedBufferSlot == found &&
429                 buffer->needsReallocation(width,  height, format, usage)) {
430             BQ_LOGE("dequeueBuffer: cannot re-allocate a shared"
431                     "buffer");
432 
433             return BAD_VALUE;
434         }
435 
436         if (mCore->mSharedBufferSlot != found) {
437             mCore->mActiveBuffers.insert(found);
438         }
439         *outSlot = found;
440         ATRACE_BUFFER_INDEX(found);
441 
442         attachedByConsumer = mSlots[found].mNeedsReallocation;
443         mSlots[found].mNeedsReallocation = false;
444 
445         mSlots[found].mBufferState.dequeue();
446 
447         if ((buffer == NULL) ||
448                 buffer->needsReallocation(width, height, format, usage))
449         {
450             mSlots[found].mAcquireCalled = false;
451             mSlots[found].mGraphicBuffer = NULL;
452             mSlots[found].mRequestBufferCalled = false;
453             mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
454             mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
455             mSlots[found].mFence = Fence::NO_FENCE;
456             mCore->mBufferAge = 0;
457             mCore->mIsAllocating = true;
458 
459             returnFlags |= BUFFER_NEEDS_REALLOCATION;
460         } else {
461             // We add 1 because that will be the frame number when this buffer
462             // is queued
463             mCore->mBufferAge =
464                     mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber;
465         }
466 
467         BQ_LOGV("dequeueBuffer: setting buffer age to %" PRIu64,
468                 mCore->mBufferAge);
469 
470         if (CC_UNLIKELY(mSlots[found].mFence == NULL)) {
471             BQ_LOGE("dequeueBuffer: about to return a NULL fence - "
472                     "slot=%d w=%d h=%d format=%u",
473                     found, buffer->width, buffer->height, buffer->format);
474         }
475 
476         eglDisplay = mSlots[found].mEglDisplay;
477         eglFence = mSlots[found].mEglFence;
478         // Don't return a fence in shared buffer mode, except for the first
479         // frame.
480         *outFence = (mCore->mSharedBufferMode &&
481                 mCore->mSharedBufferSlot == found) ?
482                 Fence::NO_FENCE : mSlots[found].mFence;
483         mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
484         mSlots[found].mFence = Fence::NO_FENCE;
485 
486         // If shared buffer mode has just been enabled, cache the slot of the
487         // first buffer that is dequeued and mark it as the shared buffer.
488         if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot ==
489                 BufferQueueCore::INVALID_BUFFER_SLOT) {
490             mCore->mSharedBufferSlot = found;
491             mSlots[found].mBufferState.mShared = true;
492         }
493     } // Autolock scope
494 
495     if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
496         status_t error;
497         BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
498         sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
499                 width, height, format, usage,
500                 {mConsumerName.string(), mConsumerName.size()}, &error));
501         { // Autolock scope
502             Mutex::Autolock lock(mCore->mMutex);
503 
504             if (graphicBuffer != NULL && !mCore->mIsAbandoned) {
505                 graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
506                 mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
507             }
508 
509             mCore->mIsAllocating = false;
510             mCore->mIsAllocatingCondition.broadcast();
511 
512             if (graphicBuffer == NULL) {
513                 mCore->mFreeSlots.insert(*outSlot);
514                 mCore->clearBufferSlotLocked(*outSlot);
515                 BQ_LOGE("dequeueBuffer: createGraphicBuffer failed");
516                 return error;
517             }
518 
519             if (mCore->mIsAbandoned) {
520                 mCore->mFreeSlots.insert(*outSlot);
521                 mCore->clearBufferSlotLocked(*outSlot);
522                 BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
523                 return NO_INIT;
524             }
525 
526             VALIDATE_CONSISTENCY();
527         } // Autolock scope
528     }
529 
530     if (attachedByConsumer) {
531         returnFlags |= BUFFER_NEEDS_REALLOCATION;
532     }
533 
534     if (eglFence != EGL_NO_SYNC_KHR) {
535         EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0,
536                 1000000000);
537         // If something goes wrong, log the error, but return the buffer without
538         // synchronizing access to it. It's too late at this point to abort the
539         // dequeue operation.
540         if (result == EGL_FALSE) {
541             BQ_LOGE("dequeueBuffer: error %#x waiting for fence",
542                     eglGetError());
543         } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
544             BQ_LOGE("dequeueBuffer: timeout waiting for fence");
545         }
546         eglDestroySyncKHR(eglDisplay, eglFence);
547     }
548 
549     BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x",
550             *outSlot,
551             mSlots[*outSlot].mFrameNumber,
552             mSlots[*outSlot].mGraphicBuffer->handle, returnFlags);
553 
554     return returnFlags;
555 }
556 
detachBuffer(int slot)557 status_t BufferQueueProducer::detachBuffer(int slot) {
558     ATRACE_CALL();
559     ATRACE_BUFFER_INDEX(slot);
560     BQ_LOGV("detachBuffer: slot %d", slot);
561 
562     sp<IConsumerListener> listener;
563     {
564         Mutex::Autolock lock(mCore->mMutex);
565 
566         if (mCore->mIsAbandoned) {
567             BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
568             return NO_INIT;
569         }
570 
571         if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
572             BQ_LOGE("detachBuffer: BufferQueue has no connected producer");
573             return NO_INIT;
574         }
575 
576         if (mCore->mSharedBufferMode || mCore->mSharedBufferSlot == slot) {
577             BQ_LOGE("detachBuffer: cannot detach a buffer in shared buffer mode");
578             return BAD_VALUE;
579         }
580 
581         if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
582             BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
583                     slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
584             return BAD_VALUE;
585         } else if (!mSlots[slot].mBufferState.isDequeued()) {
586             BQ_LOGE("detachBuffer: slot %d is not owned by the producer "
587                     "(state = %s)", slot, mSlots[slot].mBufferState.string());
588             return BAD_VALUE;
589         } else if (!mSlots[slot].mRequestBufferCalled) {
590             BQ_LOGE("detachBuffer: buffer in slot %d has not been requested",
591                     slot);
592             return BAD_VALUE;
593         }
594 
595         mSlots[slot].mBufferState.detachProducer();
596         mCore->mActiveBuffers.erase(slot);
597         mCore->mFreeSlots.insert(slot);
598         mCore->clearBufferSlotLocked(slot);
599         mCore->mDequeueCondition.broadcast();
600         VALIDATE_CONSISTENCY();
601         listener = mCore->mConsumerListener;
602     }
603 
604     if (listener != NULL) {
605         listener->onBuffersReleased();
606     }
607 
608     return NO_ERROR;
609 }
610 
detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)611 status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
612         sp<Fence>* outFence) {
613     ATRACE_CALL();
614 
615     if (outBuffer == NULL) {
616         BQ_LOGE("detachNextBuffer: outBuffer must not be NULL");
617         return BAD_VALUE;
618     } else if (outFence == NULL) {
619         BQ_LOGE("detachNextBuffer: outFence must not be NULL");
620         return BAD_VALUE;
621     }
622 
623     Mutex::Autolock lock(mCore->mMutex);
624 
625     if (mCore->mIsAbandoned) {
626         BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
627         return NO_INIT;
628     }
629 
630     if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
631         BQ_LOGE("detachNextBuffer: BufferQueue has no connected producer");
632         return NO_INIT;
633     }
634 
635     if (mCore->mSharedBufferMode) {
636         BQ_LOGE("detachNextBuffer: cannot detach a buffer in shared buffer "
637             "mode");
638         return BAD_VALUE;
639     }
640 
641     mCore->waitWhileAllocatingLocked();
642 
643     if (mCore->mFreeBuffers.empty()) {
644         return NO_MEMORY;
645     }
646 
647     int found = mCore->mFreeBuffers.front();
648     mCore->mFreeBuffers.remove(found);
649     mCore->mFreeSlots.insert(found);
650 
651     BQ_LOGV("detachNextBuffer detached slot %d", found);
652 
653     *outBuffer = mSlots[found].mGraphicBuffer;
654     *outFence = mSlots[found].mFence;
655     mCore->clearBufferSlotLocked(found);
656     VALIDATE_CONSISTENCY();
657 
658     return NO_ERROR;
659 }
660 
attachBuffer(int * outSlot,const sp<android::GraphicBuffer> & buffer)661 status_t BufferQueueProducer::attachBuffer(int* outSlot,
662         const sp<android::GraphicBuffer>& buffer) {
663     ATRACE_CALL();
664 
665     if (outSlot == NULL) {
666         BQ_LOGE("attachBuffer: outSlot must not be NULL");
667         return BAD_VALUE;
668     } else if (buffer == NULL) {
669         BQ_LOGE("attachBuffer: cannot attach NULL buffer");
670         return BAD_VALUE;
671     }
672 
673     Mutex::Autolock lock(mCore->mMutex);
674 
675     if (mCore->mIsAbandoned) {
676         BQ_LOGE("attachBuffer: BufferQueue has been abandoned");
677         return NO_INIT;
678     }
679 
680     if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
681         BQ_LOGE("attachBuffer: BufferQueue has no connected producer");
682         return NO_INIT;
683     }
684 
685     if (mCore->mSharedBufferMode) {
686         BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
687         return BAD_VALUE;
688     }
689 
690     if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
691         BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
692                 "[queue %u]", buffer->getGenerationNumber(),
693                 mCore->mGenerationNumber);
694         return BAD_VALUE;
695     }
696 
697     mCore->waitWhileAllocatingLocked();
698 
699     status_t returnFlags = NO_ERROR;
700     int found;
701     status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Attach, &found);
702     if (status != NO_ERROR) {
703         return status;
704     }
705 
706     // This should not happen
707     if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
708         BQ_LOGE("attachBuffer: no available buffer slots");
709         return -EBUSY;
710     }
711 
712     *outSlot = found;
713     ATRACE_BUFFER_INDEX(*outSlot);
714     BQ_LOGV("attachBuffer: returning slot %d flags=%#x",
715             *outSlot, returnFlags);
716 
717     mSlots[*outSlot].mGraphicBuffer = buffer;
718     mSlots[*outSlot].mBufferState.attachProducer();
719     mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR;
720     mSlots[*outSlot].mFence = Fence::NO_FENCE;
721     mSlots[*outSlot].mRequestBufferCalled = true;
722     mSlots[*outSlot].mAcquireCalled = false;
723     mCore->mActiveBuffers.insert(found);
724     VALIDATE_CONSISTENCY();
725 
726     return returnFlags;
727 }
728 
queueBuffer(int slot,const QueueBufferInput & input,QueueBufferOutput * output)729 status_t BufferQueueProducer::queueBuffer(int slot,
730         const QueueBufferInput &input, QueueBufferOutput *output) {
731     ATRACE_CALL();
732     ATRACE_BUFFER_INDEX(slot);
733 
734     int64_t timestamp;
735     bool isAutoTimestamp;
736     android_dataspace dataSpace;
737     Rect crop(Rect::EMPTY_RECT);
738     int scalingMode;
739     uint32_t transform;
740     uint32_t stickyTransform;
741     sp<Fence> fence;
742     input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode,
743             &transform, &fence, &stickyTransform);
744     Region surfaceDamage = input.getSurfaceDamage();
745 
746     if (fence == NULL) {
747         BQ_LOGE("queueBuffer: fence is NULL");
748         return BAD_VALUE;
749     }
750 
751     switch (scalingMode) {
752         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
753         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
754         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
755         case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
756             break;
757         default:
758             BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode);
759             return BAD_VALUE;
760     }
761 
762     sp<IConsumerListener> frameAvailableListener;
763     sp<IConsumerListener> frameReplacedListener;
764     int callbackTicket = 0;
765     BufferItem item;
766     { // Autolock scope
767         Mutex::Autolock lock(mCore->mMutex);
768 
769         if (mCore->mIsAbandoned) {
770             BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
771             return NO_INIT;
772         }
773 
774         if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
775             BQ_LOGE("queueBuffer: BufferQueue has no connected producer");
776             return NO_INIT;
777         }
778 
779         if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
780             BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)",
781                     slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
782             return BAD_VALUE;
783         } else if (!mSlots[slot].mBufferState.isDequeued()) {
784             BQ_LOGE("queueBuffer: slot %d is not owned by the producer "
785                     "(state = %s)", slot, mSlots[slot].mBufferState.string());
786             return BAD_VALUE;
787         } else if (!mSlots[slot].mRequestBufferCalled) {
788             BQ_LOGE("queueBuffer: slot %d was queued without requesting "
789                     "a buffer", slot);
790             return BAD_VALUE;
791         }
792 
793         // If shared buffer mode has just been enabled, cache the slot of the
794         // first buffer that is queued and mark it as the shared buffer.
795         if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot ==
796                 BufferQueueCore::INVALID_BUFFER_SLOT) {
797             mCore->mSharedBufferSlot = slot;
798             mSlots[slot].mBufferState.mShared = true;
799         }
800 
801         BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d"
802                 " crop=[%d,%d,%d,%d] transform=%#x scale=%s",
803                 slot, mCore->mFrameCounter + 1, timestamp, dataSpace,
804                 crop.left, crop.top, crop.right, crop.bottom, transform,
805                 BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode)));
806 
807         const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
808         Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
809         Rect croppedRect(Rect::EMPTY_RECT);
810         crop.intersect(bufferRect, &croppedRect);
811         if (croppedRect != crop) {
812             BQ_LOGE("queueBuffer: crop rect is not contained within the "
813                     "buffer in slot %d", slot);
814             return BAD_VALUE;
815         }
816 
817         // Override UNKNOWN dataspace with consumer default
818         if (dataSpace == HAL_DATASPACE_UNKNOWN) {
819             dataSpace = mCore->mDefaultBufferDataSpace;
820         }
821 
822         mSlots[slot].mFence = fence;
823         mSlots[slot].mBufferState.queue();
824 
825         ++mCore->mFrameCounter;
826         mSlots[slot].mFrameNumber = mCore->mFrameCounter;
827 
828         item.mAcquireCalled = mSlots[slot].mAcquireCalled;
829         item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
830         item.mCrop = crop;
831         item.mTransform = transform &
832                 ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
833         item.mTransformToDisplayInverse =
834                 (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
835         item.mScalingMode = static_cast<uint32_t>(scalingMode);
836         item.mTimestamp = timestamp;
837         item.mIsAutoTimestamp = isAutoTimestamp;
838         item.mDataSpace = dataSpace;
839         item.mFrameNumber = mCore->mFrameCounter;
840         item.mSlot = slot;
841         item.mFence = fence;
842         item.mIsDroppable = mCore->mAsyncMode ||
843                 mCore->mDequeueBufferCannotBlock ||
844                 (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == slot);
845         item.mSurfaceDamage = surfaceDamage;
846         item.mQueuedBuffer = true;
847         item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh;
848 
849         mStickyTransform = stickyTransform;
850 
851         // Cache the shared buffer data so that the BufferItem can be recreated.
852         if (mCore->mSharedBufferMode) {
853             mCore->mSharedBufferCache.crop = crop;
854             mCore->mSharedBufferCache.transform = transform;
855             mCore->mSharedBufferCache.scalingMode = static_cast<uint32_t>(
856                     scalingMode);
857             mCore->mSharedBufferCache.dataspace = dataSpace;
858         }
859 
860         if (mCore->mQueue.empty()) {
861             // When the queue is empty, we can ignore mDequeueBufferCannotBlock
862             // and simply queue this buffer
863             mCore->mQueue.push_back(item);
864             frameAvailableListener = mCore->mConsumerListener;
865         } else {
866             // When the queue is not empty, we need to look at the last buffer
867             // in the queue to see if we need to replace it
868             const BufferItem& last = mCore->mQueue.itemAt(
869                     mCore->mQueue.size() - 1);
870             if (last.mIsDroppable) {
871 
872                 if (!last.mIsStale) {
873                     mSlots[last.mSlot].mBufferState.freeQueued();
874 
875                     // After leaving shared buffer mode, the shared buffer will
876                     // still be around. Mark it as no longer shared if this
877                     // operation causes it to be free.
878                     if (!mCore->mSharedBufferMode &&
879                             mSlots[last.mSlot].mBufferState.isFree()) {
880                         mSlots[last.mSlot].mBufferState.mShared = false;
881                     }
882                     // Don't put the shared buffer on the free list.
883                     if (!mSlots[last.mSlot].mBufferState.isShared()) {
884                         mCore->mActiveBuffers.erase(last.mSlot);
885                         mCore->mFreeBuffers.push_back(last.mSlot);
886                     }
887                 }
888 
889                 // Overwrite the droppable buffer with the incoming one
890                 mCore->mQueue.editItemAt(mCore->mQueue.size() - 1) = item;
891                 frameReplacedListener = mCore->mConsumerListener;
892             } else {
893                 mCore->mQueue.push_back(item);
894                 frameAvailableListener = mCore->mConsumerListener;
895             }
896         }
897 
898         mCore->mBufferHasBeenQueued = true;
899         mCore->mDequeueCondition.broadcast();
900         mCore->mLastQueuedSlot = slot;
901 
902         output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
903                 mCore->mTransformHint,
904                 static_cast<uint32_t>(mCore->mQueue.size()),
905                 mCore->mFrameCounter + 1);
906 
907         ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
908         mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size());
909 
910         // Take a ticket for the callback functions
911         callbackTicket = mNextCallbackTicket++;
912 
913         VALIDATE_CONSISTENCY();
914     } // Autolock scope
915 
916     // Don't send the GraphicBuffer through the callback, and don't send
917     // the slot number, since the consumer shouldn't need it
918     item.mGraphicBuffer.clear();
919     item.mSlot = BufferItem::INVALID_BUFFER_SLOT;
920 
921     // Call back without the main BufferQueue lock held, but with the callback
922     // lock held so we can ensure that callbacks occur in order
923     {
924         Mutex::Autolock lock(mCallbackMutex);
925         while (callbackTicket != mCurrentCallbackTicket) {
926             mCallbackCondition.wait(mCallbackMutex);
927         }
928 
929         if (frameAvailableListener != NULL) {
930             frameAvailableListener->onFrameAvailable(item);
931         } else if (frameReplacedListener != NULL) {
932             frameReplacedListener->onFrameReplaced(item);
933         }
934 
935         ++mCurrentCallbackTicket;
936         mCallbackCondition.broadcast();
937     }
938 
939     // Wait without lock held
940     if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
941         // Waiting here allows for two full buffers to be queued but not a
942         // third. In the event that frames take varying time, this makes a
943         // small trade-off in favor of latency rather than throughput.
944         mLastQueueBufferFence->waitForever("Throttling EGL Production");
945     }
946     mLastQueueBufferFence = fence;
947     mLastQueuedCrop = item.mCrop;
948     mLastQueuedTransform = item.mTransform;
949 
950     return NO_ERROR;
951 }
952 
cancelBuffer(int slot,const sp<Fence> & fence)953 status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
954     ATRACE_CALL();
955     BQ_LOGV("cancelBuffer: slot %d", slot);
956     Mutex::Autolock lock(mCore->mMutex);
957 
958     if (mCore->mIsAbandoned) {
959         BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
960         return NO_INIT;
961     }
962 
963     if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
964         BQ_LOGE("cancelBuffer: BufferQueue has no connected producer");
965         return NO_INIT;
966     }
967 
968     if (mCore->mSharedBufferMode) {
969         BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode");
970         return BAD_VALUE;
971     }
972 
973     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
974         BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
975                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
976         return BAD_VALUE;
977     } else if (!mSlots[slot].mBufferState.isDequeued()) {
978         BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
979                 "(state = %s)", slot, mSlots[slot].mBufferState.string());
980         return BAD_VALUE;
981     } else if (fence == NULL) {
982         BQ_LOGE("cancelBuffer: fence is NULL");
983         return BAD_VALUE;
984     }
985 
986     mSlots[slot].mBufferState.cancel();
987 
988     // After leaving shared buffer mode, the shared buffer will still be around.
989     // Mark it as no longer shared if this operation causes it to be free.
990     if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
991         mSlots[slot].mBufferState.mShared = false;
992     }
993 
994     // Don't put the shared buffer on the free list.
995     if (!mSlots[slot].mBufferState.isShared()) {
996         mCore->mActiveBuffers.erase(slot);
997         mCore->mFreeBuffers.push_back(slot);
998     }
999 
1000     mSlots[slot].mFence = fence;
1001     mCore->mDequeueCondition.broadcast();
1002     VALIDATE_CONSISTENCY();
1003 
1004     return NO_ERROR;
1005 }
1006 
query(int what,int * outValue)1007 int BufferQueueProducer::query(int what, int *outValue) {
1008     ATRACE_CALL();
1009     Mutex::Autolock lock(mCore->mMutex);
1010 
1011     if (outValue == NULL) {
1012         BQ_LOGE("query: outValue was NULL");
1013         return BAD_VALUE;
1014     }
1015 
1016     if (mCore->mIsAbandoned) {
1017         BQ_LOGE("query: BufferQueue has been abandoned");
1018         return NO_INIT;
1019     }
1020 
1021     int value;
1022     switch (what) {
1023         case NATIVE_WINDOW_WIDTH:
1024             value = static_cast<int32_t>(mCore->mDefaultWidth);
1025             break;
1026         case NATIVE_WINDOW_HEIGHT:
1027             value = static_cast<int32_t>(mCore->mDefaultHeight);
1028             break;
1029         case NATIVE_WINDOW_FORMAT:
1030             value = static_cast<int32_t>(mCore->mDefaultBufferFormat);
1031             break;
1032         case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
1033             value = mCore->getMinUndequeuedBufferCountLocked();
1034             break;
1035         case NATIVE_WINDOW_STICKY_TRANSFORM:
1036             value = static_cast<int32_t>(mStickyTransform);
1037             break;
1038         case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
1039             value = (mCore->mQueue.size() > 1);
1040             break;
1041         case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
1042             value = static_cast<int32_t>(mCore->mConsumerUsageBits);
1043             break;
1044         case NATIVE_WINDOW_DEFAULT_DATASPACE:
1045             value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace);
1046             break;
1047         case NATIVE_WINDOW_BUFFER_AGE:
1048             if (mCore->mBufferAge > INT32_MAX) {
1049                 value = 0;
1050             } else {
1051                 value = static_cast<int32_t>(mCore->mBufferAge);
1052             }
1053             break;
1054         default:
1055             return BAD_VALUE;
1056     }
1057 
1058     BQ_LOGV("query: %d? %d", what, value);
1059     *outValue = value;
1060     return NO_ERROR;
1061 }
1062 
connect(const sp<IProducerListener> & listener,int api,bool producerControlledByApp,QueueBufferOutput * output)1063 status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
1064         int api, bool producerControlledByApp, QueueBufferOutput *output) {
1065     ATRACE_CALL();
1066     Mutex::Autolock lock(mCore->mMutex);
1067     mConsumerName = mCore->mConsumerName;
1068     BQ_LOGV("connect: api=%d producerControlledByApp=%s", api,
1069             producerControlledByApp ? "true" : "false");
1070 
1071     if (mCore->mIsAbandoned) {
1072         BQ_LOGE("connect: BufferQueue has been abandoned");
1073         return NO_INIT;
1074     }
1075 
1076     if (mCore->mConsumerListener == NULL) {
1077         BQ_LOGE("connect: BufferQueue has no consumer");
1078         return NO_INIT;
1079     }
1080 
1081     if (output == NULL) {
1082         BQ_LOGE("connect: output was NULL");
1083         return BAD_VALUE;
1084     }
1085 
1086     if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
1087         BQ_LOGE("connect: already connected (cur=%d req=%d)",
1088                 mCore->mConnectedApi, api);
1089         return BAD_VALUE;
1090     }
1091 
1092     int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
1093             mDequeueTimeout < 0 ?
1094             mCore->mConsumerControlledByApp && producerControlledByApp : false,
1095             mCore->mMaxBufferCount) -
1096             mCore->getMaxBufferCountLocked();
1097     if (!mCore->adjustAvailableSlotsLocked(delta)) {
1098         BQ_LOGE("connect: BufferQueue failed to adjust the number of available "
1099                 "slots. Delta = %d", delta);
1100         return BAD_VALUE;
1101     }
1102 
1103     int status = NO_ERROR;
1104     switch (api) {
1105         case NATIVE_WINDOW_API_EGL:
1106         case NATIVE_WINDOW_API_CPU:
1107         case NATIVE_WINDOW_API_MEDIA:
1108         case NATIVE_WINDOW_API_CAMERA:
1109             mCore->mConnectedApi = api;
1110             output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
1111                     mCore->mTransformHint,
1112                     static_cast<uint32_t>(mCore->mQueue.size()),
1113                     mCore->mFrameCounter + 1);
1114 
1115             // Set up a death notification so that we can disconnect
1116             // automatically if the remote producer dies
1117             if (listener != NULL &&
1118                     IInterface::asBinder(listener)->remoteBinder() != NULL) {
1119                 status = IInterface::asBinder(listener)->linkToDeath(
1120                         static_cast<IBinder::DeathRecipient*>(this));
1121                 if (status != NO_ERROR) {
1122                     BQ_LOGE("connect: linkToDeath failed: %s (%d)",
1123                             strerror(-status), status);
1124                 }
1125             }
1126             mCore->mConnectedProducerListener = listener;
1127             break;
1128         default:
1129             BQ_LOGE("connect: unknown API %d", api);
1130             status = BAD_VALUE;
1131             break;
1132     }
1133 
1134     mCore->mBufferHasBeenQueued = false;
1135     mCore->mDequeueBufferCannotBlock = false;
1136     if (mDequeueTimeout < 0) {
1137         mCore->mDequeueBufferCannotBlock =
1138                 mCore->mConsumerControlledByApp && producerControlledByApp;
1139     }
1140 
1141     mCore->mAllowAllocation = true;
1142     VALIDATE_CONSISTENCY();
1143     return status;
1144 }
1145 
disconnect(int api)1146 status_t BufferQueueProducer::disconnect(int api) {
1147     ATRACE_CALL();
1148     BQ_LOGV("disconnect: api %d", api);
1149 
1150     int status = NO_ERROR;
1151     sp<IConsumerListener> listener;
1152     { // Autolock scope
1153         Mutex::Autolock lock(mCore->mMutex);
1154         mCore->waitWhileAllocatingLocked();
1155 
1156         if (mCore->mIsAbandoned) {
1157             // It's not really an error to disconnect after the surface has
1158             // been abandoned; it should just be a no-op.
1159             return NO_ERROR;
1160         }
1161 
1162         if (api == BufferQueueCore::CURRENTLY_CONNECTED_API) {
1163             api = mCore->mConnectedApi;
1164             // If we're asked to disconnect the currently connected api but
1165             // nobody is connected, it's not really an error.
1166             if (api == BufferQueueCore::NO_CONNECTED_API) {
1167                 return NO_ERROR;
1168             }
1169         }
1170 
1171         switch (api) {
1172             case NATIVE_WINDOW_API_EGL:
1173             case NATIVE_WINDOW_API_CPU:
1174             case NATIVE_WINDOW_API_MEDIA:
1175             case NATIVE_WINDOW_API_CAMERA:
1176                 if (mCore->mConnectedApi == api) {
1177                     mCore->freeAllBuffersLocked();
1178 
1179                     // Remove our death notification callback if we have one
1180                     if (mCore->mConnectedProducerListener != NULL) {
1181                         sp<IBinder> token =
1182                                 IInterface::asBinder(mCore->mConnectedProducerListener);
1183                         // This can fail if we're here because of the death
1184                         // notification, but we just ignore it
1185                         token->unlinkToDeath(
1186                                 static_cast<IBinder::DeathRecipient*>(this));
1187                     }
1188                     mCore->mSharedBufferSlot =
1189                             BufferQueueCore::INVALID_BUFFER_SLOT;
1190                     mCore->mConnectedProducerListener = NULL;
1191                     mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
1192                     mCore->mSidebandStream.clear();
1193                     mCore->mDequeueCondition.broadcast();
1194                     listener = mCore->mConsumerListener;
1195                 } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
1196                     BQ_LOGE("disconnect: still connected to another API "
1197                             "(cur=%d req=%d)", mCore->mConnectedApi, api);
1198                     status = BAD_VALUE;
1199                 }
1200                 break;
1201             default:
1202                 BQ_LOGE("disconnect: unknown API %d", api);
1203                 status = BAD_VALUE;
1204                 break;
1205         }
1206     } // Autolock scope
1207 
1208     // Call back without lock held
1209     if (listener != NULL) {
1210         listener->onBuffersReleased();
1211     }
1212 
1213     return status;
1214 }
1215 
setSidebandStream(const sp<NativeHandle> & stream)1216 status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
1217     sp<IConsumerListener> listener;
1218     { // Autolock scope
1219         Mutex::Autolock _l(mCore->mMutex);
1220         mCore->mSidebandStream = stream;
1221         listener = mCore->mConsumerListener;
1222     } // Autolock scope
1223 
1224     if (listener != NULL) {
1225         listener->onSidebandStreamChanged();
1226     }
1227     return NO_ERROR;
1228 }
1229 
allocateBuffers(uint32_t width,uint32_t height,PixelFormat format,uint32_t usage)1230 void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
1231         PixelFormat format, uint32_t usage) {
1232     ATRACE_CALL();
1233     while (true) {
1234         size_t newBufferCount = 0;
1235         uint32_t allocWidth = 0;
1236         uint32_t allocHeight = 0;
1237         PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN;
1238         uint32_t allocUsage = 0;
1239         { // Autolock scope
1240             Mutex::Autolock lock(mCore->mMutex);
1241             mCore->waitWhileAllocatingLocked();
1242 
1243             if (!mCore->mAllowAllocation) {
1244                 BQ_LOGE("allocateBuffers: allocation is not allowed for this "
1245                         "BufferQueue");
1246                 return;
1247             }
1248 
1249             newBufferCount = mCore->mFreeSlots.size();
1250             if (newBufferCount == 0) {
1251                 return;
1252             }
1253 
1254             allocWidth = width > 0 ? width : mCore->mDefaultWidth;
1255             allocHeight = height > 0 ? height : mCore->mDefaultHeight;
1256             allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
1257             allocUsage = usage | mCore->mConsumerUsageBits;
1258 
1259             mCore->mIsAllocating = true;
1260         } // Autolock scope
1261 
1262         Vector<sp<GraphicBuffer>> buffers;
1263         for (size_t i = 0; i <  newBufferCount; ++i) {
1264             status_t result = NO_ERROR;
1265             sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
1266                     allocWidth, allocHeight, allocFormat, allocUsage,
1267                     {mConsumerName.string(), mConsumerName.size()}, &result));
1268             if (result != NO_ERROR) {
1269                 BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
1270                         " %u, usage %u)", width, height, format, usage);
1271                 Mutex::Autolock lock(mCore->mMutex);
1272                 mCore->mIsAllocating = false;
1273                 mCore->mIsAllocatingCondition.broadcast();
1274                 return;
1275             }
1276             buffers.push_back(graphicBuffer);
1277         }
1278 
1279         { // Autolock scope
1280             Mutex::Autolock lock(mCore->mMutex);
1281             uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
1282             uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
1283             PixelFormat checkFormat = format != 0 ?
1284                     format : mCore->mDefaultBufferFormat;
1285             uint32_t checkUsage = usage | mCore->mConsumerUsageBits;
1286             if (checkWidth != allocWidth || checkHeight != allocHeight ||
1287                 checkFormat != allocFormat || checkUsage != allocUsage) {
1288                 // Something changed while we released the lock. Retry.
1289                 BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying.");
1290                 mCore->mIsAllocating = false;
1291                 mCore->mIsAllocatingCondition.broadcast();
1292                 continue;
1293             }
1294 
1295             for (size_t i = 0; i < newBufferCount; ++i) {
1296                 if (mCore->mFreeSlots.empty()) {
1297                     BQ_LOGV("allocateBuffers: a slot was occupied while "
1298                             "allocating. Dropping allocated buffer.");
1299                     continue;
1300                 }
1301                 auto slot = mCore->mFreeSlots.begin();
1302                 mCore->clearBufferSlotLocked(*slot); // Clean up the slot first
1303                 mSlots[*slot].mGraphicBuffer = buffers[i];
1304                 mSlots[*slot].mFence = Fence::NO_FENCE;
1305 
1306                 // freeBufferLocked puts this slot on the free slots list. Since
1307                 // we then attached a buffer, move the slot to free buffer list.
1308                 mCore->mFreeBuffers.push_front(*slot);
1309 
1310                 BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d",
1311                         *slot);
1312 
1313                 // Make sure the erase is done after all uses of the slot
1314                 // iterator since it will be invalid after this point.
1315                 mCore->mFreeSlots.erase(slot);
1316             }
1317 
1318             mCore->mIsAllocating = false;
1319             mCore->mIsAllocatingCondition.broadcast();
1320             VALIDATE_CONSISTENCY();
1321         } // Autolock scope
1322     }
1323 }
1324 
allowAllocation(bool allow)1325 status_t BufferQueueProducer::allowAllocation(bool allow) {
1326     ATRACE_CALL();
1327     BQ_LOGV("allowAllocation: %s", allow ? "true" : "false");
1328 
1329     Mutex::Autolock lock(mCore->mMutex);
1330     mCore->mAllowAllocation = allow;
1331     return NO_ERROR;
1332 }
1333 
setGenerationNumber(uint32_t generationNumber)1334 status_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) {
1335     ATRACE_CALL();
1336     BQ_LOGV("setGenerationNumber: %u", generationNumber);
1337 
1338     Mutex::Autolock lock(mCore->mMutex);
1339     mCore->mGenerationNumber = generationNumber;
1340     return NO_ERROR;
1341 }
1342 
getConsumerName() const1343 String8 BufferQueueProducer::getConsumerName() const {
1344     ATRACE_CALL();
1345     BQ_LOGV("getConsumerName: %s", mConsumerName.string());
1346     return mConsumerName;
1347 }
1348 
setSharedBufferMode(bool sharedBufferMode)1349 status_t BufferQueueProducer::setSharedBufferMode(bool sharedBufferMode) {
1350     ATRACE_CALL();
1351     BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode);
1352 
1353     Mutex::Autolock lock(mCore->mMutex);
1354     if (!sharedBufferMode) {
1355         mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
1356     }
1357     mCore->mSharedBufferMode = sharedBufferMode;
1358     return NO_ERROR;
1359 }
1360 
setAutoRefresh(bool autoRefresh)1361 status_t BufferQueueProducer::setAutoRefresh(bool autoRefresh) {
1362     ATRACE_CALL();
1363     BQ_LOGV("setAutoRefresh: %d", autoRefresh);
1364 
1365     Mutex::Autolock lock(mCore->mMutex);
1366 
1367     mCore->mAutoRefresh = autoRefresh;
1368     return NO_ERROR;
1369 }
1370 
setDequeueTimeout(nsecs_t timeout)1371 status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) {
1372     ATRACE_CALL();
1373     BQ_LOGV("setDequeueTimeout: %" PRId64, timeout);
1374 
1375     Mutex::Autolock lock(mCore->mMutex);
1376     int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false,
1377             mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked();
1378     if (!mCore->adjustAvailableSlotsLocked(delta)) {
1379         BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of "
1380                 "available slots. Delta = %d", delta);
1381         return BAD_VALUE;
1382     }
1383 
1384     mDequeueTimeout = timeout;
1385     mCore->mDequeueBufferCannotBlock = false;
1386 
1387     VALIDATE_CONSISTENCY();
1388     return NO_ERROR;
1389 }
1390 
getLastQueuedBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence,float outTransformMatrix[16])1391 status_t BufferQueueProducer::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
1392         sp<Fence>* outFence, float outTransformMatrix[16]) {
1393     ATRACE_CALL();
1394     BQ_LOGV("getLastQueuedBuffer");
1395 
1396     Mutex::Autolock lock(mCore->mMutex);
1397     if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) {
1398         *outBuffer = nullptr;
1399         *outFence = Fence::NO_FENCE;
1400         return NO_ERROR;
1401     }
1402 
1403     *outBuffer = mSlots[mCore->mLastQueuedSlot].mGraphicBuffer;
1404     *outFence = mLastQueueBufferFence;
1405 
1406     // Currently only SurfaceFlinger internally ever changes
1407     // GLConsumer's filtering mode, so we just use 'true' here as
1408     // this is slightly specialized for the current client of this API,
1409     // which does want filtering.
1410     GLConsumer::computeTransformMatrix(outTransformMatrix,
1411             mSlots[mCore->mLastQueuedSlot].mGraphicBuffer, mLastQueuedCrop,
1412             mLastQueuedTransform, true /* filter */);
1413 
1414     return NO_ERROR;
1415 }
1416 
getFrameTimestamps(uint64_t frameNumber,FrameTimestamps * outTimestamps) const1417 bool BufferQueueProducer::getFrameTimestamps(uint64_t frameNumber,
1418         FrameTimestamps* outTimestamps) const {
1419     ATRACE_CALL();
1420     BQ_LOGV("getFrameTimestamps, %" PRIu64, frameNumber);
1421     sp<IConsumerListener> listener;
1422 
1423     {
1424         Mutex::Autolock lock(mCore->mMutex);
1425         listener = mCore->mConsumerListener;
1426     }
1427     if (listener != NULL) {
1428         return listener->getFrameTimestamps(frameNumber, outTimestamps);
1429     }
1430     return false;
1431 }
1432 
binderDied(const wp<android::IBinder> &)1433 void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
1434     // If we're here, it means that a producer we were connected to died.
1435     // We're guaranteed that we are still connected to it because we remove
1436     // this callback upon disconnect. It's therefore safe to read mConnectedApi
1437     // without synchronization here.
1438     int api = mCore->mConnectedApi;
1439     disconnect(api);
1440 }
1441 
getUniqueId(uint64_t * outId) const1442 status_t BufferQueueProducer::getUniqueId(uint64_t* outId) const {
1443     BQ_LOGV("getUniqueId");
1444 
1445     *outId = mCore->mUniqueId;
1446     return NO_ERROR;
1447 }
1448 
1449 } // namespace android
1450