blob: f8b50cc3ca93bbdf1948c3750908e0d7bdfbeb8c [file] [log] [blame]
Dan Stoza289ade12014-02-28 11:17:17 -08001/*
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
Mark Salyzyn8f515ce2014-06-09 14:32:04 -070017#include <inttypes.h>
18
Dan Stoza3e96f192014-03-03 10:16:19 -080019#define LOG_TAG "BufferQueueConsumer"
20#define ATRACE_TAG ATRACE_TAG_GRAPHICS
21//#define LOG_NDEBUG 0
22
Pablo Ceballos9e314332016-01-12 13:49:19 -080023#if DEBUG_ONLY_CODE
24#define VALIDATE_CONSISTENCY() do { mCore->validateConsistencyLocked(); } while (0)
25#else
26#define VALIDATE_CONSISTENCY()
27#endif
28
Dan Stoza289ade12014-02-28 11:17:17 -080029#include <gui/BufferItem.h>
30#include <gui/BufferQueueConsumer.h>
31#include <gui/BufferQueueCore.h>
32#include <gui/IConsumerListener.h>
Dan Stozad1c10362014-03-28 15:19:08 -070033#include <gui/IProducerListener.h>
Dan Stoza289ade12014-02-28 11:17:17 -080034
35namespace android {
36
37BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
38 mCore(core),
39 mSlots(core->mSlots),
40 mConsumerName() {}
41
42BufferQueueConsumer::~BufferQueueConsumer() {}
43
44status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
Dan Stozaa4650a52015-05-12 12:56:16 -070045 nsecs_t expectedPresent, uint64_t maxFrameNumber) {
Dan Stoza289ade12014-02-28 11:17:17 -080046 ATRACE_CALL();
Dan Stoza289ade12014-02-28 11:17:17 -080047
Lajos Molnar5f920c12015-07-13 16:04:24 -070048 int numDroppedBuffers = 0;
49 sp<IProducerListener> listener;
50 {
51 Mutex::Autolock lock(mCore->mMutex);
52
53 // Check that the consumer doesn't currently have the maximum number of
54 // buffers acquired. We allow the max buffer count to be exceeded by one
55 // buffer so that the consumer can successfully set up the newly acquired
56 // buffer before releasing the old one.
57 int numAcquiredBuffers = 0;
Pablo Ceballos23b4abe2016-01-08 12:15:22 -080058 for (int s : mCore->mActiveBuffers) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -070059 if (mSlots[s].mBufferState.isAcquired()) {
Lajos Molnar5f920c12015-07-13 16:04:24 -070060 ++numAcquiredBuffers;
61 }
Dan Stoza289ade12014-02-28 11:17:17 -080062 }
Lajos Molnar5f920c12015-07-13 16:04:24 -070063 if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
64 BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)",
65 numAcquiredBuffers, mCore->mMaxAcquiredBufferCount);
66 return INVALID_OPERATION;
67 }
Dan Stoza289ade12014-02-28 11:17:17 -080068
Pablo Ceballosccdfd602015-10-07 15:05:45 -070069 bool sharedBufferAvailable = mCore->mSingleBufferMode &&
Pablo Ceballosff95aab2016-01-13 17:09:58 -080070 mCore->mAutoRefresh && mCore->mSingleBufferSlot !=
Pablo Ceballosccdfd602015-10-07 15:05:45 -070071 BufferQueueCore::INVALID_BUFFER_SLOT;
72
Lajos Molnar5f920c12015-07-13 16:04:24 -070073 // In asynchronous mode the list is guaranteed to be one buffer deep,
74 // while in synchronous mode we use the oldest buffer.
Pablo Ceballosccdfd602015-10-07 15:05:45 -070075 if (mCore->mQueue.empty() && !sharedBufferAvailable) {
Lajos Molnar5f920c12015-07-13 16:04:24 -070076 return NO_BUFFER_AVAILABLE;
77 }
Dan Stoza289ade12014-02-28 11:17:17 -080078
Lajos Molnar5f920c12015-07-13 16:04:24 -070079 BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
Dan Stoza289ade12014-02-28 11:17:17 -080080
Lajos Molnar5f920c12015-07-13 16:04:24 -070081 // If expectedPresent is specified, we may not want to return a buffer yet.
82 // If it's specified and there's more than one buffer queued, we may want
83 // to drop a buffer.
Pablo Ceballosccdfd602015-10-07 15:05:45 -070084 // Skip this if we're in single buffer mode and the queue is empty,
85 // since in that case we'll just return the shared buffer.
86 if (expectedPresent != 0 && !mCore->mQueue.empty()) {
Lajos Molnar5f920c12015-07-13 16:04:24 -070087 const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second
Dan Stoza289ade12014-02-28 11:17:17 -080088
Lajos Molnar5f920c12015-07-13 16:04:24 -070089 // The 'expectedPresent' argument indicates when the buffer is expected
90 // to be presented on-screen. If the buffer's desired present time is
91 // earlier (less) than expectedPresent -- meaning it will be displayed
92 // on time or possibly late if we show it as soon as possible -- we
93 // acquire and return it. If we don't want to display it until after the
94 // expectedPresent time, we return PRESENT_LATER without acquiring it.
95 //
96 // To be safe, we don't defer acquisition if expectedPresent is more
97 // than one second in the future beyond the desired present time
98 // (i.e., we'd be holding the buffer for a long time).
99 //
100 // NOTE: Code assumes monotonic time values from the system clock
101 // are positive.
Dan Stoza289ade12014-02-28 11:17:17 -0800102
Lajos Molnar5f920c12015-07-13 16:04:24 -0700103 // Start by checking to see if we can drop frames. We skip this check if
104 // the timestamps are being auto-generated by Surface. If the app isn't
105 // generating timestamps explicitly, it probably doesn't want frames to
106 // be discarded based on them.
107 while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) {
108 const BufferItem& bufferItem(mCore->mQueue[1]);
Dan Stozaa4650a52015-05-12 12:56:16 -0700109
Lajos Molnar5f920c12015-07-13 16:04:24 -0700110 // If dropping entry[0] would leave us with a buffer that the
111 // consumer is not yet ready for, don't drop it.
112 if (maxFrameNumber && bufferItem.mFrameNumber > maxFrameNumber) {
113 break;
114 }
115
116 // If entry[1] is timely, drop entry[0] (and repeat). We apply an
117 // additional criterion here: we only drop the earlier buffer if our
118 // desiredPresent falls within +/- 1 second of the expected present.
119 // Otherwise, bogus desiredPresent times (e.g., 0 or a small
120 // relative timestamp), which normally mean "ignore the timestamp
121 // and acquire immediately", would cause us to drop frames.
122 //
123 // We may want to add an additional criterion: don't drop the
124 // earlier buffer if entry[1]'s fence hasn't signaled yet.
125 nsecs_t desiredPresent = bufferItem.mTimestamp;
126 if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC ||
127 desiredPresent > expectedPresent) {
128 // This buffer is set to display in the near future, or
129 // desiredPresent is garbage. Either way we don't want to drop
130 // the previous buffer just to get this on the screen sooner.
131 BQ_LOGV("acquireBuffer: nodrop desire=%" PRId64 " expect=%"
132 PRId64 " (%" PRId64 ") now=%" PRId64,
133 desiredPresent, expectedPresent,
134 desiredPresent - expectedPresent,
135 systemTime(CLOCK_MONOTONIC));
136 break;
137 }
138
139 BQ_LOGV("acquireBuffer: drop desire=%" PRId64 " expect=%" PRId64
140 " size=%zu",
141 desiredPresent, expectedPresent, mCore->mQueue.size());
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800142
143 if (!front->mIsStale) {
Lajos Molnar5f920c12015-07-13 16:04:24 -0700144 // Front buffer is still in mSlots, so mark the slot as free
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700145 mSlots[front->mSlot].mBufferState.freeQueued();
146
147 // After leaving single buffer mode, the shared buffer will
148 // still be around. Mark it as no longer shared if this
149 // operation causes it to be free.
150 if (!mCore->mSingleBufferMode &&
151 mSlots[front->mSlot].mBufferState.isFree()) {
152 mSlots[front->mSlot].mBufferState.mShared = false;
153 }
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800154
155 // Don't put the shared buffer on the free list
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700156 if (!mSlots[front->mSlot].mBufferState.isShared()) {
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800157 mCore->mActiveBuffers.erase(front->mSlot);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700158 mCore->mFreeBuffers.push_back(front->mSlot);
159 }
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800160
Lajos Molnar5f920c12015-07-13 16:04:24 -0700161 listener = mCore->mConnectedProducerListener;
162 ++numDroppedBuffers;
163 }
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800164
Lajos Molnar5f920c12015-07-13 16:04:24 -0700165 mCore->mQueue.erase(front);
166 front = mCore->mQueue.begin();
Dan Stozaecc50402015-04-28 14:42:06 -0700167 }
168
Lajos Molnar5f920c12015-07-13 16:04:24 -0700169 // See if the front buffer is ready to be acquired
170 nsecs_t desiredPresent = front->mTimestamp;
171 bool bufferIsDue = desiredPresent <= expectedPresent ||
172 desiredPresent > expectedPresent + MAX_REASONABLE_NSEC;
173 bool consumerIsReady = maxFrameNumber > 0 ?
174 front->mFrameNumber <= maxFrameNumber : true;
175 if (!bufferIsDue || !consumerIsReady) {
176 BQ_LOGV("acquireBuffer: defer desire=%" PRId64 " expect=%" PRId64
177 " (%" PRId64 ") now=%" PRId64 " frame=%" PRIu64
178 " consumer=%" PRIu64,
Mark Salyzyn8f515ce2014-06-09 14:32:04 -0700179 desiredPresent, expectedPresent,
Dan Stoza289ade12014-02-28 11:17:17 -0800180 desiredPresent - expectedPresent,
Lajos Molnar5f920c12015-07-13 16:04:24 -0700181 systemTime(CLOCK_MONOTONIC),
182 front->mFrameNumber, maxFrameNumber);
183 return PRESENT_LATER;
Dan Stoza289ade12014-02-28 11:17:17 -0800184 }
185
Lajos Molnar5f920c12015-07-13 16:04:24 -0700186 BQ_LOGV("acquireBuffer: accept desire=%" PRId64 " expect=%" PRId64 " "
187 "(%" PRId64 ") now=%" PRId64, desiredPresent, expectedPresent,
Dan Stoza289ade12014-02-28 11:17:17 -0800188 desiredPresent - expectedPresent,
Lajos Molnar5f920c12015-07-13 16:04:24 -0700189 systemTime(CLOCK_MONOTONIC));
Dan Stoza289ade12014-02-28 11:17:17 -0800190 }
191
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700192 int slot = BufferQueueCore::INVALID_BUFFER_SLOT;
193
194 if (sharedBufferAvailable && mCore->mQueue.empty()) {
195 // make sure the buffer has finished allocating before acquiring it
196 mCore->waitWhileAllocatingLocked();
197
198 slot = mCore->mSingleBufferSlot;
199
200 // Recreate the BufferItem for the shared buffer from the data that
201 // was cached when it was last queued.
202 outBuffer->mGraphicBuffer = mSlots[slot].mGraphicBuffer;
203 outBuffer->mFence = Fence::NO_FENCE;
204 outBuffer->mCrop = mCore->mSingleBufferCache.crop;
205 outBuffer->mTransform = mCore->mSingleBufferCache.transform &
206 ~static_cast<uint32_t>(
207 NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
208 outBuffer->mScalingMode = mCore->mSingleBufferCache.scalingMode;
209 outBuffer->mDataSpace = mCore->mSingleBufferCache.dataspace;
210 outBuffer->mFrameNumber = mCore->mFrameCounter;
211 outBuffer->mSlot = slot;
212 outBuffer->mAcquireCalled = mSlots[slot].mAcquireCalled;
213 outBuffer->mTransformToDisplayInverse =
214 (mCore->mSingleBufferCache.transform &
215 NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
216 outBuffer->mSurfaceDamage = Region::INVALID_REGION;
Pablo Ceballos06312182015-10-07 16:32:12 -0700217 outBuffer->mQueuedBuffer = false;
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800218 outBuffer->mIsStale = false;
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800219 outBuffer->mAutoRefresh = mCore->mSingleBufferMode &&
220 mCore->mAutoRefresh;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700221 } else {
222 slot = front->mSlot;
223 *outBuffer = *front;
224 }
225
Lajos Molnar5f920c12015-07-13 16:04:24 -0700226 ATRACE_BUFFER_INDEX(slot);
227
228 BQ_LOGV("acquireBuffer: acquiring { slot=%d/%" PRIu64 " buffer=%p }",
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700229 slot, outBuffer->mFrameNumber, outBuffer->mGraphicBuffer->handle);
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800230
231 if (!outBuffer->mIsStale) {
Lajos Molnar5f920c12015-07-13 16:04:24 -0700232 mSlots[slot].mAcquireCalled = true;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700233 // Don't decrease the queue count if the BufferItem wasn't
234 // previously in the queue. This happens in single buffer mode when
235 // the queue is empty and the BufferItem is created above.
236 if (mCore->mQueue.empty()) {
237 mSlots[slot].mBufferState.acquireNotInQueue();
238 } else {
239 mSlots[slot].mBufferState.acquire();
240 }
Lajos Molnar5f920c12015-07-13 16:04:24 -0700241 mSlots[slot].mFence = Fence::NO_FENCE;
242 }
243
244 // If the buffer has previously been acquired by the consumer, set
245 // mGraphicBuffer to NULL to avoid unnecessarily remapping this buffer
246 // on the consumer side
247 if (outBuffer->mAcquireCalled) {
248 outBuffer->mGraphicBuffer = NULL;
249 }
250
251 mCore->mQueue.erase(front);
252
253 // We might have freed a slot while dropping old buffers, or the producer
254 // may be blocked waiting for the number of buffers in the queue to
255 // decrease.
256 mCore->mDequeueCondition.broadcast();
257
258 ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
259
Pablo Ceballos9e314332016-01-12 13:49:19 -0800260 VALIDATE_CONSISTENCY();
Dan Stoza289ade12014-02-28 11:17:17 -0800261 }
262
Lajos Molnar5f920c12015-07-13 16:04:24 -0700263 if (listener != NULL) {
264 for (int i = 0; i < numDroppedBuffers; ++i) {
265 listener->onBufferReleased();
266 }
Dan Stoza289ade12014-02-28 11:17:17 -0800267 }
268
Dan Stoza289ade12014-02-28 11:17:17 -0800269 return NO_ERROR;
270}
271
Dan Stoza9f3053d2014-03-06 15:14:33 -0800272status_t BufferQueueConsumer::detachBuffer(int slot) {
273 ATRACE_CALL();
274 ATRACE_BUFFER_INDEX(slot);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700275 BQ_LOGV("detachBuffer: slot %d", slot);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800276 Mutex::Autolock lock(mCore->mMutex);
277
278 if (mCore->mIsAbandoned) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700279 BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800280 return NO_INIT;
281 }
282
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800283 if (mCore->mSingleBufferMode || slot == mCore->mSingleBufferSlot) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700284 BQ_LOGE("detachBuffer: detachBuffer not allowed in single buffer"
285 "mode");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800286 return BAD_VALUE;
287 }
288
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700289 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
290 BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
291 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
292 return BAD_VALUE;
293 } else if (!mSlots[slot].mBufferState.isAcquired()) {
294 BQ_LOGE("detachBuffer: slot %d is not owned by the consumer "
295 "(state = %s)", slot, mSlots[slot].mBufferState.string());
296 return BAD_VALUE;
297 }
298
299 mSlots[slot].mBufferState.detachConsumer();
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800300 mCore->mActiveBuffers.erase(slot);
301 mCore->mFreeSlots.insert(slot);
302 mCore->clearBufferSlotLocked(slot);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800303 mCore->mDequeueCondition.broadcast();
Pablo Ceballos9e314332016-01-12 13:49:19 -0800304 VALIDATE_CONSISTENCY();
Dan Stoza9f3053d2014-03-06 15:14:33 -0800305
306 return NO_ERROR;
307}
308
309status_t BufferQueueConsumer::attachBuffer(int* outSlot,
310 const sp<android::GraphicBuffer>& buffer) {
311 ATRACE_CALL();
312
313 if (outSlot == NULL) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700314 BQ_LOGE("attachBuffer: outSlot must not be NULL");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800315 return BAD_VALUE;
316 } else if (buffer == NULL) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700317 BQ_LOGE("attachBuffer: cannot attach NULL buffer");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800318 return BAD_VALUE;
319 }
320
321 Mutex::Autolock lock(mCore->mMutex);
322
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700323 if (mCore->mSingleBufferMode) {
324 BQ_LOGE("attachBuffer: cannot attach a buffer in single buffer"
325 "mode");
326 return BAD_VALUE;
327 }
328
Dan Stoza0de7ea72015-04-23 13:20:51 -0700329 // Make sure we don't have too many acquired buffers
Dan Stoza9f3053d2014-03-06 15:14:33 -0800330 int numAcquiredBuffers = 0;
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800331 for (int s : mCore->mActiveBuffers) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700332 if (mSlots[s].mBufferState.isAcquired()) {
Dan Stoza9f3053d2014-03-06 15:14:33 -0800333 ++numAcquiredBuffers;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800334 }
335 }
336
337 if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700338 BQ_LOGE("attachBuffer: max acquired buffer count reached: %d "
Dan Stoza9f3053d2014-03-06 15:14:33 -0800339 "(max %d)", numAcquiredBuffers,
340 mCore->mMaxAcquiredBufferCount);
341 return INVALID_OPERATION;
342 }
Dan Stoza0de7ea72015-04-23 13:20:51 -0700343
Dan Stoza812ed062015-06-02 15:45:22 -0700344 if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
345 BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
346 "[queue %u]", buffer->getGenerationNumber(),
347 mCore->mGenerationNumber);
348 return BAD_VALUE;
349 }
350
Dan Stoza0de7ea72015-04-23 13:20:51 -0700351 // Find a free slot to put the buffer into
352 int found = BufferQueueCore::INVALID_BUFFER_SLOT;
353 if (!mCore->mFreeSlots.empty()) {
354 auto slot = mCore->mFreeSlots.begin();
355 found = *slot;
356 mCore->mFreeSlots.erase(slot);
357 } else if (!mCore->mFreeBuffers.empty()) {
358 found = mCore->mFreeBuffers.front();
359 mCore->mFreeBuffers.remove(found);
360 }
Dan Stoza9f3053d2014-03-06 15:14:33 -0800361 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700362 BQ_LOGE("attachBuffer: could not find free buffer slot");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800363 return NO_MEMORY;
364 }
365
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800366 mCore->mActiveBuffers.insert(found);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800367 *outSlot = found;
368 ATRACE_BUFFER_INDEX(*outSlot);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700369 BQ_LOGV("attachBuffer: returning slot %d", *outSlot);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800370
371 mSlots[*outSlot].mGraphicBuffer = buffer;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700372 mSlots[*outSlot].mBufferState.attachConsumer();
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800373 mSlots[*outSlot].mNeedsReallocation = true;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800374 mSlots[*outSlot].mFence = Fence::NO_FENCE;
375 mSlots[*outSlot].mFrameNumber = 0;
376
Dan Stoza99b18b42014-03-28 15:34:33 -0700377 // mAcquireCalled tells BufferQueue that it doesn't need to send a valid
378 // GraphicBuffer pointer on the next acquireBuffer call, which decreases
379 // Binder traffic by not un/flattening the GraphicBuffer. However, it
380 // requires that the consumer maintain a cached copy of the slot <--> buffer
381 // mappings, which is why the consumer doesn't need the valid pointer on
382 // acquire.
383 //
384 // The StreamSplitter is one of the primary users of the attach/detach
385 // logic, and while it is running, all buffers it acquires are immediately
386 // detached, and all buffers it eventually releases are ones that were
387 // attached (as opposed to having been obtained from acquireBuffer), so it
388 // doesn't make sense to maintain the slot/buffer mappings, which would
389 // become invalid for every buffer during detach/attach. By setting this to
390 // false, the valid GraphicBuffer pointer will always be sent with acquire
391 // for attached buffers.
392 mSlots[*outSlot].mAcquireCalled = false;
393
Pablo Ceballos9e314332016-01-12 13:49:19 -0800394 VALIDATE_CONSISTENCY();
Dan Stoza0de7ea72015-04-23 13:20:51 -0700395
Dan Stoza9f3053d2014-03-06 15:14:33 -0800396 return NO_ERROR;
397}
398
Dan Stoza289ade12014-02-28 11:17:17 -0800399status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
400 const sp<Fence>& releaseFence, EGLDisplay eglDisplay,
401 EGLSyncKHR eglFence) {
402 ATRACE_CALL();
403 ATRACE_BUFFER_INDEX(slot);
404
Dan Stoza9f3053d2014-03-06 15:14:33 -0800405 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS ||
406 releaseFence == NULL) {
Dan Stoza52937cd2015-05-01 16:42:55 -0700407 BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot,
408 releaseFence.get());
Dan Stoza289ade12014-02-28 11:17:17 -0800409 return BAD_VALUE;
410 }
411
Dan Stozad1c10362014-03-28 15:19:08 -0700412 sp<IProducerListener> listener;
413 { // Autolock scope
414 Mutex::Autolock lock(mCore->mMutex);
Dan Stoza289ade12014-02-28 11:17:17 -0800415
Dan Stozad1c10362014-03-28 15:19:08 -0700416 // If the frame number has changed because the buffer has been reallocated,
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700417 // we can ignore this releaseBuffer for the old buffer.
418 // Ignore this for the shared buffer where the frame number can easily
419 // get out of sync due to the buffer being queued and acquired at the
420 // same time.
421 if (frameNumber != mSlots[slot].mFrameNumber &&
422 !mSlots[slot].mBufferState.isShared()) {
Dan Stozad1c10362014-03-28 15:19:08 -0700423 return STALE_BUFFER_SLOT;
424 }
Dan Stoza289ade12014-02-28 11:17:17 -0800425
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800426 if (!mSlots[slot].mBufferState.isAcquired()) {
Dan Stoza52937cd2015-05-01 16:42:55 -0700427 BQ_LOGE("releaseBuffer: attempted to release buffer slot %d "
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700428 "but its state was %s", slot,
429 mSlots[slot].mBufferState.string());
Dan Stoza9f3053d2014-03-06 15:14:33 -0800430 return BAD_VALUE;
Dan Stoza289ade12014-02-28 11:17:17 -0800431 }
Dan Stoza289ade12014-02-28 11:17:17 -0800432
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800433 mSlots[slot].mEglDisplay = eglDisplay;
434 mSlots[slot].mEglFence = eglFence;
435 mSlots[slot].mFence = releaseFence;
436 mSlots[slot].mBufferState.release();
437
438 // After leaving single buffer mode, the shared buffer will
439 // still be around. Mark it as no longer shared if this
440 // operation causes it to be free.
441 if (!mCore->mSingleBufferMode && mSlots[slot].mBufferState.isFree()) {
442 mSlots[slot].mBufferState.mShared = false;
443 }
444 // Don't put the shared buffer on the free list.
445 if (!mSlots[slot].mBufferState.isShared()) {
446 mCore->mActiveBuffers.erase(slot);
447 mCore->mFreeBuffers.push_back(slot);
448 }
449
450 listener = mCore->mConnectedProducerListener;
451 BQ_LOGV("releaseBuffer: releasing slot %d", slot);
452
Dan Stozad1c10362014-03-28 15:19:08 -0700453 mCore->mDequeueCondition.broadcast();
Pablo Ceballos9e314332016-01-12 13:49:19 -0800454 VALIDATE_CONSISTENCY();
Dan Stozad1c10362014-03-28 15:19:08 -0700455 } // Autolock scope
Dan Stoza289ade12014-02-28 11:17:17 -0800456
Dan Stozad1c10362014-03-28 15:19:08 -0700457 // Call back without lock held
458 if (listener != NULL) {
459 listener->onBufferReleased();
460 }
Dan Stoza289ade12014-02-28 11:17:17 -0800461
462 return NO_ERROR;
463}
464
465status_t BufferQueueConsumer::connect(
466 const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
467 ATRACE_CALL();
468
469 if (consumerListener == NULL) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700470 BQ_LOGE("connect: consumerListener may not be NULL");
Dan Stoza289ade12014-02-28 11:17:17 -0800471 return BAD_VALUE;
472 }
473
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700474 BQ_LOGV("connect: controlledByApp=%s",
Dan Stoza289ade12014-02-28 11:17:17 -0800475 controlledByApp ? "true" : "false");
476
477 Mutex::Autolock lock(mCore->mMutex);
478
479 if (mCore->mIsAbandoned) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700480 BQ_LOGE("connect: BufferQueue has been abandoned");
Dan Stoza289ade12014-02-28 11:17:17 -0800481 return NO_INIT;
482 }
483
484 mCore->mConsumerListener = consumerListener;
485 mCore->mConsumerControlledByApp = controlledByApp;
486
487 return NO_ERROR;
488}
489
490status_t BufferQueueConsumer::disconnect() {
491 ATRACE_CALL();
492
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700493 BQ_LOGV("disconnect");
Dan Stoza289ade12014-02-28 11:17:17 -0800494
495 Mutex::Autolock lock(mCore->mMutex);
496
497 if (mCore->mConsumerListener == NULL) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700498 BQ_LOGE("disconnect: no consumer is connected");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800499 return BAD_VALUE;
Dan Stoza289ade12014-02-28 11:17:17 -0800500 }
501
502 mCore->mIsAbandoned = true;
503 mCore->mConsumerListener = NULL;
504 mCore->mQueue.clear();
505 mCore->freeAllBuffersLocked();
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800506 mCore->mSingleBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
Dan Stoza289ade12014-02-28 11:17:17 -0800507 mCore->mDequeueCondition.broadcast();
508 return NO_ERROR;
509}
510
Dan Stozafebd4f42014-04-09 16:14:51 -0700511status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) {
Dan Stoza289ade12014-02-28 11:17:17 -0800512 ATRACE_CALL();
513
514 if (outSlotMask == NULL) {
515 BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL");
516 return BAD_VALUE;
517 }
518
519 Mutex::Autolock lock(mCore->mMutex);
520
521 if (mCore->mIsAbandoned) {
522 BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned");
523 return NO_INIT;
524 }
525
Dan Stozafebd4f42014-04-09 16:14:51 -0700526 uint64_t mask = 0;
Dan Stoza3e96f192014-03-03 10:16:19 -0800527 for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
Dan Stoza289ade12014-02-28 11:17:17 -0800528 if (!mSlots[s].mAcquireCalled) {
Dan Stozafebd4f42014-04-09 16:14:51 -0700529 mask |= (1ULL << s);
Dan Stoza289ade12014-02-28 11:17:17 -0800530 }
531 }
532
533 // Remove from the mask queued buffers for which acquire has been called,
534 // since the consumer will not receive their buffer addresses and so must
535 // retain their cached information
536 BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
537 while (current != mCore->mQueue.end()) {
538 if (current->mAcquireCalled) {
Dan Stozafebd4f42014-04-09 16:14:51 -0700539 mask &= ~(1ULL << current->mSlot);
Dan Stoza289ade12014-02-28 11:17:17 -0800540 }
541 ++current;
542 }
543
Dan Stozafebd4f42014-04-09 16:14:51 -0700544 BQ_LOGV("getReleasedBuffers: returning mask %#" PRIx64, mask);
Dan Stoza289ade12014-02-28 11:17:17 -0800545 *outSlotMask = mask;
546 return NO_ERROR;
547}
548
549status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width,
550 uint32_t height) {
551 ATRACE_CALL();
552
553 if (width == 0 || height == 0) {
554 BQ_LOGV("setDefaultBufferSize: dimensions cannot be 0 (width=%u "
555 "height=%u)", width, height);
556 return BAD_VALUE;
557 }
558
559 BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height);
560
561 Mutex::Autolock lock(mCore->mMutex);
562 mCore->mDefaultWidth = width;
563 mCore->mDefaultHeight = height;
564 return NO_ERROR;
565}
566
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700567status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) {
Dan Stoza289ade12014-02-28 11:17:17 -0800568 ATRACE_CALL();
Dan Stoza289ade12014-02-28 11:17:17 -0800569
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700570 if (bufferCount < 1 || bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
571 BQ_LOGE("setMaxBufferCount: invalid count %d", bufferCount);
572 return BAD_VALUE;
573 }
Dan Stoza289ade12014-02-28 11:17:17 -0800574
575 Mutex::Autolock lock(mCore->mMutex);
576
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700577 if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
578 BQ_LOGE("setMaxBufferCount: producer is already connected");
Dan Stoza289ade12014-02-28 11:17:17 -0800579 return INVALID_OPERATION;
580 }
581
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700582 if (bufferCount < mCore->mMaxAcquiredBufferCount) {
583 BQ_LOGE("setMaxBufferCount: invalid buffer count (%d) less than"
584 "mMaxAcquiredBufferCount (%d)", bufferCount,
585 mCore->mMaxAcquiredBufferCount);
586 return BAD_VALUE;
587 }
588
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800589 int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
590 mCore->mDequeueBufferCannotBlock, bufferCount) -
591 mCore->getMaxBufferCountLocked();
592 if (!mCore->adjustAvailableSlotsLocked(delta)) {
593 BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number of "
594 "available slots. Delta = %d", delta);
595 return BAD_VALUE;
596 }
597
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700598 mCore->mMaxBufferCount = bufferCount;
Dan Stoza289ade12014-02-28 11:17:17 -0800599 return NO_ERROR;
600}
601
602status_t BufferQueueConsumer::setMaxAcquiredBufferCount(
603 int maxAcquiredBuffers) {
604 ATRACE_CALL();
605
606 if (maxAcquiredBuffers < 1 ||
607 maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) {
608 BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d",
609 maxAcquiredBuffers);
610 return BAD_VALUE;
611 }
612
Pablo Ceballos72daab62015-12-07 16:38:43 -0800613 sp<IConsumerListener> listener;
614 { // Autolock scope
615 Mutex::Autolock lock(mCore->mMutex);
616 mCore->waitWhileAllocatingLocked();
Dan Stoza289ade12014-02-28 11:17:17 -0800617
Pablo Ceballos72daab62015-12-07 16:38:43 -0800618 if (mCore->mIsAbandoned) {
619 BQ_LOGE("setMaxAcquiredBufferCount: consumer is abandoned");
620 return NO_INIT;
621 }
622
623 // The new maxAcquiredBuffers count should not be violated by the number
624 // of currently acquired buffers
625 int acquiredCount = 0;
626 for (int slot : mCore->mActiveBuffers) {
627 if (mSlots[slot].mBufferState.isAcquired()) {
628 acquiredCount++;
629 }
630 }
631 if (acquiredCount > maxAcquiredBuffers) {
632 BQ_LOGE("setMaxAcquiredBufferCount: the requested maxAcquiredBuffer"
633 "count (%d) exceeds the current acquired buffer count (%d)",
634 maxAcquiredBuffers, acquiredCount);
635 return BAD_VALUE;
636 }
637
638 if ((maxAcquiredBuffers + mCore->mMaxDequeuedBufferCount +
639 (mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock ? 1 : 0))
640 > mCore->mMaxBufferCount) {
641 BQ_LOGE("setMaxAcquiredBufferCount: %d acquired buffers would "
642 "exceed the maxBufferCount (%d) (maxDequeued %d async %d)",
643 maxAcquiredBuffers, mCore->mMaxBufferCount,
644 mCore->mMaxDequeuedBufferCount, mCore->mAsyncMode ||
645 mCore->mDequeueBufferCannotBlock);
646 return BAD_VALUE;
647 }
648
649 int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount;
650 if (!mCore->adjustAvailableSlotsLocked(delta)) {
651 return BAD_VALUE;
652 }
653
654 BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
655 mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
656 VALIDATE_CONSISTENCY();
657 if (delta < 0) {
658 listener = mCore->mConsumerListener;
659 }
660 }
661 // Call back without lock held
662 if (listener != NULL) {
663 listener->onBuffersReleased();
Dan Stoza289ade12014-02-28 11:17:17 -0800664 }
665
Dan Stoza289ade12014-02-28 11:17:17 -0800666 return NO_ERROR;
667}
668
669void BufferQueueConsumer::setConsumerName(const String8& name) {
670 ATRACE_CALL();
671 BQ_LOGV("setConsumerName: '%s'", name.string());
672 Mutex::Autolock lock(mCore->mMutex);
673 mCore->mConsumerName = name;
674 mConsumerName = name;
675}
676
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800677status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
Dan Stoza289ade12014-02-28 11:17:17 -0800678 ATRACE_CALL();
679 BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat);
680 Mutex::Autolock lock(mCore->mMutex);
681 mCore->mDefaultBufferFormat = defaultFormat;
682 return NO_ERROR;
683}
684
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800685status_t BufferQueueConsumer::setDefaultBufferDataSpace(
686 android_dataspace defaultDataSpace) {
687 ATRACE_CALL();
688 BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace);
689 Mutex::Autolock lock(mCore->mMutex);
690 mCore->mDefaultBufferDataSpace = defaultDataSpace;
691 return NO_ERROR;
692}
693
Dan Stoza289ade12014-02-28 11:17:17 -0800694status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) {
695 ATRACE_CALL();
696 BQ_LOGV("setConsumerUsageBits: %#x", usage);
697 Mutex::Autolock lock(mCore->mMutex);
698 mCore->mConsumerUsageBits = usage;
699 return NO_ERROR;
700}
701
702status_t BufferQueueConsumer::setTransformHint(uint32_t hint) {
703 ATRACE_CALL();
704 BQ_LOGV("setTransformHint: %#x", hint);
705 Mutex::Autolock lock(mCore->mMutex);
706 mCore->mTransformHint = hint;
707 return NO_ERROR;
708}
709
Jesse Hall399184a2014-03-03 15:42:54 -0800710sp<NativeHandle> BufferQueueConsumer::getSidebandStream() const {
711 return mCore->mSidebandStream;
712}
713
Dan Stoza289ade12014-02-28 11:17:17 -0800714void BufferQueueConsumer::dump(String8& result, const char* prefix) const {
715 mCore->dump(result, prefix);
716}
717
718} // namespace android