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