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