• 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             // TODO(http://b/140581935): This message is BQ_LOGW because it
649             // often logs when no actionable errors are present. Return to
650             // using BQ_LOGE after ensuring this only logs during errors.
651             BQ_LOGW("detachBuffer: slot %d is not owned by the producer "
652                     "(state = %s)", slot, mSlots[slot].mBufferState.string());
653             return BAD_VALUE;
654         } else if (!mSlots[slot].mRequestBufferCalled) {
655             BQ_LOGE("detachBuffer: buffer in slot %d has not been requested",
656                     slot);
657             return BAD_VALUE;
658         }
659 
660         listener = mCore->mConsumerListener;
661         auto gb = mSlots[slot].mGraphicBuffer;
662         if (listener != nullptr && gb != nullptr) {
663             listener->onFrameDetached(gb->getId());
664         }
665         mSlots[slot].mBufferState.detachProducer();
666         mCore->mActiveBuffers.erase(slot);
667         mCore->mFreeSlots.insert(slot);
668         mCore->clearBufferSlotLocked(slot);
669         mCore->mDequeueCondition.notify_all();
670         VALIDATE_CONSISTENCY();
671     }
672 
673     if (listener != nullptr) {
674         listener->onBuffersReleased();
675     }
676 
677     return NO_ERROR;
678 }
679 
detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)680 status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
681         sp<Fence>* outFence) {
682     ATRACE_CALL();
683 
684     if (outBuffer == nullptr) {
685         BQ_LOGE("detachNextBuffer: outBuffer must not be NULL");
686         return BAD_VALUE;
687     } else if (outFence == nullptr) {
688         BQ_LOGE("detachNextBuffer: outFence must not be NULL");
689         return BAD_VALUE;
690     }
691 
692     sp<IConsumerListener> listener;
693     {
694         std::unique_lock<std::mutex> lock(mCore->mMutex);
695 
696         if (mCore->mIsAbandoned) {
697             BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
698             return NO_INIT;
699         }
700 
701         if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
702             BQ_LOGE("detachNextBuffer: BufferQueue has no connected producer");
703             return NO_INIT;
704         }
705 
706         if (mCore->mSharedBufferMode) {
707             BQ_LOGE("detachNextBuffer: cannot detach a buffer in shared buffer "
708                     "mode");
709             return BAD_VALUE;
710         }
711 
712         mCore->waitWhileAllocatingLocked(lock);
713 
714         if (mCore->mFreeBuffers.empty()) {
715             return NO_MEMORY;
716         }
717 
718         int found = mCore->mFreeBuffers.front();
719         mCore->mFreeBuffers.remove(found);
720         mCore->mFreeSlots.insert(found);
721 
722         BQ_LOGV("detachNextBuffer detached slot %d", found);
723 
724         *outBuffer = mSlots[found].mGraphicBuffer;
725         *outFence = mSlots[found].mFence;
726         mCore->clearBufferSlotLocked(found);
727         VALIDATE_CONSISTENCY();
728         listener = mCore->mConsumerListener;
729     }
730 
731     if (listener != nullptr) {
732         listener->onBuffersReleased();
733     }
734 
735     return NO_ERROR;
736 }
737 
attachBuffer(int * outSlot,const sp<android::GraphicBuffer> & buffer)738 status_t BufferQueueProducer::attachBuffer(int* outSlot,
739         const sp<android::GraphicBuffer>& buffer) {
740     ATRACE_CALL();
741 
742     if (outSlot == nullptr) {
743         BQ_LOGE("attachBuffer: outSlot must not be NULL");
744         return BAD_VALUE;
745     } else if (buffer == nullptr) {
746         BQ_LOGE("attachBuffer: cannot attach NULL buffer");
747         return BAD_VALUE;
748     }
749 
750     std::unique_lock<std::mutex> lock(mCore->mMutex);
751 
752     if (mCore->mIsAbandoned) {
753         BQ_LOGE("attachBuffer: BufferQueue has been abandoned");
754         return NO_INIT;
755     }
756 
757     if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
758         BQ_LOGE("attachBuffer: BufferQueue has no connected producer");
759         return NO_INIT;
760     }
761 
762     if (mCore->mSharedBufferMode) {
763         BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
764         return BAD_VALUE;
765     }
766 
767     if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
768         BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
769                 "[queue %u]", buffer->getGenerationNumber(),
770                 mCore->mGenerationNumber);
771         return BAD_VALUE;
772     }
773 
774     mCore->waitWhileAllocatingLocked(lock);
775 
776     status_t returnFlags = NO_ERROR;
777     int found;
778     status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Attach, lock, &found);
779     if (status != NO_ERROR) {
780         return status;
781     }
782 
783     // This should not happen
784     if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
785         BQ_LOGE("attachBuffer: no available buffer slots");
786         return -EBUSY;
787     }
788 
789     *outSlot = found;
790     ATRACE_BUFFER_INDEX(*outSlot);
791     BQ_LOGV("attachBuffer: returning slot %d flags=%#x",
792             *outSlot, returnFlags);
793 
794     mSlots[*outSlot].mGraphicBuffer = buffer;
795     mSlots[*outSlot].mBufferState.attachProducer();
796     mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR;
797     mSlots[*outSlot].mFence = Fence::NO_FENCE;
798     mSlots[*outSlot].mRequestBufferCalled = true;
799     mSlots[*outSlot].mAcquireCalled = false;
800     mSlots[*outSlot].mNeedsReallocation = false;
801     mCore->mActiveBuffers.insert(found);
802     VALIDATE_CONSISTENCY();
803 
804     return returnFlags;
805 }
806 
queueBuffer(int slot,const QueueBufferInput & input,QueueBufferOutput * output)807 status_t BufferQueueProducer::queueBuffer(int slot,
808         const QueueBufferInput &input, QueueBufferOutput *output) {
809     ATRACE_CALL();
810     ATRACE_BUFFER_INDEX(slot);
811 
812     int64_t requestedPresentTimestamp;
813     bool isAutoTimestamp;
814     android_dataspace dataSpace;
815     Rect crop(Rect::EMPTY_RECT);
816     int scalingMode;
817     uint32_t transform;
818     uint32_t stickyTransform;
819     sp<Fence> acquireFence;
820     bool getFrameTimestamps = false;
821     input.deflate(&requestedPresentTimestamp, &isAutoTimestamp, &dataSpace,
822             &crop, &scalingMode, &transform, &acquireFence, &stickyTransform,
823             &getFrameTimestamps);
824     const Region& surfaceDamage = input.getSurfaceDamage();
825     const HdrMetadata& hdrMetadata = input.getHdrMetadata();
826 
827     if (acquireFence == nullptr) {
828         BQ_LOGE("queueBuffer: fence is NULL");
829         return BAD_VALUE;
830     }
831 
832     auto acquireFenceTime = std::make_shared<FenceTime>(acquireFence);
833 
834     switch (scalingMode) {
835         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
836         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
837         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
838         case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
839             break;
840         default:
841             BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode);
842             return BAD_VALUE;
843     }
844 
845     sp<IConsumerListener> frameAvailableListener;
846     sp<IConsumerListener> frameReplacedListener;
847     int callbackTicket = 0;
848     uint64_t currentFrameNumber = 0;
849     BufferItem item;
850     { // Autolock scope
851         std::lock_guard<std::mutex> lock(mCore->mMutex);
852 
853         if (mCore->mIsAbandoned) {
854             BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
855             return NO_INIT;
856         }
857 
858         if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
859             BQ_LOGE("queueBuffer: BufferQueue has no connected producer");
860             return NO_INIT;
861         }
862 
863         if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
864             BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)",
865                     slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
866             return BAD_VALUE;
867         } else if (!mSlots[slot].mBufferState.isDequeued()) {
868             BQ_LOGE("queueBuffer: slot %d is not owned by the producer "
869                     "(state = %s)", slot, mSlots[slot].mBufferState.string());
870             return BAD_VALUE;
871         } else if (!mSlots[slot].mRequestBufferCalled) {
872             BQ_LOGE("queueBuffer: slot %d was queued without requesting "
873                     "a buffer", slot);
874             return BAD_VALUE;
875         }
876 
877         // If shared buffer mode has just been enabled, cache the slot of the
878         // first buffer that is queued and mark it as the shared buffer.
879         if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot ==
880                 BufferQueueCore::INVALID_BUFFER_SLOT) {
881             mCore->mSharedBufferSlot = slot;
882             mSlots[slot].mBufferState.mShared = true;
883         }
884 
885         BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d"
886                 " validHdrMetadataTypes=0x%x crop=[%d,%d,%d,%d] transform=%#x scale=%s",
887                 slot, mCore->mFrameCounter + 1, requestedPresentTimestamp, dataSpace,
888                 hdrMetadata.validTypes, crop.left, crop.top, crop.right, crop.bottom,
889                 transform,
890                 BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode)));
891 
892         const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
893         Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
894         Rect croppedRect(Rect::EMPTY_RECT);
895         crop.intersect(bufferRect, &croppedRect);
896         if (croppedRect != crop) {
897             BQ_LOGE("queueBuffer: crop rect is not contained within the "
898                     "buffer in slot %d", slot);
899             return BAD_VALUE;
900         }
901 
902         // Override UNKNOWN dataspace with consumer default
903         if (dataSpace == HAL_DATASPACE_UNKNOWN) {
904             dataSpace = mCore->mDefaultBufferDataSpace;
905         }
906 
907         mSlots[slot].mFence = acquireFence;
908         mSlots[slot].mBufferState.queue();
909 
910         // Increment the frame counter and store a local version of it
911         // for use outside the lock on mCore->mMutex.
912         ++mCore->mFrameCounter;
913         currentFrameNumber = mCore->mFrameCounter;
914         mSlots[slot].mFrameNumber = currentFrameNumber;
915 
916         item.mAcquireCalled = mSlots[slot].mAcquireCalled;
917         item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
918         item.mCrop = crop;
919         item.mTransform = transform &
920                 ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
921         item.mTransformToDisplayInverse =
922                 (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
923         item.mScalingMode = static_cast<uint32_t>(scalingMode);
924         item.mTimestamp = requestedPresentTimestamp;
925         item.mIsAutoTimestamp = isAutoTimestamp;
926         item.mDataSpace = dataSpace;
927         item.mHdrMetadata = hdrMetadata;
928         item.mFrameNumber = currentFrameNumber;
929         item.mSlot = slot;
930         item.mFence = acquireFence;
931         item.mFenceTime = acquireFenceTime;
932         item.mIsDroppable = mCore->mAsyncMode ||
933                 (mConsumerIsSurfaceFlinger && mCore->mQueueBufferCanDrop) ||
934                 (mCore->mLegacyBufferDrop && mCore->mQueueBufferCanDrop) ||
935                 (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == slot);
936         item.mSurfaceDamage = surfaceDamage;
937         item.mQueuedBuffer = true;
938         item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh;
939         item.mApi = mCore->mConnectedApi;
940 
941         mStickyTransform = stickyTransform;
942 
943         // Cache the shared buffer data so that the BufferItem can be recreated.
944         if (mCore->mSharedBufferMode) {
945             mCore->mSharedBufferCache.crop = crop;
946             mCore->mSharedBufferCache.transform = transform;
947             mCore->mSharedBufferCache.scalingMode = static_cast<uint32_t>(
948                     scalingMode);
949             mCore->mSharedBufferCache.dataspace = dataSpace;
950         }
951 
952         output->bufferReplaced = false;
953         if (mCore->mQueue.empty()) {
954             // When the queue is empty, we can ignore mDequeueBufferCannotBlock
955             // and simply queue this buffer
956             mCore->mQueue.push_back(item);
957             frameAvailableListener = mCore->mConsumerListener;
958         } else {
959             // When the queue is not empty, we need to look at the last buffer
960             // in the queue to see if we need to replace it
961             const BufferItem& last = mCore->mQueue.itemAt(
962                     mCore->mQueue.size() - 1);
963             if (last.mIsDroppable) {
964 
965                 if (!last.mIsStale) {
966                     mSlots[last.mSlot].mBufferState.freeQueued();
967 
968                     // After leaving shared buffer mode, the shared buffer will
969                     // still be around. Mark it as no longer shared if this
970                     // operation causes it to be free.
971                     if (!mCore->mSharedBufferMode &&
972                             mSlots[last.mSlot].mBufferState.isFree()) {
973                         mSlots[last.mSlot].mBufferState.mShared = false;
974                     }
975                     // Don't put the shared buffer on the free list.
976                     if (!mSlots[last.mSlot].mBufferState.isShared()) {
977                         mCore->mActiveBuffers.erase(last.mSlot);
978                         mCore->mFreeBuffers.push_back(last.mSlot);
979                         output->bufferReplaced = true;
980                     }
981                 }
982 
983                 // Make sure to merge the damage rect from the frame we're about
984                 // to drop into the new frame's damage rect.
985                 if (last.mSurfaceDamage.bounds() == Rect::INVALID_RECT ||
986                     item.mSurfaceDamage.bounds() == Rect::INVALID_RECT) {
987                     item.mSurfaceDamage = Region::INVALID_REGION;
988                 } else {
989                     item.mSurfaceDamage |= last.mSurfaceDamage;
990                 }
991 
992                 // Overwrite the droppable buffer with the incoming one
993                 mCore->mQueue.editItemAt(mCore->mQueue.size() - 1) = item;
994                 frameReplacedListener = mCore->mConsumerListener;
995             } else {
996                 mCore->mQueue.push_back(item);
997                 frameAvailableListener = mCore->mConsumerListener;
998             }
999         }
1000 
1001         mCore->mBufferHasBeenQueued = true;
1002         mCore->mDequeueCondition.notify_all();
1003         mCore->mLastQueuedSlot = slot;
1004 
1005         output->width = mCore->mDefaultWidth;
1006         output->height = mCore->mDefaultHeight;
1007         output->transformHint = mCore->mTransformHintInUse = mCore->mTransformHint;
1008         output->numPendingBuffers = static_cast<uint32_t>(mCore->mQueue.size());
1009         output->nextFrameNumber = mCore->mFrameCounter + 1;
1010 
1011         ATRACE_INT(mCore->mConsumerName.string(),
1012                 static_cast<int32_t>(mCore->mQueue.size()));
1013 #ifndef NO_BINDER
1014         mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size());
1015 #endif
1016         // Take a ticket for the callback functions
1017         callbackTicket = mNextCallbackTicket++;
1018 
1019         VALIDATE_CONSISTENCY();
1020     } // Autolock scope
1021 
1022     // It is okay not to clear the GraphicBuffer when the consumer is SurfaceFlinger because
1023     // it is guaranteed that the BufferQueue is inside SurfaceFlinger's process and
1024     // there will be no Binder call
1025     if (!mConsumerIsSurfaceFlinger) {
1026         item.mGraphicBuffer.clear();
1027     }
1028 
1029     // Update and get FrameEventHistory.
1030     nsecs_t postedTime = systemTime(SYSTEM_TIME_MONOTONIC);
1031     NewFrameEventsEntry newFrameEventsEntry = {
1032         currentFrameNumber,
1033         postedTime,
1034         requestedPresentTimestamp,
1035         std::move(acquireFenceTime)
1036     };
1037     addAndGetFrameTimestamps(&newFrameEventsEntry,
1038             getFrameTimestamps ? &output->frameTimestamps : nullptr);
1039 
1040     // Call back without the main BufferQueue lock held, but with the callback
1041     // lock held so we can ensure that callbacks occur in order
1042 
1043     int connectedApi;
1044     sp<Fence> lastQueuedFence;
1045 
1046     { // scope for the lock
1047         std::unique_lock<std::mutex> lock(mCallbackMutex);
1048         while (callbackTicket != mCurrentCallbackTicket) {
1049             mCallbackCondition.wait(lock);
1050         }
1051 
1052         if (frameAvailableListener != nullptr) {
1053             frameAvailableListener->onFrameAvailable(item);
1054         } else if (frameReplacedListener != nullptr) {
1055             frameReplacedListener->onFrameReplaced(item);
1056         }
1057 
1058         connectedApi = mCore->mConnectedApi;
1059         lastQueuedFence = std::move(mLastQueueBufferFence);
1060 
1061         mLastQueueBufferFence = std::move(acquireFence);
1062         mLastQueuedCrop = item.mCrop;
1063         mLastQueuedTransform = item.mTransform;
1064 
1065         ++mCurrentCallbackTicket;
1066         mCallbackCondition.notify_all();
1067     }
1068 
1069     // Wait without lock held
1070     if (connectedApi == NATIVE_WINDOW_API_EGL) {
1071         // Waiting here allows for two full buffers to be queued but not a
1072         // third. In the event that frames take varying time, this makes a
1073         // small trade-off in favor of latency rather than throughput.
1074         lastQueuedFence->waitForever("Throttling EGL Production");
1075     }
1076 
1077     return NO_ERROR;
1078 }
1079 
cancelBuffer(int slot,const sp<Fence> & fence)1080 status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
1081     ATRACE_CALL();
1082     BQ_LOGV("cancelBuffer: slot %d", slot);
1083     std::lock_guard<std::mutex> lock(mCore->mMutex);
1084 
1085     if (mCore->mIsAbandoned) {
1086         BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
1087         return NO_INIT;
1088     }
1089 
1090     if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
1091         BQ_LOGE("cancelBuffer: BufferQueue has no connected producer");
1092         return NO_INIT;
1093     }
1094 
1095     if (mCore->mSharedBufferMode) {
1096         BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode");
1097         return BAD_VALUE;
1098     }
1099 
1100     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
1101         BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
1102                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
1103         return BAD_VALUE;
1104     } else if (!mSlots[slot].mBufferState.isDequeued()) {
1105         BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
1106                 "(state = %s)", slot, mSlots[slot].mBufferState.string());
1107         return BAD_VALUE;
1108     } else if (fence == nullptr) {
1109         BQ_LOGE("cancelBuffer: fence is NULL");
1110         return BAD_VALUE;
1111     }
1112 
1113     mSlots[slot].mBufferState.cancel();
1114 
1115     // After leaving shared buffer mode, the shared buffer will still be around.
1116     // Mark it as no longer shared if this operation causes it to be free.
1117     if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
1118         mSlots[slot].mBufferState.mShared = false;
1119     }
1120 
1121     // Don't put the shared buffer on the free list.
1122     if (!mSlots[slot].mBufferState.isShared()) {
1123         mCore->mActiveBuffers.erase(slot);
1124         mCore->mFreeBuffers.push_back(slot);
1125     }
1126 
1127     auto gb = mSlots[slot].mGraphicBuffer;
1128     if (mCore->mConsumerListener != nullptr && gb != nullptr) {
1129         mCore->mConsumerListener->onFrameCancelled(gb->getId());
1130     }
1131     mSlots[slot].mFence = fence;
1132     mCore->mDequeueCondition.notify_all();
1133     VALIDATE_CONSISTENCY();
1134 
1135     return NO_ERROR;
1136 }
1137 
query(int what,int * outValue)1138 int BufferQueueProducer::query(int what, int *outValue) {
1139     ATRACE_CALL();
1140     std::lock_guard<std::mutex> lock(mCore->mMutex);
1141 
1142     if (outValue == nullptr) {
1143         BQ_LOGE("query: outValue was NULL");
1144         return BAD_VALUE;
1145     }
1146 
1147     if (mCore->mIsAbandoned) {
1148         BQ_LOGE("query: BufferQueue has been abandoned");
1149         return NO_INIT;
1150     }
1151 
1152     int value;
1153     switch (what) {
1154         case NATIVE_WINDOW_WIDTH:
1155             value = static_cast<int32_t>(mCore->mDefaultWidth);
1156             break;
1157         case NATIVE_WINDOW_HEIGHT:
1158             value = static_cast<int32_t>(mCore->mDefaultHeight);
1159             break;
1160         case NATIVE_WINDOW_FORMAT:
1161             value = static_cast<int32_t>(mCore->mDefaultBufferFormat);
1162             break;
1163         case NATIVE_WINDOW_LAYER_COUNT:
1164             // All BufferQueue buffers have a single layer.
1165             value = BQ_LAYER_COUNT;
1166             break;
1167         case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
1168             value = mCore->getMinUndequeuedBufferCountLocked();
1169             break;
1170         case NATIVE_WINDOW_STICKY_TRANSFORM:
1171             value = static_cast<int32_t>(mStickyTransform);
1172             break;
1173         case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
1174             value = (mCore->mQueue.size() > 1);
1175             break;
1176         case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
1177             // deprecated; higher 32 bits are truncated
1178             value = static_cast<int32_t>(mCore->mConsumerUsageBits);
1179             break;
1180         case NATIVE_WINDOW_DEFAULT_DATASPACE:
1181             value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace);
1182             break;
1183         case NATIVE_WINDOW_BUFFER_AGE:
1184             if (mCore->mBufferAge > INT32_MAX) {
1185                 value = 0;
1186             } else {
1187                 value = static_cast<int32_t>(mCore->mBufferAge);
1188             }
1189             break;
1190         case NATIVE_WINDOW_CONSUMER_IS_PROTECTED:
1191             value = static_cast<int32_t>(mCore->mConsumerIsProtected);
1192             break;
1193         default:
1194             return BAD_VALUE;
1195     }
1196 
1197     BQ_LOGV("query: %d? %d", what, value);
1198     *outValue = value;
1199     return NO_ERROR;
1200 }
1201 
connect(const sp<IProducerListener> & listener,int api,bool producerControlledByApp,QueueBufferOutput * output)1202 status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
1203         int api, bool producerControlledByApp, QueueBufferOutput *output) {
1204     ATRACE_CALL();
1205     std::lock_guard<std::mutex> lock(mCore->mMutex);
1206     mConsumerName = mCore->mConsumerName;
1207     BQ_LOGV("connect: api=%d producerControlledByApp=%s", api,
1208             producerControlledByApp ? "true" : "false");
1209 
1210     if (mCore->mIsAbandoned) {
1211         BQ_LOGE("connect: BufferQueue has been abandoned");
1212         return NO_INIT;
1213     }
1214 
1215     if (mCore->mConsumerListener == nullptr) {
1216         BQ_LOGE("connect: BufferQueue has no consumer");
1217         return NO_INIT;
1218     }
1219 
1220     if (output == nullptr) {
1221         BQ_LOGE("connect: output was NULL");
1222         return BAD_VALUE;
1223     }
1224 
1225     if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
1226         BQ_LOGE("connect: already connected (cur=%d req=%d)",
1227                 mCore->mConnectedApi, api);
1228         return BAD_VALUE;
1229     }
1230 
1231     int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
1232             mDequeueTimeout < 0 ?
1233             mCore->mConsumerControlledByApp && producerControlledByApp : false,
1234             mCore->mMaxBufferCount) -
1235             mCore->getMaxBufferCountLocked();
1236     if (!mCore->adjustAvailableSlotsLocked(delta)) {
1237         BQ_LOGE("connect: BufferQueue failed to adjust the number of available "
1238                 "slots. Delta = %d", delta);
1239         return BAD_VALUE;
1240     }
1241 
1242     int status = NO_ERROR;
1243     switch (api) {
1244         case NATIVE_WINDOW_API_EGL:
1245         case NATIVE_WINDOW_API_CPU:
1246         case NATIVE_WINDOW_API_MEDIA:
1247         case NATIVE_WINDOW_API_CAMERA:
1248             mCore->mConnectedApi = api;
1249 
1250             output->width = mCore->mDefaultWidth;
1251             output->height = mCore->mDefaultHeight;
1252             output->transformHint = mCore->mTransformHintInUse = mCore->mTransformHint;
1253             output->numPendingBuffers =
1254                     static_cast<uint32_t>(mCore->mQueue.size());
1255             output->nextFrameNumber = mCore->mFrameCounter + 1;
1256             output->bufferReplaced = false;
1257             output->maxBufferCount = mCore->mMaxBufferCount;
1258 
1259             if (listener != nullptr) {
1260                 // Set up a death notification so that we can disconnect
1261                 // automatically if the remote producer dies
1262 #ifndef NO_BINDER
1263                 if (IInterface::asBinder(listener)->remoteBinder() != nullptr) {
1264                     status = IInterface::asBinder(listener)->linkToDeath(
1265                             static_cast<IBinder::DeathRecipient*>(this));
1266                     if (status != NO_ERROR) {
1267                         BQ_LOGE("connect: linkToDeath failed: %s (%d)",
1268                                 strerror(-status), status);
1269                     }
1270                     mCore->mLinkedToDeath = listener;
1271                 }
1272 #endif
1273                 mCore->mConnectedProducerListener = listener;
1274                 mCore->mBufferReleasedCbEnabled = listener->needsReleaseNotify();
1275             }
1276             break;
1277         default:
1278             BQ_LOGE("connect: unknown API %d", api);
1279             status = BAD_VALUE;
1280             break;
1281     }
1282     mCore->mConnectedPid = BufferQueueThreadState::getCallingPid();
1283     mCore->mBufferHasBeenQueued = false;
1284     mCore->mDequeueBufferCannotBlock = false;
1285     mCore->mQueueBufferCanDrop = false;
1286     mCore->mLegacyBufferDrop = true;
1287     if (mCore->mConsumerControlledByApp && producerControlledByApp) {
1288         mCore->mDequeueBufferCannotBlock = mDequeueTimeout < 0;
1289         mCore->mQueueBufferCanDrop = mDequeueTimeout <= 0;
1290     }
1291 
1292     mCore->mAllowAllocation = true;
1293     VALIDATE_CONSISTENCY();
1294     return status;
1295 }
1296 
disconnect(int api,DisconnectMode mode)1297 status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) {
1298     ATRACE_CALL();
1299     BQ_LOGV("disconnect: api %d", api);
1300 
1301     int status = NO_ERROR;
1302     sp<IConsumerListener> listener;
1303     { // Autolock scope
1304         std::unique_lock<std::mutex> lock(mCore->mMutex);
1305 
1306         if (mode == DisconnectMode::AllLocal) {
1307             if (BufferQueueThreadState::getCallingPid() != mCore->mConnectedPid) {
1308                 return NO_ERROR;
1309             }
1310             api = BufferQueueCore::CURRENTLY_CONNECTED_API;
1311         }
1312 
1313         mCore->waitWhileAllocatingLocked(lock);
1314 
1315         if (mCore->mIsAbandoned) {
1316             // It's not really an error to disconnect after the surface has
1317             // been abandoned; it should just be a no-op.
1318             return NO_ERROR;
1319         }
1320 
1321         if (api == BufferQueueCore::CURRENTLY_CONNECTED_API) {
1322             if (mCore->mConnectedApi == NATIVE_WINDOW_API_MEDIA) {
1323                 ALOGD("About to force-disconnect API_MEDIA, mode=%d", mode);
1324             }
1325             api = mCore->mConnectedApi;
1326             // If we're asked to disconnect the currently connected api but
1327             // nobody is connected, it's not really an error.
1328             if (api == BufferQueueCore::NO_CONNECTED_API) {
1329                 return NO_ERROR;
1330             }
1331         }
1332 
1333         switch (api) {
1334             case NATIVE_WINDOW_API_EGL:
1335             case NATIVE_WINDOW_API_CPU:
1336             case NATIVE_WINDOW_API_MEDIA:
1337             case NATIVE_WINDOW_API_CAMERA:
1338                 if (mCore->mConnectedApi == api) {
1339                     mCore->freeAllBuffersLocked();
1340 
1341 #ifndef NO_BINDER
1342                     // Remove our death notification callback if we have one
1343                     if (mCore->mLinkedToDeath != nullptr) {
1344                         sp<IBinder> token =
1345                                 IInterface::asBinder(mCore->mLinkedToDeath);
1346                         // This can fail if we're here because of the death
1347                         // notification, but we just ignore it
1348                         token->unlinkToDeath(
1349                                 static_cast<IBinder::DeathRecipient*>(this));
1350                     }
1351 #endif
1352                     mCore->mSharedBufferSlot =
1353                             BufferQueueCore::INVALID_BUFFER_SLOT;
1354                     mCore->mLinkedToDeath = nullptr;
1355                     mCore->mConnectedProducerListener = nullptr;
1356                     mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
1357                     mCore->mConnectedPid = -1;
1358                     mCore->mSidebandStream.clear();
1359                     mCore->mDequeueCondition.notify_all();
1360                     mCore->mAutoPrerotation = false;
1361                     listener = mCore->mConsumerListener;
1362                 } else if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
1363                     BQ_LOGE("disconnect: not connected (req=%d)", api);
1364                     status = NO_INIT;
1365                 } else {
1366                     BQ_LOGE("disconnect: still connected to another API "
1367                             "(cur=%d req=%d)", mCore->mConnectedApi, api);
1368                     status = BAD_VALUE;
1369                 }
1370                 break;
1371             default:
1372                 BQ_LOGE("disconnect: unknown API %d", api);
1373                 status = BAD_VALUE;
1374                 break;
1375         }
1376     } // Autolock scope
1377 
1378     // Call back without lock held
1379     if (listener != nullptr) {
1380         listener->onBuffersReleased();
1381         listener->onDisconnect();
1382     }
1383 
1384     return status;
1385 }
1386 
setSidebandStream(const sp<NativeHandle> & stream)1387 status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
1388     sp<IConsumerListener> listener;
1389     { // Autolock scope
1390         std::lock_guard<std::mutex> _l(mCore->mMutex);
1391         mCore->mSidebandStream = stream;
1392         listener = mCore->mConsumerListener;
1393     } // Autolock scope
1394 
1395     if (listener != nullptr) {
1396         listener->onSidebandStreamChanged();
1397     }
1398     return NO_ERROR;
1399 }
1400 
allocateBuffers(uint32_t width,uint32_t height,PixelFormat format,uint64_t usage)1401 void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
1402         PixelFormat format, uint64_t usage) {
1403     ATRACE_CALL();
1404 
1405     const bool useDefaultSize = !width && !height;
1406     while (true) {
1407         size_t newBufferCount = 0;
1408         uint32_t allocWidth = 0;
1409         uint32_t allocHeight = 0;
1410         PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN;
1411         uint64_t allocUsage = 0;
1412         std::string allocName;
1413         { // Autolock scope
1414             std::unique_lock<std::mutex> lock(mCore->mMutex);
1415             mCore->waitWhileAllocatingLocked(lock);
1416 
1417             if (!mCore->mAllowAllocation) {
1418                 BQ_LOGE("allocateBuffers: allocation is not allowed for this "
1419                         "BufferQueue");
1420                 return;
1421             }
1422 
1423             // Only allocate one buffer at a time to reduce risks of overlapping an allocation from
1424             // both allocateBuffers and dequeueBuffer.
1425             newBufferCount = mCore->mFreeSlots.empty() ? 0 : 1;
1426             if (newBufferCount == 0) {
1427                 return;
1428             }
1429 
1430             allocWidth = width > 0 ? width : mCore->mDefaultWidth;
1431             allocHeight = height > 0 ? height : mCore->mDefaultHeight;
1432             if (useDefaultSize && mCore->mAutoPrerotation &&
1433                 (mCore->mTransformHintInUse & NATIVE_WINDOW_TRANSFORM_ROT_90)) {
1434                 std::swap(allocWidth, allocHeight);
1435             }
1436 
1437             allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
1438             allocUsage = usage | mCore->mConsumerUsageBits;
1439             allocName.assign(mCore->mConsumerName.string(), mCore->mConsumerName.size());
1440 
1441             mCore->mIsAllocating = true;
1442         } // Autolock scope
1443 
1444         Vector<sp<GraphicBuffer>> buffers;
1445         for (size_t i = 0; i < newBufferCount; ++i) {
1446             sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
1447                     allocWidth, allocHeight, allocFormat, BQ_LAYER_COUNT,
1448                     allocUsage, allocName);
1449 
1450             status_t result = graphicBuffer->initCheck();
1451 
1452             if (result != NO_ERROR) {
1453                 BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
1454                         " %u, usage %#" PRIx64 ")", width, height, format, usage);
1455                 std::lock_guard<std::mutex> lock(mCore->mMutex);
1456                 mCore->mIsAllocating = false;
1457                 mCore->mIsAllocatingCondition.notify_all();
1458                 return;
1459             }
1460             buffers.push_back(graphicBuffer);
1461         }
1462 
1463         { // Autolock scope
1464             std::unique_lock<std::mutex> lock(mCore->mMutex);
1465             uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
1466             uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
1467             if (useDefaultSize && mCore->mAutoPrerotation &&
1468                 (mCore->mTransformHintInUse & NATIVE_WINDOW_TRANSFORM_ROT_90)) {
1469                 std::swap(checkWidth, checkHeight);
1470             }
1471 
1472             PixelFormat checkFormat = format != 0 ?
1473                     format : mCore->mDefaultBufferFormat;
1474             uint64_t checkUsage = usage | mCore->mConsumerUsageBits;
1475             if (checkWidth != allocWidth || checkHeight != allocHeight ||
1476                 checkFormat != allocFormat || checkUsage != allocUsage) {
1477                 // Something changed while we released the lock. Retry.
1478                 BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying.");
1479                 mCore->mIsAllocating = false;
1480                 mCore->mIsAllocatingCondition.notify_all();
1481                 continue;
1482             }
1483 
1484             for (size_t i = 0; i < newBufferCount; ++i) {
1485                 if (mCore->mFreeSlots.empty()) {
1486                     BQ_LOGV("allocateBuffers: a slot was occupied while "
1487                             "allocating. Dropping allocated buffer.");
1488                     continue;
1489                 }
1490                 auto slot = mCore->mFreeSlots.begin();
1491                 mCore->clearBufferSlotLocked(*slot); // Clean up the slot first
1492                 mSlots[*slot].mGraphicBuffer = buffers[i];
1493                 mSlots[*slot].mFence = Fence::NO_FENCE;
1494 
1495                 // freeBufferLocked puts this slot on the free slots list. Since
1496                 // we then attached a buffer, move the slot to free buffer list.
1497                 mCore->mFreeBuffers.push_front(*slot);
1498 
1499                 BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d",
1500                         *slot);
1501 
1502                 // Make sure the erase is done after all uses of the slot
1503                 // iterator since it will be invalid after this point.
1504                 mCore->mFreeSlots.erase(slot);
1505             }
1506 
1507             mCore->mIsAllocating = false;
1508             mCore->mIsAllocatingCondition.notify_all();
1509             VALIDATE_CONSISTENCY();
1510 
1511             // If dequeue is waiting for to allocate a buffer, release the lock until it's not
1512             // waiting anymore so it can use the buffer we just allocated.
1513             while (mDequeueWaitingForAllocation) {
1514                 mDequeueWaitingForAllocationCondition.wait(lock);
1515             }
1516         } // Autolock scope
1517     }
1518 }
1519 
allowAllocation(bool allow)1520 status_t BufferQueueProducer::allowAllocation(bool allow) {
1521     ATRACE_CALL();
1522     BQ_LOGV("allowAllocation: %s", allow ? "true" : "false");
1523 
1524     std::lock_guard<std::mutex> lock(mCore->mMutex);
1525     mCore->mAllowAllocation = allow;
1526     return NO_ERROR;
1527 }
1528 
setGenerationNumber(uint32_t generationNumber)1529 status_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) {
1530     ATRACE_CALL();
1531     BQ_LOGV("setGenerationNumber: %u", generationNumber);
1532 
1533     std::lock_guard<std::mutex> lock(mCore->mMutex);
1534     mCore->mGenerationNumber = generationNumber;
1535     return NO_ERROR;
1536 }
1537 
getConsumerName() const1538 String8 BufferQueueProducer::getConsumerName() const {
1539     ATRACE_CALL();
1540     std::lock_guard<std::mutex> lock(mCore->mMutex);
1541     BQ_LOGV("getConsumerName: %s", mConsumerName.string());
1542     return mConsumerName;
1543 }
1544 
setSharedBufferMode(bool sharedBufferMode)1545 status_t BufferQueueProducer::setSharedBufferMode(bool sharedBufferMode) {
1546     ATRACE_CALL();
1547     BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode);
1548 
1549     std::lock_guard<std::mutex> lock(mCore->mMutex);
1550     if (!sharedBufferMode) {
1551         mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
1552     }
1553     mCore->mSharedBufferMode = sharedBufferMode;
1554     return NO_ERROR;
1555 }
1556 
setAutoRefresh(bool autoRefresh)1557 status_t BufferQueueProducer::setAutoRefresh(bool autoRefresh) {
1558     ATRACE_CALL();
1559     BQ_LOGV("setAutoRefresh: %d", autoRefresh);
1560 
1561     std::lock_guard<std::mutex> lock(mCore->mMutex);
1562 
1563     mCore->mAutoRefresh = autoRefresh;
1564     return NO_ERROR;
1565 }
1566 
setDequeueTimeout(nsecs_t timeout)1567 status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) {
1568     ATRACE_CALL();
1569     BQ_LOGV("setDequeueTimeout: %" PRId64, timeout);
1570 
1571     std::lock_guard<std::mutex> lock(mCore->mMutex);
1572     bool dequeueBufferCannotBlock =
1573             timeout >= 0 ? false : mCore->mDequeueBufferCannotBlock;
1574     int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, dequeueBufferCannotBlock,
1575             mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked();
1576     if (!mCore->adjustAvailableSlotsLocked(delta)) {
1577         BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of "
1578                 "available slots. Delta = %d", delta);
1579         return BAD_VALUE;
1580     }
1581 
1582     mDequeueTimeout = timeout;
1583     mCore->mDequeueBufferCannotBlock = dequeueBufferCannotBlock;
1584     if (timeout > 0) {
1585         mCore->mQueueBufferCanDrop = false;
1586     }
1587 
1588     VALIDATE_CONSISTENCY();
1589     return NO_ERROR;
1590 }
1591 
setLegacyBufferDrop(bool drop)1592 status_t BufferQueueProducer::setLegacyBufferDrop(bool drop) {
1593     ATRACE_CALL();
1594     BQ_LOGV("setLegacyBufferDrop: drop = %d", drop);
1595 
1596     std::lock_guard<std::mutex> lock(mCore->mMutex);
1597     mCore->mLegacyBufferDrop = drop;
1598     return NO_ERROR;
1599 }
1600 
getLastQueuedBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence,float outTransformMatrix[16])1601 status_t BufferQueueProducer::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
1602         sp<Fence>* outFence, float outTransformMatrix[16]) {
1603     ATRACE_CALL();
1604     BQ_LOGV("getLastQueuedBuffer");
1605 
1606     std::lock_guard<std::mutex> lock(mCore->mMutex);
1607     if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) {
1608         *outBuffer = nullptr;
1609         *outFence = Fence::NO_FENCE;
1610         return NO_ERROR;
1611     }
1612 
1613     *outBuffer = mSlots[mCore->mLastQueuedSlot].mGraphicBuffer;
1614     *outFence = mLastQueueBufferFence;
1615 
1616     // Currently only SurfaceFlinger internally ever changes
1617     // GLConsumer's filtering mode, so we just use 'true' here as
1618     // this is slightly specialized for the current client of this API,
1619     // which does want filtering.
1620     GLConsumer::computeTransformMatrix(outTransformMatrix,
1621             mSlots[mCore->mLastQueuedSlot].mGraphicBuffer, mLastQueuedCrop,
1622             mLastQueuedTransform, true /* filter */);
1623 
1624     return NO_ERROR;
1625 }
1626 
getLastQueuedBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence,Rect * outRect,uint32_t * outTransform)1627 status_t BufferQueueProducer::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence,
1628                                                   Rect* outRect, uint32_t* outTransform) {
1629     ATRACE_CALL();
1630     BQ_LOGV("getLastQueuedBuffer");
1631 
1632     std::lock_guard<std::mutex> lock(mCore->mMutex);
1633     if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) {
1634         *outBuffer = nullptr;
1635         *outFence = Fence::NO_FENCE;
1636         return NO_ERROR;
1637     }
1638 
1639     *outBuffer = mSlots[mCore->mLastQueuedSlot].mGraphicBuffer;
1640     *outFence = mLastQueueBufferFence;
1641     *outRect = mLastQueuedCrop;
1642     *outTransform = mLastQueuedTransform;
1643 
1644     return NO_ERROR;
1645 }
1646 
getFrameTimestamps(FrameEventHistoryDelta * outDelta)1647 void BufferQueueProducer::getFrameTimestamps(FrameEventHistoryDelta* outDelta) {
1648     addAndGetFrameTimestamps(nullptr, outDelta);
1649 }
1650 
addAndGetFrameTimestamps(const NewFrameEventsEntry * newTimestamps,FrameEventHistoryDelta * outDelta)1651 void BufferQueueProducer::addAndGetFrameTimestamps(
1652         const NewFrameEventsEntry* newTimestamps,
1653         FrameEventHistoryDelta* outDelta) {
1654     if (newTimestamps == nullptr && outDelta == nullptr) {
1655         return;
1656     }
1657 
1658     ATRACE_CALL();
1659     BQ_LOGV("addAndGetFrameTimestamps");
1660     sp<IConsumerListener> listener;
1661     {
1662         std::lock_guard<std::mutex> lock(mCore->mMutex);
1663         listener = mCore->mConsumerListener;
1664     }
1665     if (listener != nullptr) {
1666         listener->addAndGetFrameTimestamps(newTimestamps, outDelta);
1667     }
1668 }
1669 
binderDied(const wp<android::IBinder> &)1670 void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
1671     // If we're here, it means that a producer we were connected to died.
1672     // We're guaranteed that we are still connected to it because we remove
1673     // this callback upon disconnect. It's therefore safe to read mConnectedApi
1674     // without synchronization here.
1675     int api = mCore->mConnectedApi;
1676     disconnect(api);
1677 }
1678 
getUniqueId(uint64_t * outId) const1679 status_t BufferQueueProducer::getUniqueId(uint64_t* outId) const {
1680     BQ_LOGV("getUniqueId");
1681 
1682     *outId = mCore->mUniqueId;
1683     return NO_ERROR;
1684 }
1685 
getConsumerUsage(uint64_t * outUsage) const1686 status_t BufferQueueProducer::getConsumerUsage(uint64_t* outUsage) const {
1687     BQ_LOGV("getConsumerUsage");
1688 
1689     std::lock_guard<std::mutex> lock(mCore->mMutex);
1690     *outUsage = mCore->mConsumerUsageBits;
1691     return NO_ERROR;
1692 }
1693 
setAutoPrerotation(bool autoPrerotation)1694 status_t BufferQueueProducer::setAutoPrerotation(bool autoPrerotation) {
1695     ATRACE_CALL();
1696     BQ_LOGV("setAutoPrerotation: %d", autoPrerotation);
1697 
1698     std::lock_guard<std::mutex> lock(mCore->mMutex);
1699 
1700     mCore->mAutoPrerotation = autoPrerotation;
1701     return NO_ERROR;
1702 }
1703 
1704 } // namespace android
1705