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 "BufferQueueConsumer"
20 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
21 //#define LOG_NDEBUG 0
22 
23 #include <gui/BufferItem.h>
24 #include <gui/BufferQueueConsumer.h>
25 #include <gui/BufferQueueCore.h>
26 #include <gui/IConsumerListener.h>
27 #include <gui/IProducerListener.h>
28 
29 namespace android {
30 
BufferQueueConsumer(const sp<BufferQueueCore> & core)31 BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
32     mCore(core),
33     mSlots(core->mSlots),
34     mConsumerName() {}
35 
~BufferQueueConsumer()36 BufferQueueConsumer::~BufferQueueConsumer() {}
37 
acquireBuffer(BufferItem * outBuffer,nsecs_t expectedPresent)38 status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
39         nsecs_t expectedPresent) {
40     ATRACE_CALL();
41     Mutex::Autolock lock(mCore->mMutex);
42 
43     // Check that the consumer doesn't currently have the maximum number of
44     // buffers acquired. We allow the max buffer count to be exceeded by one
45     // buffer so that the consumer can successfully set up the newly acquired
46     // buffer before releasing the old one.
47     int numAcquiredBuffers = 0;
48     for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
49         if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) {
50             ++numAcquiredBuffers;
51         }
52     }
53     if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
54         BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)",
55                 numAcquiredBuffers, mCore->mMaxAcquiredBufferCount);
56         return INVALID_OPERATION;
57     }
58 
59     // Check if the queue is empty.
60     // In asynchronous mode the list is guaranteed to be one buffer deep,
61     // while in synchronous mode we use the oldest buffer.
62     if (mCore->mQueue.empty()) {
63         return NO_BUFFER_AVAILABLE;
64     }
65 
66     BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
67 
68     // If expectedPresent is specified, we may not want to return a buffer yet.
69     // If it's specified and there's more than one buffer queued, we may want
70     // to drop a buffer.
71     if (expectedPresent != 0) {
72         const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second
73 
74         // The 'expectedPresent' argument indicates when the buffer is expected
75         // to be presented on-screen. If the buffer's desired present time is
76         // earlier (less) than expectedPresent -- meaning it will be displayed
77         // on time or possibly late if we show it as soon as possible -- we
78         // acquire and return it. If we don't want to display it until after the
79         // expectedPresent time, we return PRESENT_LATER without acquiring it.
80         //
81         // To be safe, we don't defer acquisition if expectedPresent is more
82         // than one second in the future beyond the desired present time
83         // (i.e., we'd be holding the buffer for a long time).
84         //
85         // NOTE: Code assumes monotonic time values from the system clock
86         // are positive.
87 
88         // Start by checking to see if we can drop frames. We skip this check if
89         // the timestamps are being auto-generated by Surface. If the app isn't
90         // generating timestamps explicitly, it probably doesn't want frames to
91         // be discarded based on them.
92         while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) {
93             // If entry[1] is timely, drop entry[0] (and repeat). We apply an
94             // additional criterion here: we only drop the earlier buffer if our
95             // desiredPresent falls within +/- 1 second of the expected present.
96             // Otherwise, bogus desiredPresent times (e.g., 0 or a small
97             // relative timestamp), which normally mean "ignore the timestamp
98             // and acquire immediately", would cause us to drop frames.
99             //
100             // We may want to add an additional criterion: don't drop the
101             // earlier buffer if entry[1]'s fence hasn't signaled yet.
102             const BufferItem& bufferItem(mCore->mQueue[1]);
103             nsecs_t desiredPresent = bufferItem.mTimestamp;
104             if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC ||
105                     desiredPresent > expectedPresent) {
106                 // This buffer is set to display in the near future, or
107                 // desiredPresent is garbage. Either way we don't want to drop
108                 // the previous buffer just to get this on the screen sooner.
109                 BQ_LOGV("acquireBuffer: nodrop desire=%" PRId64 " expect=%"
110                         PRId64 " (%" PRId64 ") now=%" PRId64,
111                         desiredPresent, expectedPresent,
112                         desiredPresent - expectedPresent,
113                         systemTime(CLOCK_MONOTONIC));
114                 break;
115             }
116 
117             BQ_LOGV("acquireBuffer: drop desire=%" PRId64 " expect=%" PRId64
118                     " size=%zu",
119                     desiredPresent, expectedPresent, mCore->mQueue.size());
120             if (mCore->stillTracking(front)) {
121                 // Front buffer is still in mSlots, so mark the slot as free
122                 mSlots[front->mSlot].mBufferState = BufferSlot::FREE;
123             }
124             mCore->mQueue.erase(front);
125             front = mCore->mQueue.begin();
126         }
127 
128         // See if the front buffer is due
129         nsecs_t desiredPresent = front->mTimestamp;
130         if (desiredPresent > expectedPresent &&
131                 desiredPresent < expectedPresent + MAX_REASONABLE_NSEC) {
132             BQ_LOGV("acquireBuffer: defer desire=%" PRId64 " expect=%" PRId64
133                     " (%" PRId64 ") now=%" PRId64,
134                     desiredPresent, expectedPresent,
135                     desiredPresent - expectedPresent,
136                     systemTime(CLOCK_MONOTONIC));
137             return PRESENT_LATER;
138         }
139 
140         BQ_LOGV("acquireBuffer: accept desire=%" PRId64 " expect=%" PRId64 " "
141                 "(%" PRId64 ") now=%" PRId64, desiredPresent, expectedPresent,
142                 desiredPresent - expectedPresent,
143                 systemTime(CLOCK_MONOTONIC));
144     }
145 
146     int slot = front->mSlot;
147     *outBuffer = *front;
148     ATRACE_BUFFER_INDEX(slot);
149 
150     BQ_LOGV("acquireBuffer: acquiring { slot=%d/%" PRIu64 " buffer=%p }",
151             slot, front->mFrameNumber, front->mGraphicBuffer->handle);
152     // If the front buffer is still being tracked, update its slot state
153     if (mCore->stillTracking(front)) {
154         mSlots[slot].mAcquireCalled = true;
155         mSlots[slot].mNeedsCleanupOnRelease = false;
156         mSlots[slot].mBufferState = BufferSlot::ACQUIRED;
157         mSlots[slot].mFence = Fence::NO_FENCE;
158     }
159 
160     // If the buffer has previously been acquired by the consumer, set
161     // mGraphicBuffer to NULL to avoid unnecessarily remapping this buffer
162     // on the consumer side
163     if (outBuffer->mAcquireCalled) {
164         outBuffer->mGraphicBuffer = NULL;
165     }
166 
167     mCore->mQueue.erase(front);
168 
169     // We might have freed a slot while dropping old buffers, or the producer
170     // may be blocked waiting for the number of buffers in the queue to
171     // decrease.
172     mCore->mDequeueCondition.broadcast();
173 
174     ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
175 
176     return NO_ERROR;
177 }
178 
detachBuffer(int slot)179 status_t BufferQueueConsumer::detachBuffer(int slot) {
180     ATRACE_CALL();
181     ATRACE_BUFFER_INDEX(slot);
182     BQ_LOGV("detachBuffer(C): slot %d", slot);
183     Mutex::Autolock lock(mCore->mMutex);
184 
185     if (mCore->mIsAbandoned) {
186         BQ_LOGE("detachBuffer(C): BufferQueue has been abandoned");
187         return NO_INIT;
188     }
189 
190     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
191         BQ_LOGE("detachBuffer(C): slot index %d out of range [0, %d)",
192                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
193         return BAD_VALUE;
194     } else if (mSlots[slot].mBufferState != BufferSlot::ACQUIRED) {
195         BQ_LOGE("detachBuffer(C): slot %d is not owned by the consumer "
196                 "(state = %d)", slot, mSlots[slot].mBufferState);
197         return BAD_VALUE;
198     }
199 
200     mCore->freeBufferLocked(slot);
201     mCore->mDequeueCondition.broadcast();
202 
203     return NO_ERROR;
204 }
205 
attachBuffer(int * outSlot,const sp<android::GraphicBuffer> & buffer)206 status_t BufferQueueConsumer::attachBuffer(int* outSlot,
207         const sp<android::GraphicBuffer>& buffer) {
208     ATRACE_CALL();
209 
210     if (outSlot == NULL) {
211         BQ_LOGE("attachBuffer(P): outSlot must not be NULL");
212         return BAD_VALUE;
213     } else if (buffer == NULL) {
214         BQ_LOGE("attachBuffer(P): cannot attach NULL buffer");
215         return BAD_VALUE;
216     }
217 
218     Mutex::Autolock lock(mCore->mMutex);
219 
220     // Make sure we don't have too many acquired buffers and find a free slot
221     // to put the buffer into (the oldest if there are multiple).
222     int numAcquiredBuffers = 0;
223     int found = BufferQueueCore::INVALID_BUFFER_SLOT;
224     for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
225         if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) {
226             ++numAcquiredBuffers;
227         } else if (mSlots[s].mBufferState == BufferSlot::FREE) {
228             if (found == BufferQueueCore::INVALID_BUFFER_SLOT ||
229                     mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) {
230                 found = s;
231             }
232         }
233     }
234 
235     if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
236         BQ_LOGE("attachBuffer(P): max acquired buffer count reached: %d "
237                 "(max %d)", numAcquiredBuffers,
238                 mCore->mMaxAcquiredBufferCount);
239         return INVALID_OPERATION;
240     }
241     if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
242         BQ_LOGE("attachBuffer(P): could not find free buffer slot");
243         return NO_MEMORY;
244     }
245 
246     *outSlot = found;
247     ATRACE_BUFFER_INDEX(*outSlot);
248     BQ_LOGV("attachBuffer(C): returning slot %d", *outSlot);
249 
250     mSlots[*outSlot].mGraphicBuffer = buffer;
251     mSlots[*outSlot].mBufferState = BufferSlot::ACQUIRED;
252     mSlots[*outSlot].mAttachedByConsumer = true;
253     mSlots[*outSlot].mNeedsCleanupOnRelease = false;
254     mSlots[*outSlot].mFence = Fence::NO_FENCE;
255     mSlots[*outSlot].mFrameNumber = 0;
256 
257     // mAcquireCalled tells BufferQueue that it doesn't need to send a valid
258     // GraphicBuffer pointer on the next acquireBuffer call, which decreases
259     // Binder traffic by not un/flattening the GraphicBuffer. However, it
260     // requires that the consumer maintain a cached copy of the slot <--> buffer
261     // mappings, which is why the consumer doesn't need the valid pointer on
262     // acquire.
263     //
264     // The StreamSplitter is one of the primary users of the attach/detach
265     // logic, and while it is running, all buffers it acquires are immediately
266     // detached, and all buffers it eventually releases are ones that were
267     // attached (as opposed to having been obtained from acquireBuffer), so it
268     // doesn't make sense to maintain the slot/buffer mappings, which would
269     // become invalid for every buffer during detach/attach. By setting this to
270     // false, the valid GraphicBuffer pointer will always be sent with acquire
271     // for attached buffers.
272     mSlots[*outSlot].mAcquireCalled = false;
273 
274     return NO_ERROR;
275 }
276 
releaseBuffer(int slot,uint64_t frameNumber,const sp<Fence> & releaseFence,EGLDisplay eglDisplay,EGLSyncKHR eglFence)277 status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
278         const sp<Fence>& releaseFence, EGLDisplay eglDisplay,
279         EGLSyncKHR eglFence) {
280     ATRACE_CALL();
281     ATRACE_BUFFER_INDEX(slot);
282 
283     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS ||
284             releaseFence == NULL) {
285         return BAD_VALUE;
286     }
287 
288     sp<IProducerListener> listener;
289     { // Autolock scope
290         Mutex::Autolock lock(mCore->mMutex);
291 
292         // If the frame number has changed because the buffer has been reallocated,
293         // we can ignore this releaseBuffer for the old buffer
294         if (frameNumber != mSlots[slot].mFrameNumber) {
295             return STALE_BUFFER_SLOT;
296         }
297 
298         // Make sure this buffer hasn't been queued while acquired by the consumer
299         BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
300         while (current != mCore->mQueue.end()) {
301             if (current->mSlot == slot) {
302                 BQ_LOGE("releaseBuffer: buffer slot %d pending release is "
303                         "currently queued", slot);
304                 return BAD_VALUE;
305             }
306             ++current;
307         }
308 
309         if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
310             mSlots[slot].mEglDisplay = eglDisplay;
311             mSlots[slot].mEglFence = eglFence;
312             mSlots[slot].mFence = releaseFence;
313             mSlots[slot].mBufferState = BufferSlot::FREE;
314             listener = mCore->mConnectedProducerListener;
315             BQ_LOGV("releaseBuffer: releasing slot %d", slot);
316         } else if (mSlots[slot].mNeedsCleanupOnRelease) {
317             BQ_LOGV("releaseBuffer: releasing a stale buffer slot %d "
318                     "(state = %d)", slot, mSlots[slot].mBufferState);
319             mSlots[slot].mNeedsCleanupOnRelease = false;
320             return STALE_BUFFER_SLOT;
321         } else {
322             BQ_LOGV("releaseBuffer: attempted to release buffer slot %d "
323                     "but its state was %d", slot, mSlots[slot].mBufferState);
324             return BAD_VALUE;
325         }
326 
327         mCore->mDequeueCondition.broadcast();
328     } // Autolock scope
329 
330     // Call back without lock held
331     if (listener != NULL) {
332         listener->onBufferReleased();
333     }
334 
335     return NO_ERROR;
336 }
337 
connect(const sp<IConsumerListener> & consumerListener,bool controlledByApp)338 status_t BufferQueueConsumer::connect(
339         const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
340     ATRACE_CALL();
341 
342     if (consumerListener == NULL) {
343         BQ_LOGE("connect(C): consumerListener may not be NULL");
344         return BAD_VALUE;
345     }
346 
347     BQ_LOGV("connect(C): controlledByApp=%s",
348             controlledByApp ? "true" : "false");
349 
350     Mutex::Autolock lock(mCore->mMutex);
351 
352     if (mCore->mIsAbandoned) {
353         BQ_LOGE("connect(C): BufferQueue has been abandoned");
354         return NO_INIT;
355     }
356 
357     mCore->mConsumerListener = consumerListener;
358     mCore->mConsumerControlledByApp = controlledByApp;
359 
360     return NO_ERROR;
361 }
362 
disconnect()363 status_t BufferQueueConsumer::disconnect() {
364     ATRACE_CALL();
365 
366     BQ_LOGV("disconnect(C)");
367 
368     Mutex::Autolock lock(mCore->mMutex);
369 
370     if (mCore->mConsumerListener == NULL) {
371         BQ_LOGE("disconnect(C): no consumer is connected");
372         return BAD_VALUE;
373     }
374 
375     mCore->mIsAbandoned = true;
376     mCore->mConsumerListener = NULL;
377     mCore->mQueue.clear();
378     mCore->freeAllBuffersLocked();
379     mCore->mDequeueCondition.broadcast();
380     return NO_ERROR;
381 }
382 
getReleasedBuffers(uint64_t * outSlotMask)383 status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) {
384     ATRACE_CALL();
385 
386     if (outSlotMask == NULL) {
387         BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL");
388         return BAD_VALUE;
389     }
390 
391     Mutex::Autolock lock(mCore->mMutex);
392 
393     if (mCore->mIsAbandoned) {
394         BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned");
395         return NO_INIT;
396     }
397 
398     uint64_t mask = 0;
399     for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
400         if (!mSlots[s].mAcquireCalled) {
401             mask |= (1ULL << s);
402         }
403     }
404 
405     // Remove from the mask queued buffers for which acquire has been called,
406     // since the consumer will not receive their buffer addresses and so must
407     // retain their cached information
408     BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
409     while (current != mCore->mQueue.end()) {
410         if (current->mAcquireCalled) {
411             mask &= ~(1ULL << current->mSlot);
412         }
413         ++current;
414     }
415 
416     BQ_LOGV("getReleasedBuffers: returning mask %#" PRIx64, mask);
417     *outSlotMask = mask;
418     return NO_ERROR;
419 }
420 
setDefaultBufferSize(uint32_t width,uint32_t height)421 status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width,
422         uint32_t height) {
423     ATRACE_CALL();
424 
425     if (width == 0 || height == 0) {
426         BQ_LOGV("setDefaultBufferSize: dimensions cannot be 0 (width=%u "
427                 "height=%u)", width, height);
428         return BAD_VALUE;
429     }
430 
431     BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height);
432 
433     Mutex::Autolock lock(mCore->mMutex);
434     mCore->mDefaultWidth = width;
435     mCore->mDefaultHeight = height;
436     return NO_ERROR;
437 }
438 
setDefaultMaxBufferCount(int bufferCount)439 status_t BufferQueueConsumer::setDefaultMaxBufferCount(int bufferCount) {
440     ATRACE_CALL();
441     Mutex::Autolock lock(mCore->mMutex);
442     return mCore->setDefaultMaxBufferCountLocked(bufferCount);
443 }
444 
disableAsyncBuffer()445 status_t BufferQueueConsumer::disableAsyncBuffer() {
446     ATRACE_CALL();
447 
448     Mutex::Autolock lock(mCore->mMutex);
449 
450     if (mCore->mConsumerListener != NULL) {
451         BQ_LOGE("disableAsyncBuffer: consumer already connected");
452         return INVALID_OPERATION;
453     }
454 
455     BQ_LOGV("disableAsyncBuffer");
456     mCore->mUseAsyncBuffer = false;
457     return NO_ERROR;
458 }
459 
setMaxAcquiredBufferCount(int maxAcquiredBuffers)460 status_t BufferQueueConsumer::setMaxAcquiredBufferCount(
461         int maxAcquiredBuffers) {
462     ATRACE_CALL();
463 
464     if (maxAcquiredBuffers < 1 ||
465             maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) {
466         BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d",
467                 maxAcquiredBuffers);
468         return BAD_VALUE;
469     }
470 
471     Mutex::Autolock lock(mCore->mMutex);
472 
473     if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
474         BQ_LOGE("setMaxAcquiredBufferCount: producer is already connected");
475         return INVALID_OPERATION;
476     }
477 
478     BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
479     mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
480     return NO_ERROR;
481 }
482 
setConsumerName(const String8 & name)483 void BufferQueueConsumer::setConsumerName(const String8& name) {
484     ATRACE_CALL();
485     BQ_LOGV("setConsumerName: '%s'", name.string());
486     Mutex::Autolock lock(mCore->mMutex);
487     mCore->mConsumerName = name;
488     mConsumerName = name;
489 }
490 
setDefaultBufferFormat(uint32_t defaultFormat)491 status_t BufferQueueConsumer::setDefaultBufferFormat(uint32_t defaultFormat) {
492     ATRACE_CALL();
493     BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat);
494     Mutex::Autolock lock(mCore->mMutex);
495     mCore->mDefaultBufferFormat = defaultFormat;
496     return NO_ERROR;
497 }
498 
setConsumerUsageBits(uint32_t usage)499 status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) {
500     ATRACE_CALL();
501     BQ_LOGV("setConsumerUsageBits: %#x", usage);
502     Mutex::Autolock lock(mCore->mMutex);
503     mCore->mConsumerUsageBits = usage;
504     return NO_ERROR;
505 }
506 
setTransformHint(uint32_t hint)507 status_t BufferQueueConsumer::setTransformHint(uint32_t hint) {
508     ATRACE_CALL();
509     BQ_LOGV("setTransformHint: %#x", hint);
510     Mutex::Autolock lock(mCore->mMutex);
511     mCore->mTransformHint = hint;
512     return NO_ERROR;
513 }
514 
getSidebandStream() const515 sp<NativeHandle> BufferQueueConsumer::getSidebandStream() const {
516     return mCore->mSidebandStream;
517 }
518 
dump(String8 & result,const char * prefix) const519 void BufferQueueConsumer::dump(String8& result, const char* prefix) const {
520     mCore->dump(result, prefix);
521 }
522 
523 } // namespace android
524