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