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     const Region& surfaceDamage = input.getSurfaceDamage();
768     const HdrMetadata& hdrMetadata = input.getHdrMetadata();
769 
770     if (acquireFence == NULL) {
771         BQ_LOGE("queueBuffer: fence is NULL");
772         return BAD_VALUE;
773     }
774 
775     auto acquireFenceTime = std::make_shared<FenceTime>(acquireFence);
776 
777     switch (scalingMode) {
778         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
779         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
780         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
781         case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
782             break;
783         default:
784             BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode);
785             return BAD_VALUE;
786     }
787 
788     sp<IConsumerListener> frameAvailableListener;
789     sp<IConsumerListener> frameReplacedListener;
790     int callbackTicket = 0;
791     uint64_t currentFrameNumber = 0;
792     BufferItem item;
793     { // Autolock scope
794         Mutex::Autolock lock(mCore->mMutex);
795 
796         if (mCore->mIsAbandoned) {
797             BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
798             return NO_INIT;
799         }
800 
801         if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
802             BQ_LOGE("queueBuffer: BufferQueue has no connected producer");
803             return NO_INIT;
804         }
805 
806         if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
807             BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)",
808                     slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
809             return BAD_VALUE;
810         } else if (!mSlots[slot].mBufferState.isDequeued()) {
811             BQ_LOGE("queueBuffer: slot %d is not owned by the producer "
812                     "(state = %s)", slot, mSlots[slot].mBufferState.string());
813             return BAD_VALUE;
814         } else if (!mSlots[slot].mRequestBufferCalled) {
815             BQ_LOGE("queueBuffer: slot %d was queued without requesting "
816                     "a buffer", slot);
817             return BAD_VALUE;
818         }
819 
820         // If shared buffer mode has just been enabled, cache the slot of the
821         // first buffer that is queued and mark it as the shared buffer.
822         if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot ==
823                 BufferQueueCore::INVALID_BUFFER_SLOT) {
824             mCore->mSharedBufferSlot = slot;
825             mSlots[slot].mBufferState.mShared = true;
826         }
827 
828         BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d"
829                 " validHdrMetadataTypes=0x%x crop=[%d,%d,%d,%d] transform=%#x scale=%s",
830                 slot, mCore->mFrameCounter + 1, requestedPresentTimestamp, dataSpace,
831                 hdrMetadata.validTypes, crop.left, crop.top, crop.right, crop.bottom,
832                 transform,
833                 BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode)));
834 
835         const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
836         Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
837         Rect croppedRect(Rect::EMPTY_RECT);
838         crop.intersect(bufferRect, &croppedRect);
839         if (croppedRect != crop) {
840             BQ_LOGE("queueBuffer: crop rect is not contained within the "
841                     "buffer in slot %d", slot);
842             return BAD_VALUE;
843         }
844 
845         // Override UNKNOWN dataspace with consumer default
846         if (dataSpace == HAL_DATASPACE_UNKNOWN) {
847             dataSpace = mCore->mDefaultBufferDataSpace;
848         }
849 
850         mSlots[slot].mFence = acquireFence;
851         mSlots[slot].mBufferState.queue();
852 
853         // Increment the frame counter and store a local version of it
854         // for use outside the lock on mCore->mMutex.
855         ++mCore->mFrameCounter;
856         currentFrameNumber = mCore->mFrameCounter;
857         mSlots[slot].mFrameNumber = currentFrameNumber;
858 
859         item.mAcquireCalled = mSlots[slot].mAcquireCalled;
860         item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
861         item.mCrop = crop;
862         item.mTransform = transform &
863                 ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
864         item.mTransformToDisplayInverse =
865                 (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
866         item.mScalingMode = static_cast<uint32_t>(scalingMode);
867         item.mTimestamp = requestedPresentTimestamp;
868         item.mIsAutoTimestamp = isAutoTimestamp;
869         item.mDataSpace = dataSpace;
870         item.mHdrMetadata = hdrMetadata;
871         item.mFrameNumber = currentFrameNumber;
872         item.mSlot = slot;
873         item.mFence = acquireFence;
874         item.mFenceTime = acquireFenceTime;
875         item.mIsDroppable = mCore->mAsyncMode ||
876                 mCore->mDequeueBufferCannotBlock ||
877                 (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == slot);
878         item.mSurfaceDamage = surfaceDamage;
879         item.mQueuedBuffer = true;
880         item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh;
881         item.mApi = mCore->mConnectedApi;
882 
883         mStickyTransform = stickyTransform;
884 
885         // Cache the shared buffer data so that the BufferItem can be recreated.
886         if (mCore->mSharedBufferMode) {
887             mCore->mSharedBufferCache.crop = crop;
888             mCore->mSharedBufferCache.transform = transform;
889             mCore->mSharedBufferCache.scalingMode = static_cast<uint32_t>(
890                     scalingMode);
891             mCore->mSharedBufferCache.dataspace = dataSpace;
892         }
893 
894         output->bufferReplaced = false;
895         if (mCore->mQueue.empty()) {
896             // When the queue is empty, we can ignore mDequeueBufferCannotBlock
897             // and simply queue this buffer
898             mCore->mQueue.push_back(item);
899             frameAvailableListener = mCore->mConsumerListener;
900         } else {
901             // When the queue is not empty, we need to look at the last buffer
902             // in the queue to see if we need to replace it
903             const BufferItem& last = mCore->mQueue.itemAt(
904                     mCore->mQueue.size() - 1);
905             if (last.mIsDroppable) {
906 
907                 if (!last.mIsStale) {
908                     mSlots[last.mSlot].mBufferState.freeQueued();
909 
910                     // After leaving shared buffer mode, the shared buffer will
911                     // still be around. Mark it as no longer shared if this
912                     // operation causes it to be free.
913                     if (!mCore->mSharedBufferMode &&
914                             mSlots[last.mSlot].mBufferState.isFree()) {
915                         mSlots[last.mSlot].mBufferState.mShared = false;
916                     }
917                     // Don't put the shared buffer on the free list.
918                     if (!mSlots[last.mSlot].mBufferState.isShared()) {
919                         mCore->mActiveBuffers.erase(last.mSlot);
920                         mCore->mFreeBuffers.push_back(last.mSlot);
921                         output->bufferReplaced = true;
922                     }
923                 }
924 
925                 // Overwrite the droppable buffer with the incoming one
926                 mCore->mQueue.editItemAt(mCore->mQueue.size() - 1) = item;
927                 frameReplacedListener = mCore->mConsumerListener;
928             } else {
929                 mCore->mQueue.push_back(item);
930                 frameAvailableListener = mCore->mConsumerListener;
931             }
932         }
933 
934         mCore->mBufferHasBeenQueued = true;
935         mCore->mDequeueCondition.broadcast();
936         mCore->mLastQueuedSlot = slot;
937 
938         output->width = mCore->mDefaultWidth;
939         output->height = mCore->mDefaultHeight;
940         output->transformHint = mCore->mTransformHint;
941         output->numPendingBuffers = static_cast<uint32_t>(mCore->mQueue.size());
942         output->nextFrameNumber = mCore->mFrameCounter + 1;
943 
944         ATRACE_INT(mCore->mConsumerName.string(),
945                 static_cast<int32_t>(mCore->mQueue.size()));
946         mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size());
947 
948         // Take a ticket for the callback functions
949         callbackTicket = mNextCallbackTicket++;
950 
951         VALIDATE_CONSISTENCY();
952     } // Autolock scope
953 
954     // It is okay not to clear the GraphicBuffer when the consumer is SurfaceFlinger because
955     // it is guaranteed that the BufferQueue is inside SurfaceFlinger's process and
956     // there will be no Binder call
957     if (!mConsumerIsSurfaceFlinger) {
958         item.mGraphicBuffer.clear();
959     }
960 
961     // Don't send the slot number through the callback since the consumer shouldn't need it
962     item.mSlot = BufferItem::INVALID_BUFFER_SLOT;
963 
964     // Call back without the main BufferQueue lock held, but with the callback
965     // lock held so we can ensure that callbacks occur in order
966 
967     int connectedApi;
968     sp<Fence> lastQueuedFence;
969 
970     { // scope for the lock
971         Mutex::Autolock lock(mCallbackMutex);
972         while (callbackTicket != mCurrentCallbackTicket) {
973             mCallbackCondition.wait(mCallbackMutex);
974         }
975 
976         if (frameAvailableListener != NULL) {
977             frameAvailableListener->onFrameAvailable(item);
978         } else if (frameReplacedListener != NULL) {
979             frameReplacedListener->onFrameReplaced(item);
980         }
981 
982         connectedApi = mCore->mConnectedApi;
983         lastQueuedFence = std::move(mLastQueueBufferFence);
984 
985         mLastQueueBufferFence = std::move(acquireFence);
986         mLastQueuedCrop = item.mCrop;
987         mLastQueuedTransform = item.mTransform;
988 
989         ++mCurrentCallbackTicket;
990         mCallbackCondition.broadcast();
991     }
992 
993     // Wait without lock held
994     if (connectedApi == NATIVE_WINDOW_API_EGL) {
995         // Waiting here allows for two full buffers to be queued but not a
996         // third. In the event that frames take varying time, this makes a
997         // small trade-off in favor of latency rather than throughput.
998         lastQueuedFence->waitForever("Throttling EGL Production");
999     }
1000 
1001     // Update and get FrameEventHistory.
1002     nsecs_t postedTime = systemTime(SYSTEM_TIME_MONOTONIC);
1003     NewFrameEventsEntry newFrameEventsEntry = {
1004         currentFrameNumber,
1005         postedTime,
1006         requestedPresentTimestamp,
1007         std::move(acquireFenceTime)
1008     };
1009     addAndGetFrameTimestamps(&newFrameEventsEntry,
1010             getFrameTimestamps ? &output->frameTimestamps : nullptr);
1011 
1012     return NO_ERROR;
1013 }
1014 
cancelBuffer(int slot,const sp<Fence> & fence)1015 status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
1016     ATRACE_CALL();
1017     BQ_LOGV("cancelBuffer: slot %d", slot);
1018     Mutex::Autolock lock(mCore->mMutex);
1019 
1020     if (mCore->mIsAbandoned) {
1021         BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
1022         return NO_INIT;
1023     }
1024 
1025     if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
1026         BQ_LOGE("cancelBuffer: BufferQueue has no connected producer");
1027         return NO_INIT;
1028     }
1029 
1030     if (mCore->mSharedBufferMode) {
1031         BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode");
1032         return BAD_VALUE;
1033     }
1034 
1035     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
1036         BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
1037                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
1038         return BAD_VALUE;
1039     } else if (!mSlots[slot].mBufferState.isDequeued()) {
1040         BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
1041                 "(state = %s)", slot, mSlots[slot].mBufferState.string());
1042         return BAD_VALUE;
1043     } else if (fence == NULL) {
1044         BQ_LOGE("cancelBuffer: fence is NULL");
1045         return BAD_VALUE;
1046     }
1047 
1048     mSlots[slot].mBufferState.cancel();
1049 
1050     // After leaving shared buffer mode, the shared buffer will still be around.
1051     // Mark it as no longer shared if this operation causes it to be free.
1052     if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
1053         mSlots[slot].mBufferState.mShared = false;
1054     }
1055 
1056     // Don't put the shared buffer on the free list.
1057     if (!mSlots[slot].mBufferState.isShared()) {
1058         mCore->mActiveBuffers.erase(slot);
1059         mCore->mFreeBuffers.push_back(slot);
1060     }
1061 
1062     mSlots[slot].mFence = fence;
1063     mCore->mDequeueCondition.broadcast();
1064     VALIDATE_CONSISTENCY();
1065 
1066     return NO_ERROR;
1067 }
1068 
query(int what,int * outValue)1069 int BufferQueueProducer::query(int what, int *outValue) {
1070     ATRACE_CALL();
1071     Mutex::Autolock lock(mCore->mMutex);
1072 
1073     if (outValue == NULL) {
1074         BQ_LOGE("query: outValue was NULL");
1075         return BAD_VALUE;
1076     }
1077 
1078     if (mCore->mIsAbandoned) {
1079         BQ_LOGE("query: BufferQueue has been abandoned");
1080         return NO_INIT;
1081     }
1082 
1083     int value;
1084     switch (what) {
1085         case NATIVE_WINDOW_WIDTH:
1086             value = static_cast<int32_t>(mCore->mDefaultWidth);
1087             break;
1088         case NATIVE_WINDOW_HEIGHT:
1089             value = static_cast<int32_t>(mCore->mDefaultHeight);
1090             break;
1091         case NATIVE_WINDOW_FORMAT:
1092             value = static_cast<int32_t>(mCore->mDefaultBufferFormat);
1093             break;
1094         case NATIVE_WINDOW_LAYER_COUNT:
1095             // All BufferQueue buffers have a single layer.
1096             value = BQ_LAYER_COUNT;
1097             break;
1098         case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
1099             value = mCore->getMinUndequeuedBufferCountLocked();
1100             break;
1101         case NATIVE_WINDOW_STICKY_TRANSFORM:
1102             value = static_cast<int32_t>(mStickyTransform);
1103             break;
1104         case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
1105             value = (mCore->mQueue.size() > 1);
1106             break;
1107         case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
1108             // deprecated; higher 32 bits are truncated
1109             value = static_cast<int32_t>(mCore->mConsumerUsageBits);
1110             break;
1111         case NATIVE_WINDOW_DEFAULT_DATASPACE:
1112             value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace);
1113             break;
1114         case NATIVE_WINDOW_BUFFER_AGE:
1115             if (mCore->mBufferAge > INT32_MAX) {
1116                 value = 0;
1117             } else {
1118                 value = static_cast<int32_t>(mCore->mBufferAge);
1119             }
1120             break;
1121         case NATIVE_WINDOW_CONSUMER_IS_PROTECTED:
1122             value = static_cast<int32_t>(mCore->mConsumerIsProtected);
1123             break;
1124         case NATIVE_WINDOW_MAX_BUFFER_COUNT:
1125             value = static_cast<int32_t>(mCore->mMaxBufferCount);
1126             break;
1127         default:
1128             return BAD_VALUE;
1129     }
1130 
1131     BQ_LOGV("query: %d? %d", what, value);
1132     *outValue = value;
1133     return NO_ERROR;
1134 }
1135 
connect(const sp<IProducerListener> & listener,int api,bool producerControlledByApp,QueueBufferOutput * output)1136 status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
1137         int api, bool producerControlledByApp, QueueBufferOutput *output) {
1138     ATRACE_CALL();
1139     Mutex::Autolock lock(mCore->mMutex);
1140     mConsumerName = mCore->mConsumerName;
1141     BQ_LOGV("connect: api=%d producerControlledByApp=%s", api,
1142             producerControlledByApp ? "true" : "false");
1143 
1144     if (mCore->mIsAbandoned) {
1145         BQ_LOGE("connect: BufferQueue has been abandoned");
1146         return NO_INIT;
1147     }
1148 
1149     if (mCore->mConsumerListener == NULL) {
1150         BQ_LOGE("connect: BufferQueue has no consumer");
1151         return NO_INIT;
1152     }
1153 
1154     if (output == NULL) {
1155         BQ_LOGE("connect: output was NULL");
1156         return BAD_VALUE;
1157     }
1158 
1159     if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
1160         BQ_LOGE("connect: already connected (cur=%d req=%d)",
1161                 mCore->mConnectedApi, api);
1162         return BAD_VALUE;
1163     }
1164 
1165     int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
1166             mDequeueTimeout < 0 ?
1167             mCore->mConsumerControlledByApp && producerControlledByApp : false,
1168             mCore->mMaxBufferCount) -
1169             mCore->getMaxBufferCountLocked();
1170     if (!mCore->adjustAvailableSlotsLocked(delta)) {
1171         BQ_LOGE("connect: BufferQueue failed to adjust the number of available "
1172                 "slots. Delta = %d", delta);
1173         return BAD_VALUE;
1174     }
1175 
1176     int status = NO_ERROR;
1177     switch (api) {
1178         case NATIVE_WINDOW_API_EGL:
1179         case NATIVE_WINDOW_API_CPU:
1180         case NATIVE_WINDOW_API_MEDIA:
1181         case NATIVE_WINDOW_API_CAMERA:
1182             mCore->mConnectedApi = api;
1183 
1184             output->width = mCore->mDefaultWidth;
1185             output->height = mCore->mDefaultHeight;
1186             output->transformHint = mCore->mTransformHint;
1187             output->numPendingBuffers =
1188                     static_cast<uint32_t>(mCore->mQueue.size());
1189             output->nextFrameNumber = mCore->mFrameCounter + 1;
1190             output->bufferReplaced = false;
1191 
1192             if (listener != NULL) {
1193                 // Set up a death notification so that we can disconnect
1194                 // automatically if the remote producer dies
1195                 if (IInterface::asBinder(listener)->remoteBinder() != NULL) {
1196                     status = IInterface::asBinder(listener)->linkToDeath(
1197                             static_cast<IBinder::DeathRecipient*>(this));
1198                     if (status != NO_ERROR) {
1199                         BQ_LOGE("connect: linkToDeath failed: %s (%d)",
1200                                 strerror(-status), status);
1201                     }
1202                     mCore->mLinkedToDeath = listener;
1203                 }
1204                 if (listener->needsReleaseNotify()) {
1205                     mCore->mConnectedProducerListener = listener;
1206                 }
1207             }
1208             break;
1209         default:
1210             BQ_LOGE("connect: unknown API %d", api);
1211             status = BAD_VALUE;
1212             break;
1213     }
1214     mCore->mConnectedPid = IPCThreadState::self()->getCallingPid();
1215     mCore->mBufferHasBeenQueued = false;
1216     mCore->mDequeueBufferCannotBlock = false;
1217     if (mDequeueTimeout < 0) {
1218         mCore->mDequeueBufferCannotBlock =
1219                 mCore->mConsumerControlledByApp && producerControlledByApp;
1220     }
1221 
1222     mCore->mAllowAllocation = true;
1223     VALIDATE_CONSISTENCY();
1224     return status;
1225 }
1226 
disconnect(int api,DisconnectMode mode)1227 status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) {
1228     ATRACE_CALL();
1229     BQ_LOGV("disconnect: api %d", api);
1230 
1231     int status = NO_ERROR;
1232     sp<IConsumerListener> listener;
1233     { // Autolock scope
1234         Mutex::Autolock lock(mCore->mMutex);
1235 
1236         if (mode == DisconnectMode::AllLocal) {
1237             if (IPCThreadState::self()->getCallingPid() != mCore->mConnectedPid) {
1238                 return NO_ERROR;
1239             }
1240             api = BufferQueueCore::CURRENTLY_CONNECTED_API;
1241         }
1242 
1243         mCore->waitWhileAllocatingLocked();
1244 
1245         if (mCore->mIsAbandoned) {
1246             // It's not really an error to disconnect after the surface has
1247             // been abandoned; it should just be a no-op.
1248             return NO_ERROR;
1249         }
1250 
1251         if (api == BufferQueueCore::CURRENTLY_CONNECTED_API) {
1252             if (mCore->mConnectedApi == NATIVE_WINDOW_API_MEDIA) {
1253                 ALOGD("About to force-disconnect API_MEDIA, mode=%d", mode);
1254             }
1255             api = mCore->mConnectedApi;
1256             // If we're asked to disconnect the currently connected api but
1257             // nobody is connected, it's not really an error.
1258             if (api == BufferQueueCore::NO_CONNECTED_API) {
1259                 return NO_ERROR;
1260             }
1261         }
1262 
1263         switch (api) {
1264             case NATIVE_WINDOW_API_EGL:
1265             case NATIVE_WINDOW_API_CPU:
1266             case NATIVE_WINDOW_API_MEDIA:
1267             case NATIVE_WINDOW_API_CAMERA:
1268                 if (mCore->mConnectedApi == api) {
1269                     mCore->freeAllBuffersLocked();
1270 
1271                     // Remove our death notification callback if we have one
1272                     if (mCore->mLinkedToDeath != NULL) {
1273                         sp<IBinder> token =
1274                                 IInterface::asBinder(mCore->mLinkedToDeath);
1275                         // This can fail if we're here because of the death
1276                         // notification, but we just ignore it
1277                         token->unlinkToDeath(
1278                                 static_cast<IBinder::DeathRecipient*>(this));
1279                     }
1280                     mCore->mSharedBufferSlot =
1281                             BufferQueueCore::INVALID_BUFFER_SLOT;
1282                     mCore->mLinkedToDeath = NULL;
1283                     mCore->mConnectedProducerListener = NULL;
1284                     mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
1285                     mCore->mConnectedPid = -1;
1286                     mCore->mSidebandStream.clear();
1287                     mCore->mDequeueCondition.broadcast();
1288                     listener = mCore->mConsumerListener;
1289                 } else if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
1290                     BQ_LOGE("disconnect: not connected (req=%d)", api);
1291                     status = NO_INIT;
1292                 } else {
1293                     BQ_LOGE("disconnect: still connected to another API "
1294                             "(cur=%d req=%d)", mCore->mConnectedApi, api);
1295                     status = BAD_VALUE;
1296                 }
1297                 break;
1298             default:
1299                 BQ_LOGE("disconnect: unknown API %d", api);
1300                 status = BAD_VALUE;
1301                 break;
1302         }
1303     } // Autolock scope
1304 
1305     // Call back without lock held
1306     if (listener != NULL) {
1307         listener->onBuffersReleased();
1308         listener->onDisconnect();
1309     }
1310 
1311     return status;
1312 }
1313 
setSidebandStream(const sp<NativeHandle> & stream)1314 status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
1315     sp<IConsumerListener> listener;
1316     { // Autolock scope
1317         Mutex::Autolock _l(mCore->mMutex);
1318         mCore->mSidebandStream = stream;
1319         listener = mCore->mConsumerListener;
1320     } // Autolock scope
1321 
1322     if (listener != NULL) {
1323         listener->onSidebandStreamChanged();
1324     }
1325     return NO_ERROR;
1326 }
1327 
allocateBuffers(uint32_t width,uint32_t height,PixelFormat format,uint64_t usage)1328 void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
1329         PixelFormat format, uint64_t usage) {
1330     ATRACE_CALL();
1331     while (true) {
1332         size_t newBufferCount = 0;
1333         uint32_t allocWidth = 0;
1334         uint32_t allocHeight = 0;
1335         PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN;
1336         uint64_t allocUsage = 0;
1337         std::string allocName;
1338         { // Autolock scope
1339             Mutex::Autolock lock(mCore->mMutex);
1340             mCore->waitWhileAllocatingLocked();
1341 
1342             if (!mCore->mAllowAllocation) {
1343                 BQ_LOGE("allocateBuffers: allocation is not allowed for this "
1344                         "BufferQueue");
1345                 return;
1346             }
1347 
1348             newBufferCount = mCore->mFreeSlots.size();
1349             if (newBufferCount == 0) {
1350                 return;
1351             }
1352 
1353             allocWidth = width > 0 ? width : mCore->mDefaultWidth;
1354             allocHeight = height > 0 ? height : mCore->mDefaultHeight;
1355             allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
1356             allocUsage = usage | mCore->mConsumerUsageBits;
1357             allocName.assign(mCore->mConsumerName.string(), mCore->mConsumerName.size());
1358 
1359             mCore->mIsAllocating = true;
1360         } // Autolock scope
1361 
1362         Vector<sp<GraphicBuffer>> buffers;
1363         for (size_t i = 0; i <  newBufferCount; ++i) {
1364             sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
1365                     allocWidth, allocHeight, allocFormat, BQ_LAYER_COUNT,
1366                     allocUsage, allocName);
1367 
1368             status_t result = graphicBuffer->initCheck();
1369 
1370             if (result != NO_ERROR) {
1371                 BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
1372                         " %u, usage %#" PRIx64 ")", width, height, format, usage);
1373                 Mutex::Autolock lock(mCore->mMutex);
1374                 mCore->mIsAllocating = false;
1375                 mCore->mIsAllocatingCondition.broadcast();
1376                 return;
1377             }
1378             buffers.push_back(graphicBuffer);
1379         }
1380 
1381         { // Autolock scope
1382             Mutex::Autolock lock(mCore->mMutex);
1383             uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
1384             uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
1385             PixelFormat checkFormat = format != 0 ?
1386                     format : mCore->mDefaultBufferFormat;
1387             uint64_t checkUsage = usage | mCore->mConsumerUsageBits;
1388             if (checkWidth != allocWidth || checkHeight != allocHeight ||
1389                 checkFormat != allocFormat || checkUsage != allocUsage) {
1390                 // Something changed while we released the lock. Retry.
1391                 BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying.");
1392                 mCore->mIsAllocating = false;
1393                 mCore->mIsAllocatingCondition.broadcast();
1394                 continue;
1395             }
1396 
1397             for (size_t i = 0; i < newBufferCount; ++i) {
1398                 if (mCore->mFreeSlots.empty()) {
1399                     BQ_LOGV("allocateBuffers: a slot was occupied while "
1400                             "allocating. Dropping allocated buffer.");
1401                     continue;
1402                 }
1403                 auto slot = mCore->mFreeSlots.begin();
1404                 mCore->clearBufferSlotLocked(*slot); // Clean up the slot first
1405                 mSlots[*slot].mGraphicBuffer = buffers[i];
1406                 mSlots[*slot].mFence = Fence::NO_FENCE;
1407 
1408                 // freeBufferLocked puts this slot on the free slots list. Since
1409                 // we then attached a buffer, move the slot to free buffer list.
1410                 mCore->mFreeBuffers.push_front(*slot);
1411 
1412                 BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d",
1413                         *slot);
1414 
1415                 // Make sure the erase is done after all uses of the slot
1416                 // iterator since it will be invalid after this point.
1417                 mCore->mFreeSlots.erase(slot);
1418             }
1419 
1420             mCore->mIsAllocating = false;
1421             mCore->mIsAllocatingCondition.broadcast();
1422             VALIDATE_CONSISTENCY();
1423         } // Autolock scope
1424     }
1425 }
1426 
allowAllocation(bool allow)1427 status_t BufferQueueProducer::allowAllocation(bool allow) {
1428     ATRACE_CALL();
1429     BQ_LOGV("allowAllocation: %s", allow ? "true" : "false");
1430 
1431     Mutex::Autolock lock(mCore->mMutex);
1432     mCore->mAllowAllocation = allow;
1433     return NO_ERROR;
1434 }
1435 
setGenerationNumber(uint32_t generationNumber)1436 status_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) {
1437     ATRACE_CALL();
1438     BQ_LOGV("setGenerationNumber: %u", generationNumber);
1439 
1440     Mutex::Autolock lock(mCore->mMutex);
1441     mCore->mGenerationNumber = generationNumber;
1442     return NO_ERROR;
1443 }
1444 
getConsumerName() const1445 String8 BufferQueueProducer::getConsumerName() const {
1446     ATRACE_CALL();
1447     Mutex::Autolock lock(mCore->mMutex);
1448     BQ_LOGV("getConsumerName: %s", mConsumerName.string());
1449     return mConsumerName;
1450 }
1451 
setSharedBufferMode(bool sharedBufferMode)1452 status_t BufferQueueProducer::setSharedBufferMode(bool sharedBufferMode) {
1453     ATRACE_CALL();
1454     BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode);
1455 
1456     Mutex::Autolock lock(mCore->mMutex);
1457     if (!sharedBufferMode) {
1458         mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
1459     }
1460     mCore->mSharedBufferMode = sharedBufferMode;
1461     return NO_ERROR;
1462 }
1463 
setAutoRefresh(bool autoRefresh)1464 status_t BufferQueueProducer::setAutoRefresh(bool autoRefresh) {
1465     ATRACE_CALL();
1466     BQ_LOGV("setAutoRefresh: %d", autoRefresh);
1467 
1468     Mutex::Autolock lock(mCore->mMutex);
1469 
1470     mCore->mAutoRefresh = autoRefresh;
1471     return NO_ERROR;
1472 }
1473 
setDequeueTimeout(nsecs_t timeout)1474 status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) {
1475     ATRACE_CALL();
1476     BQ_LOGV("setDequeueTimeout: %" PRId64, timeout);
1477 
1478     Mutex::Autolock lock(mCore->mMutex);
1479     int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false,
1480             mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked();
1481     if (!mCore->adjustAvailableSlotsLocked(delta)) {
1482         BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of "
1483                 "available slots. Delta = %d", delta);
1484         return BAD_VALUE;
1485     }
1486 
1487     mDequeueTimeout = timeout;
1488     mCore->mDequeueBufferCannotBlock = false;
1489 
1490     VALIDATE_CONSISTENCY();
1491     return NO_ERROR;
1492 }
1493 
getLastQueuedBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence,float outTransformMatrix[16])1494 status_t BufferQueueProducer::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
1495         sp<Fence>* outFence, float outTransformMatrix[16]) {
1496     ATRACE_CALL();
1497     BQ_LOGV("getLastQueuedBuffer");
1498 
1499     Mutex::Autolock lock(mCore->mMutex);
1500     if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) {
1501         *outBuffer = nullptr;
1502         *outFence = Fence::NO_FENCE;
1503         return NO_ERROR;
1504     }
1505 
1506     *outBuffer = mSlots[mCore->mLastQueuedSlot].mGraphicBuffer;
1507     *outFence = mLastQueueBufferFence;
1508 
1509     // Currently only SurfaceFlinger internally ever changes
1510     // GLConsumer's filtering mode, so we just use 'true' here as
1511     // this is slightly specialized for the current client of this API,
1512     // which does want filtering.
1513     GLConsumer::computeTransformMatrix(outTransformMatrix,
1514             mSlots[mCore->mLastQueuedSlot].mGraphicBuffer, mLastQueuedCrop,
1515             mLastQueuedTransform, true /* filter */);
1516 
1517     return NO_ERROR;
1518 }
1519 
getFrameTimestamps(FrameEventHistoryDelta * outDelta)1520 void BufferQueueProducer::getFrameTimestamps(FrameEventHistoryDelta* outDelta) {
1521     addAndGetFrameTimestamps(nullptr, outDelta);
1522 }
1523 
addAndGetFrameTimestamps(const NewFrameEventsEntry * newTimestamps,FrameEventHistoryDelta * outDelta)1524 void BufferQueueProducer::addAndGetFrameTimestamps(
1525         const NewFrameEventsEntry* newTimestamps,
1526         FrameEventHistoryDelta* outDelta) {
1527     if (newTimestamps == nullptr && outDelta == nullptr) {
1528         return;
1529     }
1530 
1531     ATRACE_CALL();
1532     BQ_LOGV("addAndGetFrameTimestamps");
1533     sp<IConsumerListener> listener;
1534     {
1535         Mutex::Autolock lock(mCore->mMutex);
1536         listener = mCore->mConsumerListener;
1537     }
1538     if (listener != NULL) {
1539         listener->addAndGetFrameTimestamps(newTimestamps, outDelta);
1540     }
1541 }
1542 
binderDied(const wp<android::IBinder> &)1543 void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
1544     // If we're here, it means that a producer we were connected to died.
1545     // We're guaranteed that we are still connected to it because we remove
1546     // this callback upon disconnect. It's therefore safe to read mConnectedApi
1547     // without synchronization here.
1548     int api = mCore->mConnectedApi;
1549     disconnect(api);
1550 }
1551 
getUniqueId(uint64_t * outId) const1552 status_t BufferQueueProducer::getUniqueId(uint64_t* outId) const {
1553     BQ_LOGV("getUniqueId");
1554 
1555     *outId = mCore->mUniqueId;
1556     return NO_ERROR;
1557 }
1558 
getConsumerUsage(uint64_t * outUsage) const1559 status_t BufferQueueProducer::getConsumerUsage(uint64_t* outUsage) const {
1560     BQ_LOGV("getConsumerUsage");
1561 
1562     Mutex::Autolock lock(mCore->mMutex);
1563     *outUsage = mCore->mConsumerUsageBits;
1564     return NO_ERROR;
1565 }
1566 
1567 } // namespace android
1568