• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <inttypes.h>
18 
19 #define LOG_TAG "BufferQueueProducer"
20 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
21 //#define LOG_NDEBUG 0
22 
23 #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         // Look for a free buffer to give to the client
165         *found = BufferQueueCore::INVALID_BUFFER_SLOT;
166         int dequeuedCount = 0;
167         int acquiredCount = 0;
168         for (int s = 0; s < maxBufferCount; ++s) {
169             switch (mSlots[s].mBufferState) {
170                 case BufferSlot::DEQUEUED:
171                     ++dequeuedCount;
172                     break;
173                 case BufferSlot::ACQUIRED:
174                     ++acquiredCount;
175                     break;
176                 case BufferSlot::FREE:
177                     // We return the oldest of the free buffers to avoid
178                     // stalling the producer if possible, since the consumer
179                     // may still have pending reads of in-flight buffers
180                     if (*found == BufferQueueCore::INVALID_BUFFER_SLOT ||
181                             mSlots[s].mFrameNumber < mSlots[*found].mFrameNumber) {
182                         *found = s;
183                     }
184                     break;
185                 default:
186                     break;
187             }
188         }
189 
190         // Producers are not allowed to dequeue more than one buffer if they
191         // did not set a buffer count
192         if (!mCore->mOverrideMaxBufferCount && dequeuedCount) {
193             BQ_LOGE("%s: can't dequeue multiple buffers without setting the "
194                     "buffer count", caller);
195             return INVALID_OPERATION;
196         }
197 
198         // See whether a buffer has been queued since the last
199         // setBufferCount so we know whether to perform the min undequeued
200         // buffers check below
201         if (mCore->mBufferHasBeenQueued) {
202             // Make sure the producer is not trying to dequeue more buffers
203             // than allowed
204             const int newUndequeuedCount =
205                 maxBufferCount - (dequeuedCount + 1);
206             const int minUndequeuedCount =
207                 mCore->getMinUndequeuedBufferCountLocked(async);
208             if (newUndequeuedCount < minUndequeuedCount) {
209                 BQ_LOGE("%s: min undequeued buffer count (%d) exceeded "
210                         "(dequeued=%d undequeued=%d)",
211                         caller, minUndequeuedCount,
212                         dequeuedCount, newUndequeuedCount);
213                 return INVALID_OPERATION;
214             }
215         }
216 
217         // If we disconnect and reconnect quickly, we can be in a state where
218         // our slots are empty but we have many buffers in the queue. This can
219         // cause us to run out of memory if we outrun the consumer. Wait here if
220         // it looks like we have too many buffers queued up.
221         bool tooManyBuffers = mCore->mQueue.size()
222                             > static_cast<size_t>(maxBufferCount);
223         if (tooManyBuffers) {
224             BQ_LOGV("%s: queue size is %zu, waiting", caller,
225                     mCore->mQueue.size());
226         }
227 
228         // If no buffer is found, or if the queue has too many buffers
229         // outstanding, wait for a buffer to be acquired or released, or for the
230         // max buffer count to change.
231         tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) ||
232                    tooManyBuffers;
233         if (tryAgain) {
234             // Return an error if we're in non-blocking mode (producer and
235             // consumer are controlled by the application).
236             // However, the consumer is allowed to briefly acquire an extra
237             // buffer (which could cause us to have to wait here), which is
238             // okay, since it is only used to implement an atomic acquire +
239             // release (e.g., in GLConsumer::updateTexImage())
240             if (mCore->mDequeueBufferCannotBlock &&
241                     (acquiredCount <= mCore->mMaxAcquiredBufferCount)) {
242                 return WOULD_BLOCK;
243             }
244             mCore->mDequeueCondition.wait(mCore->mMutex);
245         }
246     } // while (tryAgain)
247 
248     return NO_ERROR;
249 }
250 
dequeueBuffer(int * outSlot,sp<android::Fence> * outFence,bool async,uint32_t width,uint32_t height,uint32_t format,uint32_t usage)251 status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
252         sp<android::Fence> *outFence, bool async,
253         uint32_t width, uint32_t height, uint32_t format, uint32_t usage) {
254     ATRACE_CALL();
255     { // Autolock scope
256         Mutex::Autolock lock(mCore->mMutex);
257         mConsumerName = mCore->mConsumerName;
258     } // Autolock scope
259 
260     BQ_LOGV("dequeueBuffer: async=%s w=%u h=%u format=%#x, usage=%#x",
261             async ? "true" : "false", width, height, format, usage);
262 
263     if ((width && !height) || (!width && height)) {
264         BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height);
265         return BAD_VALUE;
266     }
267 
268     status_t returnFlags = NO_ERROR;
269     EGLDisplay eglDisplay = EGL_NO_DISPLAY;
270     EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
271     bool attachedByConsumer = false;
272 
273     { // Autolock scope
274         Mutex::Autolock lock(mCore->mMutex);
275         mCore->waitWhileAllocatingLocked();
276 
277         if (format == 0) {
278             format = mCore->mDefaultBufferFormat;
279         }
280 
281         // Enable the usage bits the consumer requested
282         usage |= mCore->mConsumerUsageBits;
283 
284         int found;
285         status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async,
286                 &found, &returnFlags);
287         if (status != NO_ERROR) {
288             return status;
289         }
290 
291         // This should not happen
292         if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
293             BQ_LOGE("dequeueBuffer: no available buffer slots");
294             return -EBUSY;
295         }
296 
297         *outSlot = found;
298         ATRACE_BUFFER_INDEX(found);
299 
300         attachedByConsumer = mSlots[found].mAttachedByConsumer;
301 
302         const bool useDefaultSize = !width && !height;
303         if (useDefaultSize) {
304             width = mCore->mDefaultWidth;
305             height = mCore->mDefaultHeight;
306         }
307 
308         mSlots[found].mBufferState = BufferSlot::DEQUEUED;
309 
310         const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
311         if ((buffer == NULL) ||
312                 (static_cast<uint32_t>(buffer->width) != width) ||
313                 (static_cast<uint32_t>(buffer->height) != height) ||
314                 (static_cast<uint32_t>(buffer->format) != format) ||
315                 ((static_cast<uint32_t>(buffer->usage) & usage) != usage))
316         {
317             mSlots[found].mAcquireCalled = false;
318             mSlots[found].mGraphicBuffer = NULL;
319             mSlots[found].mRequestBufferCalled = false;
320             mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
321             mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
322             mSlots[found].mFence = Fence::NO_FENCE;
323 
324             returnFlags |= BUFFER_NEEDS_REALLOCATION;
325         }
326 
327         if (CC_UNLIKELY(mSlots[found].mFence == NULL)) {
328             BQ_LOGE("dequeueBuffer: about to return a NULL fence - "
329                     "slot=%d w=%d h=%d format=%u",
330                     found, buffer->width, buffer->height, buffer->format);
331         }
332 
333         eglDisplay = mSlots[found].mEglDisplay;
334         eglFence = mSlots[found].mEglFence;
335         *outFence = mSlots[found].mFence;
336         mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
337         mSlots[found].mFence = Fence::NO_FENCE;
338     } // Autolock scope
339 
340     if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
341         status_t error;
342         BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
343         sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
344                     width, height, format, usage, &error));
345         if (graphicBuffer == NULL) {
346             BQ_LOGE("dequeueBuffer: createGraphicBuffer failed");
347             return error;
348         }
349 
350         { // Autolock scope
351             Mutex::Autolock lock(mCore->mMutex);
352 
353             if (mCore->mIsAbandoned) {
354                 BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
355                 return NO_INIT;
356             }
357 
358             mSlots[*outSlot].mFrameNumber = UINT32_MAX;
359             mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
360         } // Autolock scope
361     }
362 
363     if (attachedByConsumer) {
364         returnFlags |= BUFFER_NEEDS_REALLOCATION;
365     }
366 
367     if (eglFence != EGL_NO_SYNC_KHR) {
368         EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0,
369                 1000000000);
370         // If something goes wrong, log the error, but return the buffer without
371         // synchronizing access to it. It's too late at this point to abort the
372         // dequeue operation.
373         if (result == EGL_FALSE) {
374             BQ_LOGE("dequeueBuffer: error %#x waiting for fence",
375                     eglGetError());
376         } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
377             BQ_LOGE("dequeueBuffer: timeout waiting for fence");
378         }
379         eglDestroySyncKHR(eglDisplay, eglFence);
380     }
381 
382     BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x",
383             *outSlot,
384             mSlots[*outSlot].mFrameNumber,
385             mSlots[*outSlot].mGraphicBuffer->handle, returnFlags);
386 
387     return returnFlags;
388 }
389 
detachBuffer(int slot)390 status_t BufferQueueProducer::detachBuffer(int slot) {
391     ATRACE_CALL();
392     ATRACE_BUFFER_INDEX(slot);
393     BQ_LOGV("detachBuffer(P): slot %d", slot);
394     Mutex::Autolock lock(mCore->mMutex);
395 
396     if (mCore->mIsAbandoned) {
397         BQ_LOGE("detachBuffer(P): BufferQueue has been abandoned");
398         return NO_INIT;
399     }
400 
401     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
402         BQ_LOGE("detachBuffer(P): slot index %d out of range [0, %d)",
403                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
404         return BAD_VALUE;
405     } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
406         BQ_LOGE("detachBuffer(P): slot %d is not owned by the producer "
407                 "(state = %d)", slot, mSlots[slot].mBufferState);
408         return BAD_VALUE;
409     } else if (!mSlots[slot].mRequestBufferCalled) {
410         BQ_LOGE("detachBuffer(P): buffer in slot %d has not been requested",
411                 slot);
412         return BAD_VALUE;
413     }
414 
415     mCore->freeBufferLocked(slot);
416     mCore->mDequeueCondition.broadcast();
417 
418     return NO_ERROR;
419 }
420 
detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)421 status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
422         sp<Fence>* outFence) {
423     ATRACE_CALL();
424 
425     if (outBuffer == NULL) {
426         BQ_LOGE("detachNextBuffer: outBuffer must not be NULL");
427         return BAD_VALUE;
428     } else if (outFence == NULL) {
429         BQ_LOGE("detachNextBuffer: outFence must not be NULL");
430         return BAD_VALUE;
431     }
432 
433     Mutex::Autolock lock(mCore->mMutex);
434     mCore->waitWhileAllocatingLocked();
435 
436     if (mCore->mIsAbandoned) {
437         BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
438         return NO_INIT;
439     }
440 
441     // Find the oldest valid slot
442     int found = BufferQueueCore::INVALID_BUFFER_SLOT;
443     for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
444         if (mSlots[s].mBufferState == BufferSlot::FREE &&
445                 mSlots[s].mGraphicBuffer != NULL) {
446             if (found == BufferQueueCore::INVALID_BUFFER_SLOT ||
447                     mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) {
448                 found = s;
449             }
450         }
451     }
452 
453     if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
454         return NO_MEMORY;
455     }
456 
457     BQ_LOGV("detachNextBuffer detached slot %d", found);
458 
459     *outBuffer = mSlots[found].mGraphicBuffer;
460     *outFence = mSlots[found].mFence;
461     mCore->freeBufferLocked(found);
462 
463     return NO_ERROR;
464 }
465 
attachBuffer(int * outSlot,const sp<android::GraphicBuffer> & buffer)466 status_t BufferQueueProducer::attachBuffer(int* outSlot,
467         const sp<android::GraphicBuffer>& buffer) {
468     ATRACE_CALL();
469 
470     if (outSlot == NULL) {
471         BQ_LOGE("attachBuffer(P): outSlot must not be NULL");
472         return BAD_VALUE;
473     } else if (buffer == NULL) {
474         BQ_LOGE("attachBuffer(P): cannot attach NULL buffer");
475         return BAD_VALUE;
476     }
477 
478     Mutex::Autolock lock(mCore->mMutex);
479     mCore->waitWhileAllocatingLocked();
480 
481     status_t returnFlags = NO_ERROR;
482     int found;
483     // TODO: Should we provide an async flag to attachBuffer? It seems
484     // unlikely that buffers which we are attaching to a BufferQueue will
485     // be asynchronous (droppable), but it may not be impossible.
486     status_t status = waitForFreeSlotThenRelock("attachBuffer(P)", false,
487             &found, &returnFlags);
488     if (status != NO_ERROR) {
489         return status;
490     }
491 
492     // This should not happen
493     if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
494         BQ_LOGE("attachBuffer(P): no available buffer slots");
495         return -EBUSY;
496     }
497 
498     *outSlot = found;
499     ATRACE_BUFFER_INDEX(*outSlot);
500     BQ_LOGV("attachBuffer(P): returning slot %d flags=%#x",
501             *outSlot, returnFlags);
502 
503     mSlots[*outSlot].mGraphicBuffer = buffer;
504     mSlots[*outSlot].mBufferState = BufferSlot::DEQUEUED;
505     mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR;
506     mSlots[*outSlot].mFence = Fence::NO_FENCE;
507     mSlots[*outSlot].mRequestBufferCalled = true;
508 
509     return returnFlags;
510 }
511 
queueBuffer(int slot,const QueueBufferInput & input,QueueBufferOutput * output)512 status_t BufferQueueProducer::queueBuffer(int slot,
513         const QueueBufferInput &input, QueueBufferOutput *output) {
514     ATRACE_CALL();
515     ATRACE_BUFFER_INDEX(slot);
516 
517     int64_t timestamp;
518     bool isAutoTimestamp;
519     Rect crop;
520     int scalingMode;
521     uint32_t transform;
522     uint32_t stickyTransform;
523     bool async;
524     sp<Fence> fence;
525     input.deflate(&timestamp, &isAutoTimestamp, &crop, &scalingMode, &transform,
526             &async, &fence, &stickyTransform);
527 
528     if (fence == NULL) {
529         BQ_LOGE("queueBuffer: fence is NULL");
530         return BAD_VALUE;
531     }
532 
533     switch (scalingMode) {
534         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
535         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
536         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
537         case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
538             break;
539         default:
540             BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode);
541             return BAD_VALUE;
542     }
543 
544     sp<IConsumerListener> frameAvailableListener;
545     sp<IConsumerListener> frameReplacedListener;
546     int callbackTicket = 0;
547     BufferItem item;
548     { // Autolock scope
549         Mutex::Autolock lock(mCore->mMutex);
550 
551         if (mCore->mIsAbandoned) {
552             BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
553             return NO_INIT;
554         }
555 
556         const int maxBufferCount = mCore->getMaxBufferCountLocked(async);
557         if (async && mCore->mOverrideMaxBufferCount) {
558             // FIXME: Some drivers are manually setting the buffer count
559             // (which they shouldn't), so we do this extra test here to
560             // handle that case. This is TEMPORARY until we get this fixed.
561             if (mCore->mOverrideMaxBufferCount < maxBufferCount) {
562                 BQ_LOGE("queueBuffer: async mode is invalid with "
563                         "buffer count override");
564                 return BAD_VALUE;
565             }
566         }
567 
568         if (slot < 0 || slot >= maxBufferCount) {
569             BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)",
570                     slot, maxBufferCount);
571             return BAD_VALUE;
572         } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
573             BQ_LOGE("queueBuffer: slot %d is not owned by the producer "
574                     "(state = %d)", slot, mSlots[slot].mBufferState);
575             return BAD_VALUE;
576         } else if (!mSlots[slot].mRequestBufferCalled) {
577             BQ_LOGE("queueBuffer: slot %d was queued without requesting "
578                     "a buffer", slot);
579             return BAD_VALUE;
580         }
581 
582         BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64
583                 " crop=[%d,%d,%d,%d] transform=%#x scale=%s",
584                 slot, mCore->mFrameCounter + 1, timestamp,
585                 crop.left, crop.top, crop.right, crop.bottom,
586                 transform, BufferItem::scalingModeName(scalingMode));
587 
588         const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
589         Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
590         Rect croppedRect;
591         crop.intersect(bufferRect, &croppedRect);
592         if (croppedRect != crop) {
593             BQ_LOGE("queueBuffer: crop rect is not contained within the "
594                     "buffer in slot %d", slot);
595             return BAD_VALUE;
596         }
597 
598         mSlots[slot].mFence = fence;
599         mSlots[slot].mBufferState = BufferSlot::QUEUED;
600         ++mCore->mFrameCounter;
601         mSlots[slot].mFrameNumber = mCore->mFrameCounter;
602 
603         item.mAcquireCalled = mSlots[slot].mAcquireCalled;
604         item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
605         item.mCrop = crop;
606         item.mTransform = transform & ~NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
607         item.mTransformToDisplayInverse =
608                 bool(transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
609         item.mScalingMode = scalingMode;
610         item.mTimestamp = timestamp;
611         item.mIsAutoTimestamp = isAutoTimestamp;
612         item.mFrameNumber = mCore->mFrameCounter;
613         item.mSlot = slot;
614         item.mFence = fence;
615         item.mIsDroppable = mCore->mDequeueBufferCannotBlock || async;
616 
617         mStickyTransform = stickyTransform;
618 
619         if (mCore->mQueue.empty()) {
620             // When the queue is empty, we can ignore mDequeueBufferCannotBlock
621             // and simply queue this buffer
622             mCore->mQueue.push_back(item);
623             frameAvailableListener = mCore->mConsumerListener;
624         } else {
625             // When the queue is not empty, we need to look at the front buffer
626             // state to see if we need to replace it
627             BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
628             if (front->mIsDroppable) {
629                 // If the front queued buffer is still being tracked, we first
630                 // mark it as freed
631                 if (mCore->stillTracking(front)) {
632                     mSlots[front->mSlot].mBufferState = BufferSlot::FREE;
633                     // Reset the frame number of the freed buffer so that it is
634                     // the first in line to be dequeued again
635                     mSlots[front->mSlot].mFrameNumber = 0;
636                 }
637                 // Overwrite the droppable buffer with the incoming one
638                 *front = item;
639                 frameReplacedListener = mCore->mConsumerListener;
640             } else {
641                 mCore->mQueue.push_back(item);
642                 frameAvailableListener = mCore->mConsumerListener;
643             }
644         }
645 
646         mCore->mBufferHasBeenQueued = true;
647         mCore->mDequeueCondition.broadcast();
648 
649         output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
650                 mCore->mTransformHint, mCore->mQueue.size());
651 
652         ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
653 
654         // Take a ticket for the callback functions
655         callbackTicket = mNextCallbackTicket++;
656     } // Autolock scope
657 
658     // Wait without lock held
659     if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
660         // Waiting here allows for two full buffers to be queued but not a
661         // third. In the event that frames take varying time, this makes a
662         // small trade-off in favor of latency rather than throughput.
663         mLastQueueBufferFence->waitForever("Throttling EGL Production");
664         mLastQueueBufferFence = fence;
665     }
666 
667     // Don't send the GraphicBuffer through the callback, and don't send
668     // the slot number, since the consumer shouldn't need it
669     item.mGraphicBuffer.clear();
670     item.mSlot = BufferItem::INVALID_BUFFER_SLOT;
671 
672     // Call back without the main BufferQueue lock held, but with the callback
673     // lock held so we can ensure that callbacks occur in order
674     {
675         Mutex::Autolock lock(mCallbackMutex);
676         while (callbackTicket != mCurrentCallbackTicket) {
677             mCallbackCondition.wait(mCallbackMutex);
678         }
679 
680         if (frameAvailableListener != NULL) {
681             frameAvailableListener->onFrameAvailable(item);
682         } else if (frameReplacedListener != NULL) {
683             frameReplacedListener->onFrameReplaced(item);
684         }
685 
686         ++mCurrentCallbackTicket;
687         mCallbackCondition.broadcast();
688     }
689 
690     return NO_ERROR;
691 }
692 
cancelBuffer(int slot,const sp<Fence> & fence)693 void BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
694     ATRACE_CALL();
695     BQ_LOGV("cancelBuffer: slot %d", slot);
696     Mutex::Autolock lock(mCore->mMutex);
697 
698     if (mCore->mIsAbandoned) {
699         BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
700         return;
701     }
702 
703     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
704         BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
705                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
706         return;
707     } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
708         BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
709                 "(state = %d)", slot, mSlots[slot].mBufferState);
710         return;
711     } else if (fence == NULL) {
712         BQ_LOGE("cancelBuffer: fence is NULL");
713         return;
714     }
715 
716     mSlots[slot].mBufferState = BufferSlot::FREE;
717     mSlots[slot].mFrameNumber = 0;
718     mSlots[slot].mFence = fence;
719     mCore->mDequeueCondition.broadcast();
720 }
721 
query(int what,int * outValue)722 int BufferQueueProducer::query(int what, int *outValue) {
723     ATRACE_CALL();
724     Mutex::Autolock lock(mCore->mMutex);
725 
726     if (outValue == NULL) {
727         BQ_LOGE("query: outValue was NULL");
728         return BAD_VALUE;
729     }
730 
731     if (mCore->mIsAbandoned) {
732         BQ_LOGE("query: BufferQueue has been abandoned");
733         return NO_INIT;
734     }
735 
736     int value;
737     switch (what) {
738         case NATIVE_WINDOW_WIDTH:
739             value = mCore->mDefaultWidth;
740             break;
741         case NATIVE_WINDOW_HEIGHT:
742             value = mCore->mDefaultHeight;
743             break;
744         case NATIVE_WINDOW_FORMAT:
745             value = mCore->mDefaultBufferFormat;
746             break;
747         case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
748             value = mCore->getMinUndequeuedBufferCountLocked(false);
749             break;
750         case NATIVE_WINDOW_STICKY_TRANSFORM:
751             value = static_cast<int>(mStickyTransform);
752             break;
753         case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
754             value = (mCore->mQueue.size() > 1);
755             break;
756         case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
757             value = mCore->mConsumerUsageBits;
758             break;
759         default:
760             return BAD_VALUE;
761     }
762 
763     BQ_LOGV("query: %d? %d", what, value);
764     *outValue = value;
765     return NO_ERROR;
766 }
767 
connect(const sp<IProducerListener> & listener,int api,bool producerControlledByApp,QueueBufferOutput * output)768 status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
769         int api, bool producerControlledByApp, QueueBufferOutput *output) {
770     ATRACE_CALL();
771     Mutex::Autolock lock(mCore->mMutex);
772     mConsumerName = mCore->mConsumerName;
773     BQ_LOGV("connect(P): api=%d producerControlledByApp=%s", api,
774             producerControlledByApp ? "true" : "false");
775 
776     if (mCore->mIsAbandoned) {
777         BQ_LOGE("connect(P): BufferQueue has been abandoned");
778         return NO_INIT;
779     }
780 
781     if (mCore->mConsumerListener == NULL) {
782         BQ_LOGE("connect(P): BufferQueue has no consumer");
783         return NO_INIT;
784     }
785 
786     if (output == NULL) {
787         BQ_LOGE("connect(P): output was NULL");
788         return BAD_VALUE;
789     }
790 
791     if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
792         BQ_LOGE("connect(P): already connected (cur=%d req=%d)",
793                 mCore->mConnectedApi, api);
794         return BAD_VALUE;
795     }
796 
797     int status = NO_ERROR;
798     switch (api) {
799         case NATIVE_WINDOW_API_EGL:
800         case NATIVE_WINDOW_API_CPU:
801         case NATIVE_WINDOW_API_MEDIA:
802         case NATIVE_WINDOW_API_CAMERA:
803             mCore->mConnectedApi = api;
804             output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
805                     mCore->mTransformHint, mCore->mQueue.size());
806 
807             // Set up a death notification so that we can disconnect
808             // automatically if the remote producer dies
809             if (listener != NULL &&
810                     listener->asBinder()->remoteBinder() != NULL) {
811                 status = listener->asBinder()->linkToDeath(
812                         static_cast<IBinder::DeathRecipient*>(this));
813                 if (status != NO_ERROR) {
814                     BQ_LOGE("connect(P): linkToDeath failed: %s (%d)",
815                             strerror(-status), status);
816                 }
817             }
818             mCore->mConnectedProducerListener = listener;
819             break;
820         default:
821             BQ_LOGE("connect(P): unknown API %d", api);
822             status = BAD_VALUE;
823             break;
824     }
825 
826     mCore->mBufferHasBeenQueued = false;
827     mCore->mDequeueBufferCannotBlock =
828             mCore->mConsumerControlledByApp && producerControlledByApp;
829 
830     return status;
831 }
832 
disconnect(int api)833 status_t BufferQueueProducer::disconnect(int api) {
834     ATRACE_CALL();
835     BQ_LOGV("disconnect(P): api %d", api);
836 
837     int status = NO_ERROR;
838     sp<IConsumerListener> listener;
839     { // Autolock scope
840         Mutex::Autolock lock(mCore->mMutex);
841         mCore->waitWhileAllocatingLocked();
842 
843         if (mCore->mIsAbandoned) {
844             // It's not really an error to disconnect after the surface has
845             // been abandoned; it should just be a no-op.
846             return NO_ERROR;
847         }
848 
849         switch (api) {
850             case NATIVE_WINDOW_API_EGL:
851             case NATIVE_WINDOW_API_CPU:
852             case NATIVE_WINDOW_API_MEDIA:
853             case NATIVE_WINDOW_API_CAMERA:
854                 if (mCore->mConnectedApi == api) {
855                     mCore->freeAllBuffersLocked();
856 
857                     // Remove our death notification callback if we have one
858                     if (mCore->mConnectedProducerListener != NULL) {
859                         sp<IBinder> token =
860                                 mCore->mConnectedProducerListener->asBinder();
861                         // This can fail if we're here because of the death
862                         // notification, but we just ignore it
863                         token->unlinkToDeath(
864                                 static_cast<IBinder::DeathRecipient*>(this));
865                     }
866                     mCore->mConnectedProducerListener = NULL;
867                     mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
868                     mCore->mSidebandStream.clear();
869                     mCore->mDequeueCondition.broadcast();
870                     listener = mCore->mConsumerListener;
871                 } else {
872                     BQ_LOGE("disconnect(P): connected to another API "
873                             "(cur=%d req=%d)", mCore->mConnectedApi, api);
874                     status = BAD_VALUE;
875                 }
876                 break;
877             default:
878                 BQ_LOGE("disconnect(P): unknown API %d", api);
879                 status = BAD_VALUE;
880                 break;
881         }
882     } // Autolock scope
883 
884     // Call back without lock held
885     if (listener != NULL) {
886         listener->onBuffersReleased();
887     }
888 
889     return status;
890 }
891 
setSidebandStream(const sp<NativeHandle> & stream)892 status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
893     sp<IConsumerListener> listener;
894     { // Autolock scope
895         Mutex::Autolock _l(mCore->mMutex);
896         mCore->mSidebandStream = stream;
897         listener = mCore->mConsumerListener;
898     } // Autolock scope
899 
900     if (listener != NULL) {
901         listener->onSidebandStreamChanged();
902     }
903     return NO_ERROR;
904 }
905 
allocateBuffers(bool async,uint32_t width,uint32_t height,uint32_t format,uint32_t usage)906 void BufferQueueProducer::allocateBuffers(bool async, uint32_t width,
907         uint32_t height, uint32_t format, uint32_t usage) {
908     ATRACE_CALL();
909     while (true) {
910         Vector<int> freeSlots;
911         size_t newBufferCount = 0;
912         uint32_t allocWidth = 0;
913         uint32_t allocHeight = 0;
914         uint32_t allocFormat = 0;
915         uint32_t allocUsage = 0;
916         { // Autolock scope
917             Mutex::Autolock lock(mCore->mMutex);
918             mCore->waitWhileAllocatingLocked();
919 
920             int currentBufferCount = 0;
921             for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) {
922                 if (mSlots[slot].mGraphicBuffer != NULL) {
923                     ++currentBufferCount;
924                 } else {
925                     if (mSlots[slot].mBufferState != BufferSlot::FREE) {
926                         BQ_LOGE("allocateBuffers: slot %d without buffer is not FREE",
927                                 slot);
928                         continue;
929                     }
930 
931                     freeSlots.push_back(slot);
932                 }
933             }
934 
935             int maxBufferCount = mCore->getMaxBufferCountLocked(async);
936             BQ_LOGV("allocateBuffers: allocating from %d buffers up to %d buffers",
937                     currentBufferCount, maxBufferCount);
938             if (maxBufferCount <= currentBufferCount)
939                 return;
940             newBufferCount = maxBufferCount - currentBufferCount;
941             if (freeSlots.size() < newBufferCount) {
942                 BQ_LOGE("allocateBuffers: ran out of free slots");
943                 return;
944             }
945             allocWidth = width > 0 ? width : mCore->mDefaultWidth;
946             allocHeight = height > 0 ? height : mCore->mDefaultHeight;
947             allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
948             allocUsage = usage | mCore->mConsumerUsageBits;
949 
950             mCore->mIsAllocating = true;
951         } // Autolock scope
952 
953         Vector<sp<GraphicBuffer> > buffers;
954         for (size_t i = 0; i <  newBufferCount; ++i) {
955             status_t result = NO_ERROR;
956             sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
957                     allocWidth, allocHeight, allocFormat, allocUsage, &result));
958             if (result != NO_ERROR) {
959                 BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
960                         " %u, usage %u)", width, height, format, usage);
961                 Mutex::Autolock lock(mCore->mMutex);
962                 mCore->mIsAllocating = false;
963                 mCore->mIsAllocatingCondition.broadcast();
964                 return;
965             }
966             buffers.push_back(graphicBuffer);
967         }
968 
969         { // Autolock scope
970             Mutex::Autolock lock(mCore->mMutex);
971             uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
972             uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
973             uint32_t checkFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
974             uint32_t checkUsage = usage | mCore->mConsumerUsageBits;
975             if (checkWidth != allocWidth || checkHeight != allocHeight ||
976                 checkFormat != allocFormat || checkUsage != allocUsage) {
977                 // Something changed while we released the lock. Retry.
978                 BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying.");
979                 mCore->mIsAllocating = false;
980                 mCore->mIsAllocatingCondition.broadcast();
981                 continue;
982             }
983 
984             for (size_t i = 0; i < newBufferCount; ++i) {
985                 int slot = freeSlots[i];
986                 if (mSlots[slot].mBufferState != BufferSlot::FREE) {
987                     // A consumer allocated the FREE slot with attachBuffer. Discard the buffer we
988                     // allocated.
989                     BQ_LOGV("allocateBuffers: slot %d was acquired while allocating. "
990                             "Dropping allocated buffer.", slot);
991                     continue;
992                 }
993                 mCore->freeBufferLocked(slot); // Clean up the slot first
994                 mSlots[slot].mGraphicBuffer = buffers[i];
995                 mSlots[slot].mFrameNumber = 0;
996                 mSlots[slot].mFence = Fence::NO_FENCE;
997                 BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", slot);
998             }
999 
1000             mCore->mIsAllocating = false;
1001             mCore->mIsAllocatingCondition.broadcast();
1002         } // Autolock scope
1003     }
1004 }
1005 
binderDied(const wp<android::IBinder> &)1006 void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
1007     // If we're here, it means that a producer we were connected to died.
1008     // We're guaranteed that we are still connected to it because we remove
1009     // this callback upon disconnect. It's therefore safe to read mConnectedApi
1010     // without synchronization here.
1011     int api = mCore->mConnectedApi;
1012     disconnect(api);
1013 }
1014 
1015 } // namespace android
1016