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