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 #define EGL_EGLEXT_PROTOTYPES
24 
25 #include <gui/BufferItem.h>
26 #include <gui/BufferQueueCore.h>
27 #include <gui/BufferQueueProducer.h>
28 #include <gui/IConsumerListener.h>
29 #include <gui/IGraphicBufferAlloc.h>
30 #include <gui/IProducerListener.h>
31 
32 #include <utils/Log.h>
33 #include <utils/Trace.h>
34 
35 namespace android {
36 
BufferQueueProducer(const sp<BufferQueueCore> & core)37 BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) :
38     mCore(core),
39     mSlots(core->mSlots),
40     mConsumerName(),
41     mStickyTransform(0),
42     mLastQueueBufferFence(Fence::NO_FENCE),
43     mCallbackMutex(),
44     mNextCallbackTicket(0),
45     mCurrentCallbackTicket(0),
46     mCallbackCondition() {}
47 
~BufferQueueProducer()48 BufferQueueProducer::~BufferQueueProducer() {}
49 
requestBuffer(int slot,sp<GraphicBuffer> * buf)50 status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
51     ATRACE_CALL();
52     BQ_LOGV("requestBuffer: slot %d", slot);
53     Mutex::Autolock lock(mCore->mMutex);
54 
55     if (mCore->mIsAbandoned) {
56         BQ_LOGE("requestBuffer: BufferQueue has been abandoned");
57         return NO_INIT;
58     }
59 
60     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
61         BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)",
62                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
63         return BAD_VALUE;
64     } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
65         BQ_LOGE("requestBuffer: slot %d is not owned by the producer "
66                 "(state = %d)", slot, mSlots[slot].mBufferState);
67         return BAD_VALUE;
68     }
69 
70     mSlots[slot].mRequestBufferCalled = true;
71     *buf = mSlots[slot].mGraphicBuffer;
72     return NO_ERROR;
73 }
74 
setBufferCount(int bufferCount)75 status_t BufferQueueProducer::setBufferCount(int bufferCount) {
76     ATRACE_CALL();
77     BQ_LOGV("setBufferCount: count = %d", bufferCount);
78 
79     sp<IConsumerListener> listener;
80     { // Autolock scope
81         Mutex::Autolock lock(mCore->mMutex);
82         mCore->waitWhileAllocatingLocked();
83 
84         if (mCore->mIsAbandoned) {
85             BQ_LOGE("setBufferCount: BufferQueue has been abandoned");
86             return NO_INIT;
87         }
88 
89         if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
90             BQ_LOGE("setBufferCount: bufferCount %d too large (max %d)",
91                     bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS);
92             return BAD_VALUE;
93         }
94 
95         // There must be no dequeued buffers when changing the buffer count.
96         for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
97             if (mSlots[s].mBufferState == BufferSlot::DEQUEUED) {
98                 BQ_LOGE("setBufferCount: buffer owned by producer");
99                 return BAD_VALUE;
100             }
101         }
102 
103         if (bufferCount == 0) {
104             mCore->mOverrideMaxBufferCount = 0;
105             mCore->mDequeueCondition.broadcast();
106             return NO_ERROR;
107         }
108 
109         const int minBufferSlots = mCore->getMinMaxBufferCountLocked(false);
110         if (bufferCount < minBufferSlots) {
111             BQ_LOGE("setBufferCount: requested buffer count %d is less than "
112                     "minimum %d", bufferCount, minBufferSlots);
113             return BAD_VALUE;
114         }
115 
116         // Here we are guaranteed that the producer doesn't have any dequeued
117         // buffers and will release all of its buffer references. We don't
118         // clear the queue, however, so that currently queued buffers still
119         // get displayed.
120         mCore->freeAllBuffersLocked();
121         mCore->mOverrideMaxBufferCount = bufferCount;
122         mCore->mDequeueCondition.broadcast();
123         listener = mCore->mConsumerListener;
124     } // Autolock scope
125 
126     // Call back without lock held
127     if (listener != NULL) {
128         listener->onBuffersReleased();
129     }
130 
131     return NO_ERROR;
132 }
133 
waitForFreeSlotThenRelock(const char * caller,bool async,int * found,status_t * returnFlags) const134 status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller,
135         bool async, int* found, status_t* returnFlags) const {
136     bool tryAgain = true;
137     while (tryAgain) {
138         if (mCore->mIsAbandoned) {
139             BQ_LOGE("%s: BufferQueue has been abandoned", caller);
140             return NO_INIT;
141         }
142 
143         const int maxBufferCount = mCore->getMaxBufferCountLocked(async);
144         if (async && mCore->mOverrideMaxBufferCount) {
145             // FIXME: Some drivers are manually setting the buffer count
146             // (which they shouldn't), so we do this extra test here to
147             // handle that case. This is TEMPORARY until we get this fixed.
148             if (mCore->mOverrideMaxBufferCount < maxBufferCount) {
149                 BQ_LOGE("%s: async mode is invalid with buffer count override",
150                         caller);
151                 return BAD_VALUE;
152             }
153         }
154 
155         // Free up any buffers that are in slots beyond the max buffer count
156         for (int s = maxBufferCount; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
157             assert(mSlots[s].mBufferState == BufferSlot::FREE);
158             if (mSlots[s].mGraphicBuffer != NULL) {
159                 mCore->freeBufferLocked(s);
160                 *returnFlags |= RELEASE_ALL_BUFFERS;
161             }
162         }
163 
164         int dequeuedCount = 0;
165         int acquiredCount = 0;
166         for (int s = 0; s < maxBufferCount; ++s) {
167             switch (mSlots[s].mBufferState) {
168                 case BufferSlot::DEQUEUED:
169                     ++dequeuedCount;
170                     break;
171                 case BufferSlot::ACQUIRED:
172                     ++acquiredCount;
173                     break;
174                 default:
175                     break;
176             }
177         }
178 
179         // Producers are not allowed to dequeue more than one buffer if they
180         // did not set a buffer count
181         if (!mCore->mOverrideMaxBufferCount && dequeuedCount) {
182             BQ_LOGE("%s: can't dequeue multiple buffers without setting the "
183                     "buffer count", caller);
184             return INVALID_OPERATION;
185         }
186 
187         // See whether a buffer has been queued since the last
188         // setBufferCount so we know whether to perform the min undequeued
189         // buffers check below
190         if (mCore->mBufferHasBeenQueued) {
191             // Make sure the producer is not trying to dequeue more buffers
192             // than allowed
193             const int newUndequeuedCount =
194                 maxBufferCount - (dequeuedCount + 1);
195             const int minUndequeuedCount =
196                 mCore->getMinUndequeuedBufferCountLocked(async);
197             if (newUndequeuedCount < minUndequeuedCount) {
198                 BQ_LOGE("%s: min undequeued buffer count (%d) exceeded "
199                         "(dequeued=%d undequeued=%d)",
200                         caller, minUndequeuedCount,
201                         dequeuedCount, newUndequeuedCount);
202                 return INVALID_OPERATION;
203             }
204         }
205 
206         *found = BufferQueueCore::INVALID_BUFFER_SLOT;
207 
208         // If we disconnect and reconnect quickly, we can be in a state where
209         // our slots are empty but we have many buffers in the queue. This can
210         // cause us to run out of memory if we outrun the consumer. Wait here if
211         // it looks like we have too many buffers queued up.
212         bool tooManyBuffers = mCore->mQueue.size()
213                             > static_cast<size_t>(maxBufferCount);
214         if (tooManyBuffers) {
215             BQ_LOGV("%s: queue size is %zu, waiting", caller,
216                     mCore->mQueue.size());
217         } else {
218             if (!mCore->mFreeBuffers.empty()) {
219                 auto slot = mCore->mFreeBuffers.begin();
220                 *found = *slot;
221                 mCore->mFreeBuffers.erase(slot);
222             } else if (mCore->mAllowAllocation && !mCore->mFreeSlots.empty()) {
223                 auto slot = mCore->mFreeSlots.begin();
224                 // Only return free slots up to the max buffer count
225                 if (*slot < maxBufferCount) {
226                     *found = *slot;
227                     mCore->mFreeSlots.erase(slot);
228                 }
229             }
230         }
231 
232         // If no buffer is found, or if the queue has too many buffers
233         // outstanding, wait for a buffer to be acquired or released, or for the
234         // max buffer count to change.
235         tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) ||
236                    tooManyBuffers;
237         if (tryAgain) {
238             // Return an error if we're in non-blocking mode (producer and
239             // consumer are controlled by the application).
240             // However, the consumer is allowed to briefly acquire an extra
241             // buffer (which could cause us to have to wait here), which is
242             // okay, since it is only used to implement an atomic acquire +
243             // release (e.g., in GLConsumer::updateTexImage())
244             if (mCore->mDequeueBufferCannotBlock &&
245                     (acquiredCount <= mCore->mMaxAcquiredBufferCount)) {
246                 return WOULD_BLOCK;
247             }
248             mCore->mDequeueCondition.wait(mCore->mMutex);
249         }
250     } // while (tryAgain)
251 
252     return NO_ERROR;
253 }
254 
dequeueBuffer(int * outSlot,sp<android::Fence> * outFence,bool async,uint32_t width,uint32_t height,PixelFormat format,uint32_t usage)255 status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
256         sp<android::Fence> *outFence, bool async,
257         uint32_t width, uint32_t height, PixelFormat format, uint32_t usage) {
258     ATRACE_CALL();
259     { // Autolock scope
260         Mutex::Autolock lock(mCore->mMutex);
261         mConsumerName = mCore->mConsumerName;
262     } // Autolock scope
263 
264     BQ_LOGV("dequeueBuffer: async=%s w=%u h=%u format=%#x, usage=%#x",
265             async ? "true" : "false", width, height, format, usage);
266 
267     if ((width && !height) || (!width && height)) {
268         BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height);
269         return BAD_VALUE;
270     }
271 
272     status_t returnFlags = NO_ERROR;
273     EGLDisplay eglDisplay = EGL_NO_DISPLAY;
274     EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
275     bool attachedByConsumer = false;
276 
277     { // Autolock scope
278         Mutex::Autolock lock(mCore->mMutex);
279         mCore->waitWhileAllocatingLocked();
280 
281         if (format == 0) {
282             format = mCore->mDefaultBufferFormat;
283         }
284 
285         // Enable the usage bits the consumer requested
286         usage |= mCore->mConsumerUsageBits;
287 
288         const bool useDefaultSize = !width && !height;
289         if (useDefaultSize) {
290             width = mCore->mDefaultWidth;
291             height = mCore->mDefaultHeight;
292         }
293 
294         int found = BufferItem::INVALID_BUFFER_SLOT;
295         while (found == BufferItem::INVALID_BUFFER_SLOT) {
296             status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async,
297                     &found, &returnFlags);
298             if (status != NO_ERROR) {
299                 return status;
300             }
301 
302             // This should not happen
303             if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
304                 BQ_LOGE("dequeueBuffer: no available buffer slots");
305                 return -EBUSY;
306             }
307 
308             const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
309 
310             // If we are not allowed to allocate new buffers,
311             // waitForFreeSlotThenRelock must have returned a slot containing a
312             // buffer. If this buffer would require reallocation to meet the
313             // requested attributes, we free it and attempt to get another one.
314             if (!mCore->mAllowAllocation) {
315                 if (buffer->needsReallocation(width, height, format, usage)) {
316                     mCore->freeBufferLocked(found);
317                     found = BufferItem::INVALID_BUFFER_SLOT;
318                     continue;
319                 }
320             }
321         }
322 
323         *outSlot = found;
324         ATRACE_BUFFER_INDEX(found);
325 
326         attachedByConsumer = mSlots[found].mAttachedByConsumer;
327 
328         mSlots[found].mBufferState = BufferSlot::DEQUEUED;
329 
330         const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
331         if ((buffer == NULL) ||
332                 buffer->needsReallocation(width, height, format, usage))
333         {
334             mSlots[found].mAcquireCalled = false;
335             mSlots[found].mGraphicBuffer = NULL;
336             mSlots[found].mRequestBufferCalled = false;
337             mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
338             mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
339             mSlots[found].mFence = Fence::NO_FENCE;
340             mCore->mBufferAge = 0;
341 
342             returnFlags |= BUFFER_NEEDS_REALLOCATION;
343         } else {
344             // We add 1 because that will be the frame number when this buffer
345             // is queued
346             mCore->mBufferAge =
347                     mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber;
348         }
349 
350         BQ_LOGV("dequeueBuffer: setting buffer age to %" PRIu64,
351                 mCore->mBufferAge);
352 
353         if (CC_UNLIKELY(mSlots[found].mFence == NULL)) {
354             BQ_LOGE("dequeueBuffer: about to return a NULL fence - "
355                     "slot=%d w=%d h=%d format=%u",
356                     found, buffer->width, buffer->height, buffer->format);
357         }
358 
359         eglDisplay = mSlots[found].mEglDisplay;
360         eglFence = mSlots[found].mEglFence;
361         *outFence = mSlots[found].mFence;
362         mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
363         mSlots[found].mFence = Fence::NO_FENCE;
364 
365         mCore->validateConsistencyLocked();
366     } // Autolock scope
367 
368     if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
369         status_t error;
370         BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
371         sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
372                 width, height, format, usage, &error));
373         if (graphicBuffer == NULL) {
374             BQ_LOGE("dequeueBuffer: createGraphicBuffer failed");
375             return error;
376         }
377 
378         { // Autolock scope
379             Mutex::Autolock lock(mCore->mMutex);
380 
381             if (mCore->mIsAbandoned) {
382                 BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
383                 return NO_INIT;
384             }
385 
386             graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
387             mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
388         } // Autolock scope
389     }
390 
391     if (attachedByConsumer) {
392         returnFlags |= BUFFER_NEEDS_REALLOCATION;
393     }
394 
395     if (eglFence != EGL_NO_SYNC_KHR) {
396         EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0,
397                 1000000000);
398         // If something goes wrong, log the error, but return the buffer without
399         // synchronizing access to it. It's too late at this point to abort the
400         // dequeue operation.
401         if (result == EGL_FALSE) {
402             BQ_LOGE("dequeueBuffer: error %#x waiting for fence",
403                     eglGetError());
404         } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
405             BQ_LOGE("dequeueBuffer: timeout waiting for fence");
406         }
407         eglDestroySyncKHR(eglDisplay, eglFence);
408     }
409 
410     BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x",
411             *outSlot,
412             mSlots[*outSlot].mFrameNumber,
413             mSlots[*outSlot].mGraphicBuffer->handle, returnFlags);
414 
415     return returnFlags;
416 }
417 
detachBuffer(int slot)418 status_t BufferQueueProducer::detachBuffer(int slot) {
419     ATRACE_CALL();
420     ATRACE_BUFFER_INDEX(slot);
421     BQ_LOGV("detachBuffer(P): slot %d", slot);
422     Mutex::Autolock lock(mCore->mMutex);
423 
424     if (mCore->mIsAbandoned) {
425         BQ_LOGE("detachBuffer(P): BufferQueue has been abandoned");
426         return NO_INIT;
427     }
428 
429     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
430         BQ_LOGE("detachBuffer(P): slot index %d out of range [0, %d)",
431                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
432         return BAD_VALUE;
433     } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
434         BQ_LOGE("detachBuffer(P): slot %d is not owned by the producer "
435                 "(state = %d)", slot, mSlots[slot].mBufferState);
436         return BAD_VALUE;
437     } else if (!mSlots[slot].mRequestBufferCalled) {
438         BQ_LOGE("detachBuffer(P): buffer in slot %d has not been requested",
439                 slot);
440         return BAD_VALUE;
441     }
442 
443     mCore->freeBufferLocked(slot);
444     mCore->mDequeueCondition.broadcast();
445     mCore->validateConsistencyLocked();
446 
447     return NO_ERROR;
448 }
449 
detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)450 status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
451         sp<Fence>* outFence) {
452     ATRACE_CALL();
453 
454     if (outBuffer == NULL) {
455         BQ_LOGE("detachNextBuffer: outBuffer must not be NULL");
456         return BAD_VALUE;
457     } else if (outFence == NULL) {
458         BQ_LOGE("detachNextBuffer: outFence must not be NULL");
459         return BAD_VALUE;
460     }
461 
462     Mutex::Autolock lock(mCore->mMutex);
463     mCore->waitWhileAllocatingLocked();
464 
465     if (mCore->mIsAbandoned) {
466         BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
467         return NO_INIT;
468     }
469 
470     if (mCore->mFreeBuffers.empty()) {
471         return NO_MEMORY;
472     }
473 
474     int found = mCore->mFreeBuffers.front();
475     mCore->mFreeBuffers.remove(found);
476 
477     BQ_LOGV("detachNextBuffer detached slot %d", found);
478 
479     *outBuffer = mSlots[found].mGraphicBuffer;
480     *outFence = mSlots[found].mFence;
481     mCore->freeBufferLocked(found);
482     mCore->validateConsistencyLocked();
483 
484     return NO_ERROR;
485 }
486 
attachBuffer(int * outSlot,const sp<android::GraphicBuffer> & buffer)487 status_t BufferQueueProducer::attachBuffer(int* outSlot,
488         const sp<android::GraphicBuffer>& buffer) {
489     ATRACE_CALL();
490 
491     if (outSlot == NULL) {
492         BQ_LOGE("attachBuffer(P): outSlot must not be NULL");
493         return BAD_VALUE;
494     } else if (buffer == NULL) {
495         BQ_LOGE("attachBuffer(P): cannot attach NULL buffer");
496         return BAD_VALUE;
497     }
498 
499     Mutex::Autolock lock(mCore->mMutex);
500     mCore->waitWhileAllocatingLocked();
501 
502     if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
503         BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
504                 "[queue %u]", buffer->getGenerationNumber(),
505                 mCore->mGenerationNumber);
506         return BAD_VALUE;
507     }
508 
509     status_t returnFlags = NO_ERROR;
510     int found;
511     // TODO: Should we provide an async flag to attachBuffer? It seems
512     // unlikely that buffers which we are attaching to a BufferQueue will
513     // be asynchronous (droppable), but it may not be impossible.
514     status_t status = waitForFreeSlotThenRelock("attachBuffer(P)", false,
515             &found, &returnFlags);
516     if (status != NO_ERROR) {
517         return status;
518     }
519 
520     // This should not happen
521     if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
522         BQ_LOGE("attachBuffer(P): no available buffer slots");
523         return -EBUSY;
524     }
525 
526     *outSlot = found;
527     ATRACE_BUFFER_INDEX(*outSlot);
528     BQ_LOGV("attachBuffer(P): returning slot %d flags=%#x",
529             *outSlot, returnFlags);
530 
531     mSlots[*outSlot].mGraphicBuffer = buffer;
532     mSlots[*outSlot].mBufferState = BufferSlot::DEQUEUED;
533     mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR;
534     mSlots[*outSlot].mFence = Fence::NO_FENCE;
535     mSlots[*outSlot].mRequestBufferCalled = true;
536 
537     mCore->validateConsistencyLocked();
538 
539     return returnFlags;
540 }
541 
queueBuffer(int slot,const QueueBufferInput & input,QueueBufferOutput * output)542 status_t BufferQueueProducer::queueBuffer(int slot,
543         const QueueBufferInput &input, QueueBufferOutput *output) {
544     ATRACE_CALL();
545     ATRACE_BUFFER_INDEX(slot);
546 
547     int64_t timestamp;
548     bool isAutoTimestamp;
549     android_dataspace dataSpace;
550     Rect crop;
551     int scalingMode;
552     uint32_t transform;
553     uint32_t stickyTransform;
554     bool async;
555     sp<Fence> fence;
556     input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode,
557             &transform, &async, &fence, &stickyTransform);
558     Region surfaceDamage = input.getSurfaceDamage();
559 
560     if (fence == NULL) {
561         BQ_LOGE("queueBuffer: fence is NULL");
562         return BAD_VALUE;
563     }
564 
565     switch (scalingMode) {
566         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
567         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
568         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
569         case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
570             break;
571         default:
572             BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode);
573             return BAD_VALUE;
574     }
575 
576     sp<IConsumerListener> frameAvailableListener;
577     sp<IConsumerListener> frameReplacedListener;
578     int callbackTicket = 0;
579     BufferItem item;
580     { // Autolock scope
581         Mutex::Autolock lock(mCore->mMutex);
582 
583         if (mCore->mIsAbandoned) {
584             BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
585             return NO_INIT;
586         }
587 
588         const int maxBufferCount = mCore->getMaxBufferCountLocked(async);
589         if (async && mCore->mOverrideMaxBufferCount) {
590             // FIXME: Some drivers are manually setting the buffer count
591             // (which they shouldn't), so we do this extra test here to
592             // handle that case. This is TEMPORARY until we get this fixed.
593             if (mCore->mOverrideMaxBufferCount < maxBufferCount) {
594                 BQ_LOGE("queueBuffer: async mode is invalid with "
595                         "buffer count override");
596                 return BAD_VALUE;
597             }
598         }
599 
600         if (slot < 0 || slot >= maxBufferCount) {
601             BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)",
602                     slot, maxBufferCount);
603             return BAD_VALUE;
604         } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
605             BQ_LOGE("queueBuffer: slot %d is not owned by the producer "
606                     "(state = %d)", slot, mSlots[slot].mBufferState);
607             return BAD_VALUE;
608         } else if (!mSlots[slot].mRequestBufferCalled) {
609             BQ_LOGE("queueBuffer: slot %d was queued without requesting "
610                     "a buffer", slot);
611             return BAD_VALUE;
612         }
613 
614         BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d"
615                 " crop=[%d,%d,%d,%d] transform=%#x scale=%s",
616                 slot, mCore->mFrameCounter + 1, timestamp, dataSpace,
617                 crop.left, crop.top, crop.right, crop.bottom, transform,
618                 BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode)));
619 
620         const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
621         Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
622         Rect croppedRect;
623         crop.intersect(bufferRect, &croppedRect);
624         if (croppedRect != crop) {
625             BQ_LOGE("queueBuffer: crop rect is not contained within the "
626                     "buffer in slot %d", slot);
627             return BAD_VALUE;
628         }
629 
630         // Override UNKNOWN dataspace with consumer default
631         if (dataSpace == HAL_DATASPACE_UNKNOWN) {
632             dataSpace = mCore->mDefaultBufferDataSpace;
633         }
634 
635         mSlots[slot].mFence = fence;
636         mSlots[slot].mBufferState = BufferSlot::QUEUED;
637         ++mCore->mFrameCounter;
638         mSlots[slot].mFrameNumber = mCore->mFrameCounter;
639 
640         item.mAcquireCalled = mSlots[slot].mAcquireCalled;
641         item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
642         item.mCrop = crop;
643         item.mTransform = transform &
644                 ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
645         item.mTransformToDisplayInverse =
646                 (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
647         item.mScalingMode = static_cast<uint32_t>(scalingMode);
648         item.mTimestamp = timestamp;
649         item.mIsAutoTimestamp = isAutoTimestamp;
650         item.mDataSpace = dataSpace;
651         item.mFrameNumber = mCore->mFrameCounter;
652         item.mSlot = slot;
653         item.mFence = fence;
654         item.mIsDroppable = mCore->mDequeueBufferCannotBlock || async;
655         item.mSurfaceDamage = surfaceDamage;
656 
657         mStickyTransform = stickyTransform;
658 
659         if (mCore->mQueue.empty()) {
660             // When the queue is empty, we can ignore mDequeueBufferCannotBlock
661             // and simply queue this buffer
662             mCore->mQueue.push_back(item);
663             frameAvailableListener = mCore->mConsumerListener;
664         } else {
665             // When the queue is not empty, we need to look at the front buffer
666             // state to see if we need to replace it
667             BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
668             if (front->mIsDroppable) {
669                 // If the front queued buffer is still being tracked, we first
670                 // mark it as freed
671                 if (mCore->stillTracking(front)) {
672                     mSlots[front->mSlot].mBufferState = BufferSlot::FREE;
673                     mCore->mFreeBuffers.push_front(front->mSlot);
674                 }
675                 // Overwrite the droppable buffer with the incoming one
676                 *front = item;
677                 frameReplacedListener = mCore->mConsumerListener;
678             } else {
679                 mCore->mQueue.push_back(item);
680                 frameAvailableListener = mCore->mConsumerListener;
681             }
682         }
683 
684         mCore->mBufferHasBeenQueued = true;
685         mCore->mDequeueCondition.broadcast();
686 
687         output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
688                 mCore->mTransformHint,
689                 static_cast<uint32_t>(mCore->mQueue.size()));
690 
691         ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
692 
693         // Take a ticket for the callback functions
694         callbackTicket = mNextCallbackTicket++;
695 
696         mCore->validateConsistencyLocked();
697     } // Autolock scope
698 
699     // Wait without lock held
700     if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
701         // Waiting here allows for two full buffers to be queued but not a
702         // third. In the event that frames take varying time, this makes a
703         // small trade-off in favor of latency rather than throughput.
704         mLastQueueBufferFence->waitForever("Throttling EGL Production");
705         mLastQueueBufferFence = fence;
706     }
707 
708     // Don't send the GraphicBuffer through the callback, and don't send
709     // the slot number, since the consumer shouldn't need it
710     item.mGraphicBuffer.clear();
711     item.mSlot = BufferItem::INVALID_BUFFER_SLOT;
712 
713     // Call back without the main BufferQueue lock held, but with the callback
714     // lock held so we can ensure that callbacks occur in order
715     {
716         Mutex::Autolock lock(mCallbackMutex);
717         while (callbackTicket != mCurrentCallbackTicket) {
718             mCallbackCondition.wait(mCallbackMutex);
719         }
720 
721         if (frameAvailableListener != NULL) {
722             frameAvailableListener->onFrameAvailable(item);
723         } else if (frameReplacedListener != NULL) {
724             frameReplacedListener->onFrameReplaced(item);
725         }
726 
727         ++mCurrentCallbackTicket;
728         mCallbackCondition.broadcast();
729     }
730 
731     return NO_ERROR;
732 }
733 
cancelBuffer(int slot,const sp<Fence> & fence)734 void BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
735     ATRACE_CALL();
736     BQ_LOGV("cancelBuffer: slot %d", slot);
737     Mutex::Autolock lock(mCore->mMutex);
738 
739     if (mCore->mIsAbandoned) {
740         BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
741         return;
742     }
743 
744     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
745         BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
746                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
747         return;
748     } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
749         BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
750                 "(state = %d)", slot, mSlots[slot].mBufferState);
751         return;
752     } else if (fence == NULL) {
753         BQ_LOGE("cancelBuffer: fence is NULL");
754         return;
755     }
756 
757     mCore->mFreeBuffers.push_front(slot);
758     mSlots[slot].mBufferState = BufferSlot::FREE;
759     mSlots[slot].mFence = fence;
760     mCore->mDequeueCondition.broadcast();
761     mCore->validateConsistencyLocked();
762 }
763 
query(int what,int * outValue)764 int BufferQueueProducer::query(int what, int *outValue) {
765     ATRACE_CALL();
766     Mutex::Autolock lock(mCore->mMutex);
767 
768     if (outValue == NULL) {
769         BQ_LOGE("query: outValue was NULL");
770         return BAD_VALUE;
771     }
772 
773     if (mCore->mIsAbandoned) {
774         BQ_LOGE("query: BufferQueue has been abandoned");
775         return NO_INIT;
776     }
777 
778     int value;
779     switch (what) {
780         case NATIVE_WINDOW_WIDTH:
781             value = static_cast<int32_t>(mCore->mDefaultWidth);
782             break;
783         case NATIVE_WINDOW_HEIGHT:
784             value = static_cast<int32_t>(mCore->mDefaultHeight);
785             break;
786         case NATIVE_WINDOW_FORMAT:
787             value = static_cast<int32_t>(mCore->mDefaultBufferFormat);
788             break;
789         case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
790             value = mCore->getMinUndequeuedBufferCountLocked(false);
791             break;
792         case NATIVE_WINDOW_STICKY_TRANSFORM:
793             value = static_cast<int32_t>(mStickyTransform);
794             break;
795         case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
796             value = (mCore->mQueue.size() > 1);
797             break;
798         case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
799             value = static_cast<int32_t>(mCore->mConsumerUsageBits);
800             break;
801         case NATIVE_WINDOW_DEFAULT_DATASPACE:
802             value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace);
803             break;
804         case NATIVE_WINDOW_BUFFER_AGE:
805             if (mCore->mBufferAge > INT32_MAX) {
806                 value = 0;
807             } else {
808                 value = static_cast<int32_t>(mCore->mBufferAge);
809             }
810             break;
811         default:
812             return BAD_VALUE;
813     }
814 
815     BQ_LOGV("query: %d? %d", what, value);
816     *outValue = value;
817     return NO_ERROR;
818 }
819 
connect(const sp<IProducerListener> & listener,int api,bool producerControlledByApp,QueueBufferOutput * output)820 status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
821         int api, bool producerControlledByApp, QueueBufferOutput *output) {
822     ATRACE_CALL();
823     Mutex::Autolock lock(mCore->mMutex);
824     mConsumerName = mCore->mConsumerName;
825     BQ_LOGV("connect(P): api=%d producerControlledByApp=%s", api,
826             producerControlledByApp ? "true" : "false");
827 
828     if (mCore->mIsAbandoned) {
829         BQ_LOGE("connect(P): BufferQueue has been abandoned");
830         return NO_INIT;
831     }
832 
833     if (mCore->mConsumerListener == NULL) {
834         BQ_LOGE("connect(P): BufferQueue has no consumer");
835         return NO_INIT;
836     }
837 
838     if (output == NULL) {
839         BQ_LOGE("connect(P): output was NULL");
840         return BAD_VALUE;
841     }
842 
843     if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
844         BQ_LOGE("connect(P): already connected (cur=%d req=%d)",
845                 mCore->mConnectedApi, api);
846         return BAD_VALUE;
847     }
848 
849     int status = NO_ERROR;
850     switch (api) {
851         case NATIVE_WINDOW_API_EGL:
852         case NATIVE_WINDOW_API_CPU:
853         case NATIVE_WINDOW_API_MEDIA:
854         case NATIVE_WINDOW_API_CAMERA:
855             mCore->mConnectedApi = api;
856             output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
857                     mCore->mTransformHint,
858                     static_cast<uint32_t>(mCore->mQueue.size()));
859 
860             // Set up a death notification so that we can disconnect
861             // automatically if the remote producer dies
862             if (listener != NULL &&
863                     IInterface::asBinder(listener)->remoteBinder() != NULL) {
864                 status = IInterface::asBinder(listener)->linkToDeath(
865                         static_cast<IBinder::DeathRecipient*>(this));
866                 if (status != NO_ERROR) {
867                     BQ_LOGE("connect(P): linkToDeath failed: %s (%d)",
868                             strerror(-status), status);
869                 }
870             }
871             mCore->mConnectedProducerListener = listener;
872             break;
873         default:
874             BQ_LOGE("connect(P): unknown API %d", api);
875             status = BAD_VALUE;
876             break;
877     }
878 
879     mCore->mBufferHasBeenQueued = false;
880     mCore->mDequeueBufferCannotBlock =
881             mCore->mConsumerControlledByApp && producerControlledByApp;
882     mCore->mAllowAllocation = true;
883 
884     return status;
885 }
886 
disconnect(int api)887 status_t BufferQueueProducer::disconnect(int api) {
888     ATRACE_CALL();
889     BQ_LOGV("disconnect(P): api %d", api);
890 
891     int status = NO_ERROR;
892     sp<IConsumerListener> listener;
893     { // Autolock scope
894         Mutex::Autolock lock(mCore->mMutex);
895         mCore->waitWhileAllocatingLocked();
896 
897         if (mCore->mIsAbandoned) {
898             // It's not really an error to disconnect after the surface has
899             // been abandoned; it should just be a no-op.
900             return NO_ERROR;
901         }
902 
903         switch (api) {
904             case NATIVE_WINDOW_API_EGL:
905             case NATIVE_WINDOW_API_CPU:
906             case NATIVE_WINDOW_API_MEDIA:
907             case NATIVE_WINDOW_API_CAMERA:
908                 if (mCore->mConnectedApi == api) {
909                     mCore->freeAllBuffersLocked();
910 
911                     // Remove our death notification callback if we have one
912                     if (mCore->mConnectedProducerListener != NULL) {
913                         sp<IBinder> token =
914                                 IInterface::asBinder(mCore->mConnectedProducerListener);
915                         // This can fail if we're here because of the death
916                         // notification, but we just ignore it
917                         token->unlinkToDeath(
918                                 static_cast<IBinder::DeathRecipient*>(this));
919                     }
920                     mCore->mConnectedProducerListener = NULL;
921                     mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
922                     mCore->mSidebandStream.clear();
923                     mCore->mDequeueCondition.broadcast();
924                     listener = mCore->mConsumerListener;
925                 } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
926                     BQ_LOGE("disconnect(P): still connected to another API "
927                             "(cur=%d req=%d)", mCore->mConnectedApi, api);
928                     status = BAD_VALUE;
929                 }
930                 break;
931             default:
932                 BQ_LOGE("disconnect(P): unknown API %d", api);
933                 status = BAD_VALUE;
934                 break;
935         }
936     } // Autolock scope
937 
938     // Call back without lock held
939     if (listener != NULL) {
940         listener->onBuffersReleased();
941     }
942 
943     return status;
944 }
945 
setSidebandStream(const sp<NativeHandle> & stream)946 status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
947     sp<IConsumerListener> listener;
948     { // Autolock scope
949         Mutex::Autolock _l(mCore->mMutex);
950         mCore->mSidebandStream = stream;
951         listener = mCore->mConsumerListener;
952     } // Autolock scope
953 
954     if (listener != NULL) {
955         listener->onSidebandStreamChanged();
956     }
957     return NO_ERROR;
958 }
959 
allocateBuffers(bool async,uint32_t width,uint32_t height,PixelFormat format,uint32_t usage)960 void BufferQueueProducer::allocateBuffers(bool async, uint32_t width,
961         uint32_t height, PixelFormat format, uint32_t usage) {
962     ATRACE_CALL();
963     while (true) {
964         Vector<int> freeSlots;
965         size_t newBufferCount = 0;
966         uint32_t allocWidth = 0;
967         uint32_t allocHeight = 0;
968         PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN;
969         uint32_t allocUsage = 0;
970         { // Autolock scope
971             Mutex::Autolock lock(mCore->mMutex);
972             mCore->waitWhileAllocatingLocked();
973 
974             if (!mCore->mAllowAllocation) {
975                 BQ_LOGE("allocateBuffers: allocation is not allowed for this "
976                         "BufferQueue");
977                 return;
978             }
979 
980             int currentBufferCount = 0;
981             for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) {
982                 if (mSlots[slot].mGraphicBuffer != NULL) {
983                     ++currentBufferCount;
984                 } else {
985                     if (mSlots[slot].mBufferState != BufferSlot::FREE) {
986                         BQ_LOGE("allocateBuffers: slot %d without buffer is not FREE",
987                                 slot);
988                         continue;
989                     }
990 
991                     freeSlots.push_back(slot);
992                 }
993             }
994 
995             int maxBufferCount = mCore->getMaxBufferCountLocked(async);
996             BQ_LOGV("allocateBuffers: allocating from %d buffers up to %d buffers",
997                     currentBufferCount, maxBufferCount);
998             if (maxBufferCount <= currentBufferCount)
999                 return;
1000             newBufferCount =
1001                     static_cast<size_t>(maxBufferCount - currentBufferCount);
1002             if (freeSlots.size() < newBufferCount) {
1003                 BQ_LOGE("allocateBuffers: ran out of free slots");
1004                 return;
1005             }
1006             allocWidth = width > 0 ? width : mCore->mDefaultWidth;
1007             allocHeight = height > 0 ? height : mCore->mDefaultHeight;
1008             allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
1009             allocUsage = usage | mCore->mConsumerUsageBits;
1010 
1011             mCore->mIsAllocating = true;
1012         } // Autolock scope
1013 
1014         Vector<sp<GraphicBuffer>> buffers;
1015         for (size_t i = 0; i <  newBufferCount; ++i) {
1016             status_t result = NO_ERROR;
1017             sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
1018                     allocWidth, allocHeight, allocFormat, allocUsage, &result));
1019             if (result != NO_ERROR) {
1020                 BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
1021                         " %u, usage %u)", width, height, format, usage);
1022                 Mutex::Autolock lock(mCore->mMutex);
1023                 mCore->mIsAllocating = false;
1024                 mCore->mIsAllocatingCondition.broadcast();
1025                 return;
1026             }
1027             buffers.push_back(graphicBuffer);
1028         }
1029 
1030         { // Autolock scope
1031             Mutex::Autolock lock(mCore->mMutex);
1032             uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
1033             uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
1034             PixelFormat checkFormat = format != 0 ?
1035                     format : mCore->mDefaultBufferFormat;
1036             uint32_t checkUsage = usage | mCore->mConsumerUsageBits;
1037             if (checkWidth != allocWidth || checkHeight != allocHeight ||
1038                 checkFormat != allocFormat || checkUsage != allocUsage) {
1039                 // Something changed while we released the lock. Retry.
1040                 BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying.");
1041                 mCore->mIsAllocating = false;
1042                 mCore->mIsAllocatingCondition.broadcast();
1043                 continue;
1044             }
1045 
1046             for (size_t i = 0; i < newBufferCount; ++i) {
1047                 int slot = freeSlots[i];
1048                 if (mSlots[slot].mBufferState != BufferSlot::FREE) {
1049                     // A consumer allocated the FREE slot with attachBuffer. Discard the buffer we
1050                     // allocated.
1051                     BQ_LOGV("allocateBuffers: slot %d was acquired while allocating. "
1052                             "Dropping allocated buffer.", slot);
1053                     continue;
1054                 }
1055                 mCore->freeBufferLocked(slot); // Clean up the slot first
1056                 mSlots[slot].mGraphicBuffer = buffers[i];
1057                 mSlots[slot].mFence = Fence::NO_FENCE;
1058 
1059                 // freeBufferLocked puts this slot on the free slots list. Since
1060                 // we then attached a buffer, move the slot to free buffer list.
1061                 mCore->mFreeSlots.erase(slot);
1062                 mCore->mFreeBuffers.push_front(slot);
1063 
1064                 BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", slot);
1065             }
1066 
1067             mCore->mIsAllocating = false;
1068             mCore->mIsAllocatingCondition.broadcast();
1069             mCore->validateConsistencyLocked();
1070         } // Autolock scope
1071     }
1072 }
1073 
allowAllocation(bool allow)1074 status_t BufferQueueProducer::allowAllocation(bool allow) {
1075     ATRACE_CALL();
1076     BQ_LOGV("allowAllocation: %s", allow ? "true" : "false");
1077 
1078     Mutex::Autolock lock(mCore->mMutex);
1079     mCore->mAllowAllocation = allow;
1080     return NO_ERROR;
1081 }
1082 
setGenerationNumber(uint32_t generationNumber)1083 status_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) {
1084     ATRACE_CALL();
1085     BQ_LOGV("setGenerationNumber: %u", generationNumber);
1086 
1087     Mutex::Autolock lock(mCore->mMutex);
1088     mCore->mGenerationNumber = generationNumber;
1089     return NO_ERROR;
1090 }
1091 
getConsumerName() const1092 String8 BufferQueueProducer::getConsumerName() const {
1093     ATRACE_CALL();
1094     BQ_LOGV("getConsumerName: %s", mConsumerName.string());
1095     return mConsumerName;
1096 }
1097 
binderDied(const wp<android::IBinder> &)1098 void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
1099     // If we're here, it means that a producer we were connected to died.
1100     // We're guaranteed that we are still connected to it because we remove
1101     // this callback upon disconnect. It's therefore safe to read mConnectedApi
1102     // without synchronization here.
1103     int api = mCore->mConnectedApi;
1104     disconnect(api);
1105 }
1106 
1107 } // namespace android
1108