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, &error));
500         { // Autolock scope
501             Mutex::Autolock lock(mCore->mMutex);
502 
503             if (graphicBuffer != NULL && !mCore->mIsAbandoned) {
504                 graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
505                 mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
506             }
507 
508             mCore->mIsAllocating = false;
509             mCore->mIsAllocatingCondition.broadcast();
510 
511             if (graphicBuffer == NULL) {
512                 BQ_LOGE("dequeueBuffer: createGraphicBuffer failed");
513                 return error;
514             }
515 
516             if (mCore->mIsAbandoned) {
517                 BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
518                 return NO_INIT;
519             }
520 
521             VALIDATE_CONSISTENCY();
522         } // Autolock scope
523     }
524 
525     if (attachedByConsumer) {
526         returnFlags |= BUFFER_NEEDS_REALLOCATION;
527     }
528 
529     if (eglFence != EGL_NO_SYNC_KHR) {
530         EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0,
531                 1000000000);
532         // If something goes wrong, log the error, but return the buffer without
533         // synchronizing access to it. It's too late at this point to abort the
534         // dequeue operation.
535         if (result == EGL_FALSE) {
536             BQ_LOGE("dequeueBuffer: error %#x waiting for fence",
537                     eglGetError());
538         } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
539             BQ_LOGE("dequeueBuffer: timeout waiting for fence");
540         }
541         eglDestroySyncKHR(eglDisplay, eglFence);
542     }
543 
544     BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x",
545             *outSlot,
546             mSlots[*outSlot].mFrameNumber,
547             mSlots[*outSlot].mGraphicBuffer->handle, returnFlags);
548 
549     return returnFlags;
550 }
551 
detachBuffer(int slot)552 status_t BufferQueueProducer::detachBuffer(int slot) {
553     ATRACE_CALL();
554     ATRACE_BUFFER_INDEX(slot);
555     BQ_LOGV("detachBuffer: slot %d", slot);
556 
557     sp<IConsumerListener> listener;
558     {
559         Mutex::Autolock lock(mCore->mMutex);
560 
561         if (mCore->mIsAbandoned) {
562             BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
563             return NO_INIT;
564         }
565 
566         if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
567             BQ_LOGE("detachBuffer: BufferQueue has no connected producer");
568             return NO_INIT;
569         }
570 
571         if (mCore->mSharedBufferMode || mCore->mSharedBufferSlot == slot) {
572             BQ_LOGE("detachBuffer: cannot detach a buffer in shared buffer mode");
573             return BAD_VALUE;
574         }
575 
576         if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
577             BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
578                     slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
579             return BAD_VALUE;
580         } else if (!mSlots[slot].mBufferState.isDequeued()) {
581             BQ_LOGE("detachBuffer: slot %d is not owned by the producer "
582                     "(state = %s)", slot, mSlots[slot].mBufferState.string());
583             return BAD_VALUE;
584         } else if (!mSlots[slot].mRequestBufferCalled) {
585             BQ_LOGE("detachBuffer: buffer in slot %d has not been requested",
586                     slot);
587             return BAD_VALUE;
588         }
589 
590         mSlots[slot].mBufferState.detachProducer();
591         mCore->mActiveBuffers.erase(slot);
592         mCore->mFreeSlots.insert(slot);
593         mCore->clearBufferSlotLocked(slot);
594         mCore->mDequeueCondition.broadcast();
595         VALIDATE_CONSISTENCY();
596         listener = mCore->mConsumerListener;
597     }
598 
599     if (listener != NULL) {
600         listener->onBuffersReleased();
601     }
602 
603     return NO_ERROR;
604 }
605 
detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)606 status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
607         sp<Fence>* outFence) {
608     ATRACE_CALL();
609 
610     if (outBuffer == NULL) {
611         BQ_LOGE("detachNextBuffer: outBuffer must not be NULL");
612         return BAD_VALUE;
613     } else if (outFence == NULL) {
614         BQ_LOGE("detachNextBuffer: outFence must not be NULL");
615         return BAD_VALUE;
616     }
617 
618     Mutex::Autolock lock(mCore->mMutex);
619 
620     if (mCore->mIsAbandoned) {
621         BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
622         return NO_INIT;
623     }
624 
625     if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
626         BQ_LOGE("detachNextBuffer: BufferQueue has no connected producer");
627         return NO_INIT;
628     }
629 
630     if (mCore->mSharedBufferMode) {
631         BQ_LOGE("detachNextBuffer: cannot detach a buffer in shared buffer "
632             "mode");
633         return BAD_VALUE;
634     }
635 
636     mCore->waitWhileAllocatingLocked();
637 
638     if (mCore->mFreeBuffers.empty()) {
639         return NO_MEMORY;
640     }
641 
642     int found = mCore->mFreeBuffers.front();
643     mCore->mFreeBuffers.remove(found);
644     mCore->mFreeSlots.insert(found);
645 
646     BQ_LOGV("detachNextBuffer detached slot %d", found);
647 
648     *outBuffer = mSlots[found].mGraphicBuffer;
649     *outFence = mSlots[found].mFence;
650     mCore->clearBufferSlotLocked(found);
651     VALIDATE_CONSISTENCY();
652 
653     return NO_ERROR;
654 }
655 
attachBuffer(int * outSlot,const sp<android::GraphicBuffer> & buffer)656 status_t BufferQueueProducer::attachBuffer(int* outSlot,
657         const sp<android::GraphicBuffer>& buffer) {
658     ATRACE_CALL();
659 
660     if (outSlot == NULL) {
661         BQ_LOGE("attachBuffer: outSlot must not be NULL");
662         return BAD_VALUE;
663     } else if (buffer == NULL) {
664         BQ_LOGE("attachBuffer: cannot attach NULL buffer");
665         return BAD_VALUE;
666     }
667 
668     Mutex::Autolock lock(mCore->mMutex);
669 
670     if (mCore->mIsAbandoned) {
671         BQ_LOGE("attachBuffer: BufferQueue has been abandoned");
672         return NO_INIT;
673     }
674 
675     if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
676         BQ_LOGE("attachBuffer: BufferQueue has no connected producer");
677         return NO_INIT;
678     }
679 
680     if (mCore->mSharedBufferMode) {
681         BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
682         return BAD_VALUE;
683     }
684 
685     if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
686         BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
687                 "[queue %u]", buffer->getGenerationNumber(),
688                 mCore->mGenerationNumber);
689         return BAD_VALUE;
690     }
691 
692     mCore->waitWhileAllocatingLocked();
693 
694     status_t returnFlags = NO_ERROR;
695     int found;
696     status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Attach, &found);
697     if (status != NO_ERROR) {
698         return status;
699     }
700 
701     // This should not happen
702     if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
703         BQ_LOGE("attachBuffer: no available buffer slots");
704         return -EBUSY;
705     }
706 
707     *outSlot = found;
708     ATRACE_BUFFER_INDEX(*outSlot);
709     BQ_LOGV("attachBuffer: returning slot %d flags=%#x",
710             *outSlot, returnFlags);
711 
712     mSlots[*outSlot].mGraphicBuffer = buffer;
713     mSlots[*outSlot].mBufferState.attachProducer();
714     mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR;
715     mSlots[*outSlot].mFence = Fence::NO_FENCE;
716     mSlots[*outSlot].mRequestBufferCalled = true;
717     mSlots[*outSlot].mAcquireCalled = false;
718     mCore->mActiveBuffers.insert(found);
719     VALIDATE_CONSISTENCY();
720 
721     return returnFlags;
722 }
723 
queueBuffer(int slot,const QueueBufferInput & input,QueueBufferOutput * output)724 status_t BufferQueueProducer::queueBuffer(int slot,
725         const QueueBufferInput &input, QueueBufferOutput *output) {
726     ATRACE_CALL();
727     ATRACE_BUFFER_INDEX(slot);
728 
729     int64_t timestamp;
730     bool isAutoTimestamp;
731     android_dataspace dataSpace;
732     Rect crop(Rect::EMPTY_RECT);
733     int scalingMode;
734     uint32_t transform;
735     uint32_t stickyTransform;
736     sp<Fence> fence;
737     input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode,
738             &transform, &fence, &stickyTransform);
739     Region surfaceDamage = input.getSurfaceDamage();
740 
741     if (fence == NULL) {
742         BQ_LOGE("queueBuffer: fence is NULL");
743         return BAD_VALUE;
744     }
745 
746     switch (scalingMode) {
747         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
748         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
749         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
750         case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
751             break;
752         default:
753             BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode);
754             return BAD_VALUE;
755     }
756 
757     sp<IConsumerListener> frameAvailableListener;
758     sp<IConsumerListener> frameReplacedListener;
759     int callbackTicket = 0;
760     BufferItem item;
761     { // Autolock scope
762         Mutex::Autolock lock(mCore->mMutex);
763 
764         if (mCore->mIsAbandoned) {
765             BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
766             return NO_INIT;
767         }
768 
769         if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
770             BQ_LOGE("queueBuffer: BufferQueue has no connected producer");
771             return NO_INIT;
772         }
773 
774         if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
775             BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)",
776                     slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
777             return BAD_VALUE;
778         } else if (!mSlots[slot].mBufferState.isDequeued()) {
779             BQ_LOGE("queueBuffer: slot %d is not owned by the producer "
780                     "(state = %s)", slot, mSlots[slot].mBufferState.string());
781             return BAD_VALUE;
782         } else if (!mSlots[slot].mRequestBufferCalled) {
783             BQ_LOGE("queueBuffer: slot %d was queued without requesting "
784                     "a buffer", slot);
785             return BAD_VALUE;
786         }
787 
788         // If shared buffer mode has just been enabled, cache the slot of the
789         // first buffer that is queued and mark it as the shared buffer.
790         if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot ==
791                 BufferQueueCore::INVALID_BUFFER_SLOT) {
792             mCore->mSharedBufferSlot = slot;
793             mSlots[slot].mBufferState.mShared = true;
794         }
795 
796         BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d"
797                 " crop=[%d,%d,%d,%d] transform=%#x scale=%s",
798                 slot, mCore->mFrameCounter + 1, timestamp, dataSpace,
799                 crop.left, crop.top, crop.right, crop.bottom, transform,
800                 BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode)));
801 
802         const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
803         Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
804         Rect croppedRect(Rect::EMPTY_RECT);
805         crop.intersect(bufferRect, &croppedRect);
806         if (croppedRect != crop) {
807             BQ_LOGE("queueBuffer: crop rect is not contained within the "
808                     "buffer in slot %d", slot);
809             return BAD_VALUE;
810         }
811 
812         // Override UNKNOWN dataspace with consumer default
813         if (dataSpace == HAL_DATASPACE_UNKNOWN) {
814             dataSpace = mCore->mDefaultBufferDataSpace;
815         }
816 
817         mSlots[slot].mFence = fence;
818         mSlots[slot].mBufferState.queue();
819 
820         ++mCore->mFrameCounter;
821         mSlots[slot].mFrameNumber = mCore->mFrameCounter;
822 
823         item.mAcquireCalled = mSlots[slot].mAcquireCalled;
824         item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
825         item.mCrop = crop;
826         item.mTransform = transform &
827                 ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
828         item.mTransformToDisplayInverse =
829                 (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
830         item.mScalingMode = static_cast<uint32_t>(scalingMode);
831         item.mTimestamp = timestamp;
832         item.mIsAutoTimestamp = isAutoTimestamp;
833         item.mDataSpace = dataSpace;
834         item.mFrameNumber = mCore->mFrameCounter;
835         item.mSlot = slot;
836         item.mFence = fence;
837         item.mIsDroppable = mCore->mAsyncMode ||
838                 mCore->mDequeueBufferCannotBlock ||
839                 (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == slot);
840         item.mSurfaceDamage = surfaceDamage;
841         item.mQueuedBuffer = true;
842         item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh;
843 
844         mStickyTransform = stickyTransform;
845 
846         // Cache the shared buffer data so that the BufferItem can be recreated.
847         if (mCore->mSharedBufferMode) {
848             mCore->mSharedBufferCache.crop = crop;
849             mCore->mSharedBufferCache.transform = transform;
850             mCore->mSharedBufferCache.scalingMode = static_cast<uint32_t>(
851                     scalingMode);
852             mCore->mSharedBufferCache.dataspace = dataSpace;
853         }
854 
855         if (mCore->mQueue.empty()) {
856             // When the queue is empty, we can ignore mDequeueBufferCannotBlock
857             // and simply queue this buffer
858             mCore->mQueue.push_back(item);
859             frameAvailableListener = mCore->mConsumerListener;
860         } else {
861             // When the queue is not empty, we need to look at the last buffer
862             // in the queue to see if we need to replace it
863             const BufferItem& last = mCore->mQueue.itemAt(
864                     mCore->mQueue.size() - 1);
865             if (last.mIsDroppable) {
866 
867                 if (!last.mIsStale) {
868                     mSlots[last.mSlot].mBufferState.freeQueued();
869 
870                     // After leaving shared buffer mode, the shared buffer will
871                     // still be around. Mark it as no longer shared if this
872                     // operation causes it to be free.
873                     if (!mCore->mSharedBufferMode &&
874                             mSlots[last.mSlot].mBufferState.isFree()) {
875                         mSlots[last.mSlot].mBufferState.mShared = false;
876                     }
877                     // Don't put the shared buffer on the free list.
878                     if (!mSlots[last.mSlot].mBufferState.isShared()) {
879                         mCore->mActiveBuffers.erase(last.mSlot);
880                         mCore->mFreeBuffers.push_back(last.mSlot);
881                     }
882                 }
883 
884                 // Overwrite the droppable buffer with the incoming one
885                 mCore->mQueue.editItemAt(mCore->mQueue.size() - 1) = item;
886                 frameReplacedListener = mCore->mConsumerListener;
887             } else {
888                 mCore->mQueue.push_back(item);
889                 frameAvailableListener = mCore->mConsumerListener;
890             }
891         }
892 
893         mCore->mBufferHasBeenQueued = true;
894         mCore->mDequeueCondition.broadcast();
895         mCore->mLastQueuedSlot = slot;
896 
897         output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
898                 mCore->mTransformHint,
899                 static_cast<uint32_t>(mCore->mQueue.size()));
900 
901         ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
902 
903         // Take a ticket for the callback functions
904         callbackTicket = mNextCallbackTicket++;
905 
906         VALIDATE_CONSISTENCY();
907     } // Autolock scope
908 
909     // Don't send the GraphicBuffer through the callback, and don't send
910     // the slot number, since the consumer shouldn't need it
911     item.mGraphicBuffer.clear();
912     item.mSlot = BufferItem::INVALID_BUFFER_SLOT;
913 
914     // Call back without the main BufferQueue lock held, but with the callback
915     // lock held so we can ensure that callbacks occur in order
916     {
917         Mutex::Autolock lock(mCallbackMutex);
918         while (callbackTicket != mCurrentCallbackTicket) {
919             mCallbackCondition.wait(mCallbackMutex);
920         }
921 
922         if (frameAvailableListener != NULL) {
923             frameAvailableListener->onFrameAvailable(item);
924         } else if (frameReplacedListener != NULL) {
925             frameReplacedListener->onFrameReplaced(item);
926         }
927 
928         ++mCurrentCallbackTicket;
929         mCallbackCondition.broadcast();
930     }
931 
932     // Wait without lock held
933     if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
934         // Waiting here allows for two full buffers to be queued but not a
935         // third. In the event that frames take varying time, this makes a
936         // small trade-off in favor of latency rather than throughput.
937         mLastQueueBufferFence->waitForever("Throttling EGL Production");
938     }
939     mLastQueueBufferFence = fence;
940     mLastQueuedCrop = item.mCrop;
941     mLastQueuedTransform = item.mTransform;
942 
943     return NO_ERROR;
944 }
945 
cancelBuffer(int slot,const sp<Fence> & fence)946 status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
947     ATRACE_CALL();
948     BQ_LOGV("cancelBuffer: slot %d", slot);
949     Mutex::Autolock lock(mCore->mMutex);
950 
951     if (mCore->mIsAbandoned) {
952         BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
953         return NO_INIT;
954     }
955 
956     if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
957         BQ_LOGE("cancelBuffer: BufferQueue has no connected producer");
958         return NO_INIT;
959     }
960 
961     if (mCore->mSharedBufferMode) {
962         BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode");
963         return BAD_VALUE;
964     }
965 
966     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
967         BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
968                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
969         return BAD_VALUE;
970     } else if (!mSlots[slot].mBufferState.isDequeued()) {
971         BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
972                 "(state = %s)", slot, mSlots[slot].mBufferState.string());
973         return BAD_VALUE;
974     } else if (fence == NULL) {
975         BQ_LOGE("cancelBuffer: fence is NULL");
976         return BAD_VALUE;
977     }
978 
979     mSlots[slot].mBufferState.cancel();
980 
981     // After leaving shared buffer mode, the shared buffer will still be around.
982     // Mark it as no longer shared if this operation causes it to be free.
983     if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
984         mSlots[slot].mBufferState.mShared = false;
985     }
986 
987     // Don't put the shared buffer on the free list.
988     if (!mSlots[slot].mBufferState.isShared()) {
989         mCore->mActiveBuffers.erase(slot);
990         mCore->mFreeBuffers.push_back(slot);
991     }
992 
993     mSlots[slot].mFence = fence;
994     mCore->mDequeueCondition.broadcast();
995     VALIDATE_CONSISTENCY();
996 
997     return NO_ERROR;
998 }
999 
query(int what,int * outValue)1000 int BufferQueueProducer::query(int what, int *outValue) {
1001     ATRACE_CALL();
1002     Mutex::Autolock lock(mCore->mMutex);
1003 
1004     if (outValue == NULL) {
1005         BQ_LOGE("query: outValue was NULL");
1006         return BAD_VALUE;
1007     }
1008 
1009     if (mCore->mIsAbandoned) {
1010         BQ_LOGE("query: BufferQueue has been abandoned");
1011         return NO_INIT;
1012     }
1013 
1014     int value;
1015     switch (what) {
1016         case NATIVE_WINDOW_WIDTH:
1017             value = static_cast<int32_t>(mCore->mDefaultWidth);
1018             break;
1019         case NATIVE_WINDOW_HEIGHT:
1020             value = static_cast<int32_t>(mCore->mDefaultHeight);
1021             break;
1022         case NATIVE_WINDOW_FORMAT:
1023             value = static_cast<int32_t>(mCore->mDefaultBufferFormat);
1024             break;
1025         case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
1026             value = mCore->getMinUndequeuedBufferCountLocked();
1027             break;
1028         case NATIVE_WINDOW_STICKY_TRANSFORM:
1029             value = static_cast<int32_t>(mStickyTransform);
1030             break;
1031         case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
1032             value = (mCore->mQueue.size() > 1);
1033             break;
1034         case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
1035             value = static_cast<int32_t>(mCore->mConsumerUsageBits);
1036             break;
1037         case NATIVE_WINDOW_DEFAULT_DATASPACE:
1038             value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace);
1039             break;
1040         case NATIVE_WINDOW_BUFFER_AGE:
1041             if (mCore->mBufferAge > INT32_MAX) {
1042                 value = 0;
1043             } else {
1044                 value = static_cast<int32_t>(mCore->mBufferAge);
1045             }
1046             break;
1047         default:
1048             return BAD_VALUE;
1049     }
1050 
1051     BQ_LOGV("query: %d? %d", what, value);
1052     *outValue = value;
1053     return NO_ERROR;
1054 }
1055 
connect(const sp<IProducerListener> & listener,int api,bool producerControlledByApp,QueueBufferOutput * output)1056 status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
1057         int api, bool producerControlledByApp, QueueBufferOutput *output) {
1058     ATRACE_CALL();
1059     Mutex::Autolock lock(mCore->mMutex);
1060     mConsumerName = mCore->mConsumerName;
1061     BQ_LOGV("connect: api=%d producerControlledByApp=%s", api,
1062             producerControlledByApp ? "true" : "false");
1063 
1064     if (mCore->mIsAbandoned) {
1065         BQ_LOGE("connect: BufferQueue has been abandoned");
1066         return NO_INIT;
1067     }
1068 
1069     if (mCore->mConsumerListener == NULL) {
1070         BQ_LOGE("connect: BufferQueue has no consumer");
1071         return NO_INIT;
1072     }
1073 
1074     if (output == NULL) {
1075         BQ_LOGE("connect: output was NULL");
1076         return BAD_VALUE;
1077     }
1078 
1079     if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
1080         BQ_LOGE("connect: already connected (cur=%d req=%d)",
1081                 mCore->mConnectedApi, api);
1082         return BAD_VALUE;
1083     }
1084 
1085     int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
1086             mDequeueTimeout < 0 ?
1087             mCore->mConsumerControlledByApp && producerControlledByApp : false,
1088             mCore->mMaxBufferCount) -
1089             mCore->getMaxBufferCountLocked();
1090     if (!mCore->adjustAvailableSlotsLocked(delta)) {
1091         BQ_LOGE("connect: BufferQueue failed to adjust the number of available "
1092                 "slots. Delta = %d", delta);
1093         return BAD_VALUE;
1094     }
1095 
1096     int status = NO_ERROR;
1097     switch (api) {
1098         case NATIVE_WINDOW_API_EGL:
1099         case NATIVE_WINDOW_API_CPU:
1100         case NATIVE_WINDOW_API_MEDIA:
1101         case NATIVE_WINDOW_API_CAMERA:
1102             mCore->mConnectedApi = api;
1103             output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
1104                     mCore->mTransformHint,
1105                     static_cast<uint32_t>(mCore->mQueue.size()));
1106 
1107             // Set up a death notification so that we can disconnect
1108             // automatically if the remote producer dies
1109             if (listener != NULL &&
1110                     IInterface::asBinder(listener)->remoteBinder() != NULL) {
1111                 status = IInterface::asBinder(listener)->linkToDeath(
1112                         static_cast<IBinder::DeathRecipient*>(this));
1113                 if (status != NO_ERROR) {
1114                     BQ_LOGE("connect: linkToDeath failed: %s (%d)",
1115                             strerror(-status), status);
1116                 }
1117             }
1118             mCore->mConnectedProducerListener = listener;
1119             break;
1120         default:
1121             BQ_LOGE("connect: unknown API %d", api);
1122             status = BAD_VALUE;
1123             break;
1124     }
1125 
1126     mCore->mBufferHasBeenQueued = false;
1127     mCore->mDequeueBufferCannotBlock = false;
1128     if (mDequeueTimeout < 0) {
1129         mCore->mDequeueBufferCannotBlock =
1130                 mCore->mConsumerControlledByApp && producerControlledByApp;
1131     }
1132 
1133     mCore->mAllowAllocation = true;
1134     VALIDATE_CONSISTENCY();
1135     return status;
1136 }
1137 
disconnect(int api)1138 status_t BufferQueueProducer::disconnect(int api) {
1139     ATRACE_CALL();
1140     BQ_LOGV("disconnect: api %d", api);
1141 
1142     int status = NO_ERROR;
1143     sp<IConsumerListener> listener;
1144     { // Autolock scope
1145         Mutex::Autolock lock(mCore->mMutex);
1146         mCore->waitWhileAllocatingLocked();
1147 
1148         if (mCore->mIsAbandoned) {
1149             // It's not really an error to disconnect after the surface has
1150             // been abandoned; it should just be a no-op.
1151             return NO_ERROR;
1152         }
1153 
1154         if (api == BufferQueueCore::CURRENTLY_CONNECTED_API) {
1155             api = mCore->mConnectedApi;
1156             // If we're asked to disconnect the currently connected api but
1157             // nobody is connected, it's not really an error.
1158             if (api == BufferQueueCore::NO_CONNECTED_API) {
1159                 return NO_ERROR;
1160             }
1161         }
1162 
1163         switch (api) {
1164             case NATIVE_WINDOW_API_EGL:
1165             case NATIVE_WINDOW_API_CPU:
1166             case NATIVE_WINDOW_API_MEDIA:
1167             case NATIVE_WINDOW_API_CAMERA:
1168                 if (mCore->mConnectedApi == api) {
1169                     mCore->freeAllBuffersLocked();
1170 
1171                     // Remove our death notification callback if we have one
1172                     if (mCore->mConnectedProducerListener != NULL) {
1173                         sp<IBinder> token =
1174                                 IInterface::asBinder(mCore->mConnectedProducerListener);
1175                         // This can fail if we're here because of the death
1176                         // notification, but we just ignore it
1177                         token->unlinkToDeath(
1178                                 static_cast<IBinder::DeathRecipient*>(this));
1179                     }
1180                     mCore->mSharedBufferSlot =
1181                             BufferQueueCore::INVALID_BUFFER_SLOT;
1182                     mCore->mConnectedProducerListener = NULL;
1183                     mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
1184                     mCore->mSidebandStream.clear();
1185                     mCore->mDequeueCondition.broadcast();
1186                     listener = mCore->mConsumerListener;
1187                 } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
1188                     BQ_LOGE("disconnect: still connected to another API "
1189                             "(cur=%d req=%d)", mCore->mConnectedApi, api);
1190                     status = BAD_VALUE;
1191                 }
1192                 break;
1193             default:
1194                 BQ_LOGE("disconnect: unknown API %d", api);
1195                 status = BAD_VALUE;
1196                 break;
1197         }
1198     } // Autolock scope
1199 
1200     // Call back without lock held
1201     if (listener != NULL) {
1202         listener->onBuffersReleased();
1203     }
1204 
1205     return status;
1206 }
1207 
setSidebandStream(const sp<NativeHandle> & stream)1208 status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
1209     sp<IConsumerListener> listener;
1210     { // Autolock scope
1211         Mutex::Autolock _l(mCore->mMutex);
1212         mCore->mSidebandStream = stream;
1213         listener = mCore->mConsumerListener;
1214     } // Autolock scope
1215 
1216     if (listener != NULL) {
1217         listener->onSidebandStreamChanged();
1218     }
1219     return NO_ERROR;
1220 }
1221 
allocateBuffers(uint32_t width,uint32_t height,PixelFormat format,uint32_t usage)1222 void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
1223         PixelFormat format, uint32_t usage) {
1224     ATRACE_CALL();
1225     while (true) {
1226         size_t newBufferCount = 0;
1227         uint32_t allocWidth = 0;
1228         uint32_t allocHeight = 0;
1229         PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN;
1230         uint32_t allocUsage = 0;
1231         { // Autolock scope
1232             Mutex::Autolock lock(mCore->mMutex);
1233             mCore->waitWhileAllocatingLocked();
1234 
1235             if (!mCore->mAllowAllocation) {
1236                 BQ_LOGE("allocateBuffers: allocation is not allowed for this "
1237                         "BufferQueue");
1238                 return;
1239             }
1240 
1241             newBufferCount = mCore->mFreeSlots.size();
1242             if (newBufferCount == 0) {
1243                 return;
1244             }
1245 
1246             allocWidth = width > 0 ? width : mCore->mDefaultWidth;
1247             allocHeight = height > 0 ? height : mCore->mDefaultHeight;
1248             allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
1249             allocUsage = usage | mCore->mConsumerUsageBits;
1250 
1251             mCore->mIsAllocating = true;
1252         } // Autolock scope
1253 
1254         Vector<sp<GraphicBuffer>> buffers;
1255         for (size_t i = 0; i <  newBufferCount; ++i) {
1256             status_t result = NO_ERROR;
1257             sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
1258                     allocWidth, allocHeight, allocFormat, allocUsage, &result));
1259             if (result != NO_ERROR) {
1260                 BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
1261                         " %u, usage %u)", width, height, format, usage);
1262                 Mutex::Autolock lock(mCore->mMutex);
1263                 mCore->mIsAllocating = false;
1264                 mCore->mIsAllocatingCondition.broadcast();
1265                 return;
1266             }
1267             buffers.push_back(graphicBuffer);
1268         }
1269 
1270         { // Autolock scope
1271             Mutex::Autolock lock(mCore->mMutex);
1272             uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
1273             uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
1274             PixelFormat checkFormat = format != 0 ?
1275                     format : mCore->mDefaultBufferFormat;
1276             uint32_t checkUsage = usage | mCore->mConsumerUsageBits;
1277             if (checkWidth != allocWidth || checkHeight != allocHeight ||
1278                 checkFormat != allocFormat || checkUsage != allocUsage) {
1279                 // Something changed while we released the lock. Retry.
1280                 BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying.");
1281                 mCore->mIsAllocating = false;
1282                 mCore->mIsAllocatingCondition.broadcast();
1283                 continue;
1284             }
1285 
1286             for (size_t i = 0; i < newBufferCount; ++i) {
1287                 if (mCore->mFreeSlots.empty()) {
1288                     BQ_LOGV("allocateBuffers: a slot was occupied while "
1289                             "allocating. Dropping allocated buffer.");
1290                     continue;
1291                 }
1292                 auto slot = mCore->mFreeSlots.begin();
1293                 mCore->clearBufferSlotLocked(*slot); // Clean up the slot first
1294                 mSlots[*slot].mGraphicBuffer = buffers[i];
1295                 mSlots[*slot].mFence = Fence::NO_FENCE;
1296 
1297                 // freeBufferLocked puts this slot on the free slots list. Since
1298                 // we then attached a buffer, move the slot to free buffer list.
1299                 mCore->mFreeBuffers.push_front(*slot);
1300 
1301                 BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d",
1302                         *slot);
1303 
1304                 // Make sure the erase is done after all uses of the slot
1305                 // iterator since it will be invalid after this point.
1306                 mCore->mFreeSlots.erase(slot);
1307             }
1308 
1309             mCore->mIsAllocating = false;
1310             mCore->mIsAllocatingCondition.broadcast();
1311             VALIDATE_CONSISTENCY();
1312         } // Autolock scope
1313     }
1314 }
1315 
allowAllocation(bool allow)1316 status_t BufferQueueProducer::allowAllocation(bool allow) {
1317     ATRACE_CALL();
1318     BQ_LOGV("allowAllocation: %s", allow ? "true" : "false");
1319 
1320     Mutex::Autolock lock(mCore->mMutex);
1321     mCore->mAllowAllocation = allow;
1322     return NO_ERROR;
1323 }
1324 
setGenerationNumber(uint32_t generationNumber)1325 status_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) {
1326     ATRACE_CALL();
1327     BQ_LOGV("setGenerationNumber: %u", generationNumber);
1328 
1329     Mutex::Autolock lock(mCore->mMutex);
1330     mCore->mGenerationNumber = generationNumber;
1331     return NO_ERROR;
1332 }
1333 
getConsumerName() const1334 String8 BufferQueueProducer::getConsumerName() const {
1335     ATRACE_CALL();
1336     BQ_LOGV("getConsumerName: %s", mConsumerName.string());
1337     return mConsumerName;
1338 }
1339 
getNextFrameNumber() const1340 uint64_t BufferQueueProducer::getNextFrameNumber() const {
1341     ATRACE_CALL();
1342 
1343     Mutex::Autolock lock(mCore->mMutex);
1344     uint64_t nextFrameNumber = mCore->mFrameCounter + 1;
1345     return nextFrameNumber;
1346 }
1347 
setSharedBufferMode(bool sharedBufferMode)1348 status_t BufferQueueProducer::setSharedBufferMode(bool sharedBufferMode) {
1349     ATRACE_CALL();
1350     BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode);
1351 
1352     Mutex::Autolock lock(mCore->mMutex);
1353     if (!sharedBufferMode) {
1354         mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
1355     }
1356     mCore->mSharedBufferMode = sharedBufferMode;
1357     return NO_ERROR;
1358 }
1359 
setAutoRefresh(bool autoRefresh)1360 status_t BufferQueueProducer::setAutoRefresh(bool autoRefresh) {
1361     ATRACE_CALL();
1362     BQ_LOGV("setAutoRefresh: %d", autoRefresh);
1363 
1364     Mutex::Autolock lock(mCore->mMutex);
1365 
1366     mCore->mAutoRefresh = autoRefresh;
1367     return NO_ERROR;
1368 }
1369 
setDequeueTimeout(nsecs_t timeout)1370 status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) {
1371     ATRACE_CALL();
1372     BQ_LOGV("setDequeueTimeout: %" PRId64, timeout);
1373 
1374     Mutex::Autolock lock(mCore->mMutex);
1375     int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false,
1376             mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked();
1377     if (!mCore->adjustAvailableSlotsLocked(delta)) {
1378         BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of "
1379                 "available slots. Delta = %d", delta);
1380         return BAD_VALUE;
1381     }
1382 
1383     mDequeueTimeout = timeout;
1384     mCore->mDequeueBufferCannotBlock = false;
1385 
1386     VALIDATE_CONSISTENCY();
1387     return NO_ERROR;
1388 }
1389 
getLastQueuedBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence,float outTransformMatrix[16])1390 status_t BufferQueueProducer::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
1391         sp<Fence>* outFence, float outTransformMatrix[16]) {
1392     ATRACE_CALL();
1393     BQ_LOGV("getLastQueuedBuffer");
1394 
1395     Mutex::Autolock lock(mCore->mMutex);
1396     if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) {
1397         *outBuffer = nullptr;
1398         *outFence = Fence::NO_FENCE;
1399         return NO_ERROR;
1400     }
1401 
1402     *outBuffer = mSlots[mCore->mLastQueuedSlot].mGraphicBuffer;
1403     *outFence = mLastQueueBufferFence;
1404 
1405     // Currently only SurfaceFlinger internally ever changes
1406     // GLConsumer's filtering mode, so we just use 'true' here as
1407     // this is slightly specialized for the current client of this API,
1408     // which does want filtering.
1409     GLConsumer::computeTransformMatrix(outTransformMatrix,
1410             mSlots[mCore->mLastQueuedSlot].mGraphicBuffer, mLastQueuedCrop,
1411             mLastQueuedTransform, true /* filter */);
1412 
1413     return NO_ERROR;
1414 }
1415 
binderDied(const wp<android::IBinder> &)1416 void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
1417     // If we're here, it means that a producer we were connected to died.
1418     // We're guaranteed that we are still connected to it because we remove
1419     // this callback upon disconnect. It's therefore safe to read mConnectedApi
1420     // without synchronization here.
1421     int api = mCore->mConnectedApi;
1422     disconnect(api);
1423 }
1424 
getUniqueId(uint64_t * outId) const1425 status_t BufferQueueProducer::getUniqueId(uint64_t* outId) const {
1426     BQ_LOGV("getUniqueId");
1427 
1428     *outId = mCore->mUniqueId;
1429     return NO_ERROR;
1430 }
1431 
1432 } // namespace android
1433