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