blob: be754c25fc9f28133e99f261861b9155d0c79586 [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
Pablo Ceballos88f69282016-02-11 18:01:49 -080035#include <binder/IPCThreadState.h>
36#include <binder/PermissionCache.h>
37#include <private/android_filesystem_config.h>
38
Mathias Agopian6a3c05b2017-04-27 20:06:55 -070039#include <system/window.h>
40
Dan Stoza289ade12014-02-28 11:17:17 -080041namespace android {
42
43BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
44 mCore(core),
45 mSlots(core->mSlots),
46 mConsumerName() {}
47
48BufferQueueConsumer::~BufferQueueConsumer() {}
49
50status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
Dan Stozaa4650a52015-05-12 12:56:16 -070051 nsecs_t expectedPresent, uint64_t maxFrameNumber) {
Dan Stoza289ade12014-02-28 11:17:17 -080052 ATRACE_CALL();
Dan Stoza289ade12014-02-28 11:17:17 -080053
Lajos Molnar5f920c12015-07-13 16:04:24 -070054 int numDroppedBuffers = 0;
55 sp<IProducerListener> listener;
56 {
57 Mutex::Autolock lock(mCore->mMutex);
58
59 // Check that the consumer doesn't currently have the maximum number of
60 // buffers acquired. We allow the max buffer count to be exceeded by one
61 // buffer so that the consumer can successfully set up the newly acquired
62 // buffer before releasing the old one.
63 int numAcquiredBuffers = 0;
Pablo Ceballos23b4abe2016-01-08 12:15:22 -080064 for (int s : mCore->mActiveBuffers) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -070065 if (mSlots[s].mBufferState.isAcquired()) {
Lajos Molnar5f920c12015-07-13 16:04:24 -070066 ++numAcquiredBuffers;
67 }
Dan Stoza289ade12014-02-28 11:17:17 -080068 }
Lajos Molnar5f920c12015-07-13 16:04:24 -070069 if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
70 BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)",
71 numAcquiredBuffers, mCore->mMaxAcquiredBufferCount);
72 return INVALID_OPERATION;
73 }
Dan Stoza289ade12014-02-28 11:17:17 -080074
Pablo Ceballos3559fbf2016-03-17 15:50:23 -070075 bool sharedBufferAvailable = mCore->mSharedBufferMode &&
76 mCore->mAutoRefresh && mCore->mSharedBufferSlot !=
Pablo Ceballosccdfd602015-10-07 15:05:45 -070077 BufferQueueCore::INVALID_BUFFER_SLOT;
78
Lajos Molnar5f920c12015-07-13 16:04:24 -070079 // In asynchronous mode the list is guaranteed to be one buffer deep,
80 // while in synchronous mode we use the oldest buffer.
Pablo Ceballosccdfd602015-10-07 15:05:45 -070081 if (mCore->mQueue.empty() && !sharedBufferAvailable) {
Lajos Molnar5f920c12015-07-13 16:04:24 -070082 return NO_BUFFER_AVAILABLE;
83 }
Dan Stoza289ade12014-02-28 11:17:17 -080084
Lajos Molnar5f920c12015-07-13 16:04:24 -070085 BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
Dan Stoza289ade12014-02-28 11:17:17 -080086
Lajos Molnar5f920c12015-07-13 16:04:24 -070087 // If expectedPresent is specified, we may not want to return a buffer yet.
88 // If it's specified and there's more than one buffer queued, we may want
89 // to drop a buffer.
Pablo Ceballos3559fbf2016-03-17 15:50:23 -070090 // Skip this if we're in shared buffer mode and the queue is empty,
Pablo Ceballosccdfd602015-10-07 15:05:45 -070091 // since in that case we'll just return the shared buffer.
92 if (expectedPresent != 0 && !mCore->mQueue.empty()) {
Lajos Molnar5f920c12015-07-13 16:04:24 -070093 const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second
Dan Stoza289ade12014-02-28 11:17:17 -080094
Lajos Molnar5f920c12015-07-13 16:04:24 -070095 // The 'expectedPresent' argument indicates when the buffer is expected
96 // to be presented on-screen. If the buffer's desired present time is
97 // earlier (less) than expectedPresent -- meaning it will be displayed
98 // on time or possibly late if we show it as soon as possible -- we
99 // acquire and return it. If we don't want to display it until after the
100 // expectedPresent time, we return PRESENT_LATER without acquiring it.
101 //
102 // To be safe, we don't defer acquisition if expectedPresent is more
103 // than one second in the future beyond the desired present time
104 // (i.e., we'd be holding the buffer for a long time).
105 //
106 // NOTE: Code assumes monotonic time values from the system clock
107 // are positive.
Dan Stoza289ade12014-02-28 11:17:17 -0800108
Lajos Molnar5f920c12015-07-13 16:04:24 -0700109 // Start by checking to see if we can drop frames. We skip this check if
110 // the timestamps are being auto-generated by Surface. If the app isn't
111 // generating timestamps explicitly, it probably doesn't want frames to
112 // be discarded based on them.
113 while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) {
114 const BufferItem& bufferItem(mCore->mQueue[1]);
Dan Stozaa4650a52015-05-12 12:56:16 -0700115
Lajos Molnar5f920c12015-07-13 16:04:24 -0700116 // If dropping entry[0] would leave us with a buffer that the
117 // consumer is not yet ready for, don't drop it.
118 if (maxFrameNumber && bufferItem.mFrameNumber > maxFrameNumber) {
119 break;
120 }
121
122 // If entry[1] is timely, drop entry[0] (and repeat). We apply an
123 // additional criterion here: we only drop the earlier buffer if our
124 // desiredPresent falls within +/- 1 second of the expected present.
125 // Otherwise, bogus desiredPresent times (e.g., 0 or a small
126 // relative timestamp), which normally mean "ignore the timestamp
127 // and acquire immediately", would cause us to drop frames.
128 //
129 // We may want to add an additional criterion: don't drop the
130 // earlier buffer if entry[1]'s fence hasn't signaled yet.
131 nsecs_t desiredPresent = bufferItem.mTimestamp;
132 if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC ||
133 desiredPresent > expectedPresent) {
134 // This buffer is set to display in the near future, or
135 // desiredPresent is garbage. Either way we don't want to drop
136 // the previous buffer just to get this on the screen sooner.
137 BQ_LOGV("acquireBuffer: nodrop desire=%" PRId64 " expect=%"
138 PRId64 " (%" PRId64 ") now=%" PRId64,
139 desiredPresent, expectedPresent,
140 desiredPresent - expectedPresent,
141 systemTime(CLOCK_MONOTONIC));
142 break;
143 }
144
145 BQ_LOGV("acquireBuffer: drop desire=%" PRId64 " expect=%" PRId64
146 " size=%zu",
147 desiredPresent, expectedPresent, mCore->mQueue.size());
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800148
149 if (!front->mIsStale) {
Lajos Molnar5f920c12015-07-13 16:04:24 -0700150 // Front buffer is still in mSlots, so mark the slot as free
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700151 mSlots[front->mSlot].mBufferState.freeQueued();
152
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700153 // After leaving shared buffer mode, the shared buffer will
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700154 // still be around. Mark it as no longer shared if this
155 // operation causes it to be free.
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700156 if (!mCore->mSharedBufferMode &&
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700157 mSlots[front->mSlot].mBufferState.isFree()) {
158 mSlots[front->mSlot].mBufferState.mShared = false;
159 }
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800160
161 // Don't put the shared buffer on the free list
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700162 if (!mSlots[front->mSlot].mBufferState.isShared()) {
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800163 mCore->mActiveBuffers.erase(front->mSlot);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700164 mCore->mFreeBuffers.push_back(front->mSlot);
165 }
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800166
Lajos Molnar5f920c12015-07-13 16:04:24 -0700167 listener = mCore->mConnectedProducerListener;
168 ++numDroppedBuffers;
169 }
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800170
Lajos Molnar5f920c12015-07-13 16:04:24 -0700171 mCore->mQueue.erase(front);
172 front = mCore->mQueue.begin();
Dan Stozaecc50402015-04-28 14:42:06 -0700173 }
174
Lajos Molnar5f920c12015-07-13 16:04:24 -0700175 // See if the front buffer is ready to be acquired
176 nsecs_t desiredPresent = front->mTimestamp;
177 bool bufferIsDue = desiredPresent <= expectedPresent ||
178 desiredPresent > expectedPresent + MAX_REASONABLE_NSEC;
179 bool consumerIsReady = maxFrameNumber > 0 ?
180 front->mFrameNumber <= maxFrameNumber : true;
181 if (!bufferIsDue || !consumerIsReady) {
182 BQ_LOGV("acquireBuffer: defer desire=%" PRId64 " expect=%" PRId64
183 " (%" PRId64 ") now=%" PRId64 " frame=%" PRIu64
184 " consumer=%" PRIu64,
Mark Salyzyn8f515ce2014-06-09 14:32:04 -0700185 desiredPresent, expectedPresent,
Dan Stoza289ade12014-02-28 11:17:17 -0800186 desiredPresent - expectedPresent,
Lajos Molnar5f920c12015-07-13 16:04:24 -0700187 systemTime(CLOCK_MONOTONIC),
188 front->mFrameNumber, maxFrameNumber);
189 return PRESENT_LATER;
Dan Stoza289ade12014-02-28 11:17:17 -0800190 }
191
Lajos Molnar5f920c12015-07-13 16:04:24 -0700192 BQ_LOGV("acquireBuffer: accept desire=%" PRId64 " expect=%" PRId64 " "
193 "(%" PRId64 ") now=%" PRId64, desiredPresent, expectedPresent,
Dan Stoza289ade12014-02-28 11:17:17 -0800194 desiredPresent - expectedPresent,
Lajos Molnar5f920c12015-07-13 16:04:24 -0700195 systemTime(CLOCK_MONOTONIC));
Dan Stoza289ade12014-02-28 11:17:17 -0800196 }
197
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700198 int slot = BufferQueueCore::INVALID_BUFFER_SLOT;
199
200 if (sharedBufferAvailable && mCore->mQueue.empty()) {
201 // make sure the buffer has finished allocating before acquiring it
202 mCore->waitWhileAllocatingLocked();
203
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700204 slot = mCore->mSharedBufferSlot;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700205
206 // Recreate the BufferItem for the shared buffer from the data that
207 // was cached when it was last queued.
208 outBuffer->mGraphicBuffer = mSlots[slot].mGraphicBuffer;
209 outBuffer->mFence = Fence::NO_FENCE;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700210 outBuffer->mFenceTime = FenceTime::NO_FENCE;
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700211 outBuffer->mCrop = mCore->mSharedBufferCache.crop;
212 outBuffer->mTransform = mCore->mSharedBufferCache.transform &
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700213 ~static_cast<uint32_t>(
214 NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700215 outBuffer->mScalingMode = mCore->mSharedBufferCache.scalingMode;
216 outBuffer->mDataSpace = mCore->mSharedBufferCache.dataspace;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700217 outBuffer->mFrameNumber = mCore->mFrameCounter;
218 outBuffer->mSlot = slot;
219 outBuffer->mAcquireCalled = mSlots[slot].mAcquireCalled;
220 outBuffer->mTransformToDisplayInverse =
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700221 (mCore->mSharedBufferCache.transform &
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700222 NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
223 outBuffer->mSurfaceDamage = Region::INVALID_REGION;
Pablo Ceballos06312182015-10-07 16:32:12 -0700224 outBuffer->mQueuedBuffer = false;
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800225 outBuffer->mIsStale = false;
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700226 outBuffer->mAutoRefresh = mCore->mSharedBufferMode &&
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800227 mCore->mAutoRefresh;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700228 } else {
229 slot = front->mSlot;
230 *outBuffer = *front;
231 }
232
Lajos Molnar5f920c12015-07-13 16:04:24 -0700233 ATRACE_BUFFER_INDEX(slot);
234
235 BQ_LOGV("acquireBuffer: acquiring { slot=%d/%" PRIu64 " buffer=%p }",
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700236 slot, outBuffer->mFrameNumber, outBuffer->mGraphicBuffer->handle);
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800237
238 if (!outBuffer->mIsStale) {
Lajos Molnar5f920c12015-07-13 16:04:24 -0700239 mSlots[slot].mAcquireCalled = true;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700240 // Don't decrease the queue count if the BufferItem wasn't
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700241 // previously in the queue. This happens in shared buffer mode when
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700242 // the queue is empty and the BufferItem is created above.
243 if (mCore->mQueue.empty()) {
244 mSlots[slot].mBufferState.acquireNotInQueue();
245 } else {
246 mSlots[slot].mBufferState.acquire();
247 }
Lajos Molnar5f920c12015-07-13 16:04:24 -0700248 mSlots[slot].mFence = Fence::NO_FENCE;
249 }
250
251 // If the buffer has previously been acquired by the consumer, set
252 // mGraphicBuffer to NULL to avoid unnecessarily remapping this buffer
253 // on the consumer side
254 if (outBuffer->mAcquireCalled) {
255 outBuffer->mGraphicBuffer = NULL;
256 }
257
258 mCore->mQueue.erase(front);
259
260 // We might have freed a slot while dropping old buffers, or the producer
261 // may be blocked waiting for the number of buffers in the queue to
262 // decrease.
263 mCore->mDequeueCondition.broadcast();
264
Colin Cross6e7e2b42016-09-27 14:08:19 -0700265 ATRACE_INT(mCore->mConsumerName.string(),
266 static_cast<int32_t>(mCore->mQueue.size()));
Dan Stozae77c7662016-05-13 11:37:28 -0700267 mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size());
Lajos Molnar5f920c12015-07-13 16:04:24 -0700268
Pablo Ceballos9e314332016-01-12 13:49:19 -0800269 VALIDATE_CONSISTENCY();
Dan Stoza289ade12014-02-28 11:17:17 -0800270 }
271
Lajos Molnar5f920c12015-07-13 16:04:24 -0700272 if (listener != NULL) {
273 for (int i = 0; i < numDroppedBuffers; ++i) {
274 listener->onBufferReleased();
275 }
Dan Stoza289ade12014-02-28 11:17:17 -0800276 }
277
Dan Stoza289ade12014-02-28 11:17:17 -0800278 return NO_ERROR;
279}
280
Dan Stoza9f3053d2014-03-06 15:14:33 -0800281status_t BufferQueueConsumer::detachBuffer(int slot) {
282 ATRACE_CALL();
283 ATRACE_BUFFER_INDEX(slot);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700284 BQ_LOGV("detachBuffer: slot %d", slot);
Pablo Ceballos38273792016-03-02 01:38:10 +0000285 Mutex::Autolock lock(mCore->mMutex);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800286
Pablo Ceballos38273792016-03-02 01:38:10 +0000287 if (mCore->mIsAbandoned) {
288 BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
289 return NO_INIT;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800290 }
291
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700292 if (mCore->mSharedBufferMode || slot == mCore->mSharedBufferSlot) {
293 BQ_LOGE("detachBuffer: detachBuffer not allowed in shared buffer mode");
Pablo Ceballos38273792016-03-02 01:38:10 +0000294 return BAD_VALUE;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800295 }
296
Pablo Ceballos38273792016-03-02 01:38:10 +0000297 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
298 BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
299 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
300 return BAD_VALUE;
301 } else if (!mSlots[slot].mBufferState.isAcquired()) {
302 BQ_LOGE("detachBuffer: slot %d is not owned by the consumer "
303 "(state = %s)", slot, mSlots[slot].mBufferState.string());
304 return BAD_VALUE;
305 }
306
307 mSlots[slot].mBufferState.detachConsumer();
308 mCore->mActiveBuffers.erase(slot);
309 mCore->mFreeSlots.insert(slot);
310 mCore->clearBufferSlotLocked(slot);
311 mCore->mDequeueCondition.broadcast();
312 VALIDATE_CONSISTENCY();
Dan Stoza9f3053d2014-03-06 15:14:33 -0800313
314 return NO_ERROR;
315}
316
317status_t BufferQueueConsumer::attachBuffer(int* outSlot,
318 const sp<android::GraphicBuffer>& buffer) {
319 ATRACE_CALL();
320
321 if (outSlot == NULL) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700322 BQ_LOGE("attachBuffer: outSlot must not be NULL");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800323 return BAD_VALUE;
324 } else if (buffer == NULL) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700325 BQ_LOGE("attachBuffer: cannot attach NULL buffer");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800326 return BAD_VALUE;
327 }
328
329 Mutex::Autolock lock(mCore->mMutex);
330
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700331 if (mCore->mSharedBufferMode) {
332 BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700333 return BAD_VALUE;
334 }
335
Dan Stoza0de7ea72015-04-23 13:20:51 -0700336 // Make sure we don't have too many acquired buffers
Dan Stoza9f3053d2014-03-06 15:14:33 -0800337 int numAcquiredBuffers = 0;
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800338 for (int s : mCore->mActiveBuffers) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700339 if (mSlots[s].mBufferState.isAcquired()) {
Dan Stoza9f3053d2014-03-06 15:14:33 -0800340 ++numAcquiredBuffers;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800341 }
342 }
343
344 if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700345 BQ_LOGE("attachBuffer: max acquired buffer count reached: %d "
Dan Stoza9f3053d2014-03-06 15:14:33 -0800346 "(max %d)", numAcquiredBuffers,
347 mCore->mMaxAcquiredBufferCount);
348 return INVALID_OPERATION;
349 }
Dan Stoza0de7ea72015-04-23 13:20:51 -0700350
Dan Stoza812ed062015-06-02 15:45:22 -0700351 if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
352 BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
353 "[queue %u]", buffer->getGenerationNumber(),
354 mCore->mGenerationNumber);
355 return BAD_VALUE;
356 }
357
Dan Stoza0de7ea72015-04-23 13:20:51 -0700358 // Find a free slot to put the buffer into
359 int found = BufferQueueCore::INVALID_BUFFER_SLOT;
360 if (!mCore->mFreeSlots.empty()) {
361 auto slot = mCore->mFreeSlots.begin();
362 found = *slot;
363 mCore->mFreeSlots.erase(slot);
364 } else if (!mCore->mFreeBuffers.empty()) {
365 found = mCore->mFreeBuffers.front();
366 mCore->mFreeBuffers.remove(found);
367 }
Dan Stoza9f3053d2014-03-06 15:14:33 -0800368 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700369 BQ_LOGE("attachBuffer: could not find free buffer slot");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800370 return NO_MEMORY;
371 }
372
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800373 mCore->mActiveBuffers.insert(found);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800374 *outSlot = found;
375 ATRACE_BUFFER_INDEX(*outSlot);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700376 BQ_LOGV("attachBuffer: returning slot %d", *outSlot);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800377
378 mSlots[*outSlot].mGraphicBuffer = buffer;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700379 mSlots[*outSlot].mBufferState.attachConsumer();
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800380 mSlots[*outSlot].mNeedsReallocation = true;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800381 mSlots[*outSlot].mFence = Fence::NO_FENCE;
382 mSlots[*outSlot].mFrameNumber = 0;
383
Dan Stoza99b18b42014-03-28 15:34:33 -0700384 // mAcquireCalled tells BufferQueue that it doesn't need to send a valid
385 // GraphicBuffer pointer on the next acquireBuffer call, which decreases
386 // Binder traffic by not un/flattening the GraphicBuffer. However, it
387 // requires that the consumer maintain a cached copy of the slot <--> buffer
388 // mappings, which is why the consumer doesn't need the valid pointer on
389 // acquire.
390 //
391 // The StreamSplitter is one of the primary users of the attach/detach
392 // logic, and while it is running, all buffers it acquires are immediately
393 // detached, and all buffers it eventually releases are ones that were
394 // attached (as opposed to having been obtained from acquireBuffer), so it
395 // doesn't make sense to maintain the slot/buffer mappings, which would
396 // become invalid for every buffer during detach/attach. By setting this to
397 // false, the valid GraphicBuffer pointer will always be sent with acquire
398 // for attached buffers.
399 mSlots[*outSlot].mAcquireCalled = false;
400
Pablo Ceballos9e314332016-01-12 13:49:19 -0800401 VALIDATE_CONSISTENCY();
Dan Stoza0de7ea72015-04-23 13:20:51 -0700402
Dan Stoza9f3053d2014-03-06 15:14:33 -0800403 return NO_ERROR;
404}
405
Dan Stoza289ade12014-02-28 11:17:17 -0800406status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
407 const sp<Fence>& releaseFence, EGLDisplay eglDisplay,
408 EGLSyncKHR eglFence) {
409 ATRACE_CALL();
410 ATRACE_BUFFER_INDEX(slot);
411
Dan Stoza9f3053d2014-03-06 15:14:33 -0800412 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS ||
413 releaseFence == NULL) {
Dan Stoza52937cd2015-05-01 16:42:55 -0700414 BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot,
415 releaseFence.get());
Dan Stoza289ade12014-02-28 11:17:17 -0800416 return BAD_VALUE;
417 }
418
Dan Stozad1c10362014-03-28 15:19:08 -0700419 sp<IProducerListener> listener;
420 { // Autolock scope
421 Mutex::Autolock lock(mCore->mMutex);
Dan Stoza289ade12014-02-28 11:17:17 -0800422
Dan Stozad1c10362014-03-28 15:19:08 -0700423 // If the frame number has changed because the buffer has been reallocated,
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700424 // we can ignore this releaseBuffer for the old buffer.
425 // Ignore this for the shared buffer where the frame number can easily
426 // get out of sync due to the buffer being queued and acquired at the
427 // same time.
428 if (frameNumber != mSlots[slot].mFrameNumber &&
429 !mSlots[slot].mBufferState.isShared()) {
Dan Stozad1c10362014-03-28 15:19:08 -0700430 return STALE_BUFFER_SLOT;
431 }
Dan Stoza289ade12014-02-28 11:17:17 -0800432
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800433 if (!mSlots[slot].mBufferState.isAcquired()) {
Dan Stoza52937cd2015-05-01 16:42:55 -0700434 BQ_LOGE("releaseBuffer: attempted to release buffer slot %d "
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700435 "but its state was %s", slot,
436 mSlots[slot].mBufferState.string());
Dan Stoza9f3053d2014-03-06 15:14:33 -0800437 return BAD_VALUE;
Dan Stoza289ade12014-02-28 11:17:17 -0800438 }
Dan Stoza289ade12014-02-28 11:17:17 -0800439
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800440 mSlots[slot].mEglDisplay = eglDisplay;
441 mSlots[slot].mEglFence = eglFence;
442 mSlots[slot].mFence = releaseFence;
443 mSlots[slot].mBufferState.release();
444
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700445 // After leaving shared buffer mode, the shared buffer will
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800446 // still be around. Mark it as no longer shared if this
447 // operation causes it to be free.
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700448 if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800449 mSlots[slot].mBufferState.mShared = false;
450 }
451 // Don't put the shared buffer on the free list.
452 if (!mSlots[slot].mBufferState.isShared()) {
453 mCore->mActiveBuffers.erase(slot);
454 mCore->mFreeBuffers.push_back(slot);
455 }
456
457 listener = mCore->mConnectedProducerListener;
458 BQ_LOGV("releaseBuffer: releasing slot %d", slot);
459
Dan Stozad1c10362014-03-28 15:19:08 -0700460 mCore->mDequeueCondition.broadcast();
Pablo Ceballos9e314332016-01-12 13:49:19 -0800461 VALIDATE_CONSISTENCY();
Dan Stozad1c10362014-03-28 15:19:08 -0700462 } // Autolock scope
Dan Stoza289ade12014-02-28 11:17:17 -0800463
Dan Stozad1c10362014-03-28 15:19:08 -0700464 // Call back without lock held
465 if (listener != NULL) {
466 listener->onBufferReleased();
467 }
Dan Stoza289ade12014-02-28 11:17:17 -0800468
469 return NO_ERROR;
470}
471
472status_t BufferQueueConsumer::connect(
473 const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
474 ATRACE_CALL();
475
476 if (consumerListener == NULL) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700477 BQ_LOGE("connect: consumerListener may not be NULL");
Dan Stoza289ade12014-02-28 11:17:17 -0800478 return BAD_VALUE;
479 }
480
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700481 BQ_LOGV("connect: controlledByApp=%s",
Dan Stoza289ade12014-02-28 11:17:17 -0800482 controlledByApp ? "true" : "false");
483
484 Mutex::Autolock lock(mCore->mMutex);
485
486 if (mCore->mIsAbandoned) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700487 BQ_LOGE("connect: BufferQueue has been abandoned");
Dan Stoza289ade12014-02-28 11:17:17 -0800488 return NO_INIT;
489 }
490
491 mCore->mConsumerListener = consumerListener;
492 mCore->mConsumerControlledByApp = controlledByApp;
493
494 return NO_ERROR;
495}
496
497status_t BufferQueueConsumer::disconnect() {
498 ATRACE_CALL();
499
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700500 BQ_LOGV("disconnect");
Dan Stoza289ade12014-02-28 11:17:17 -0800501
502 Mutex::Autolock lock(mCore->mMutex);
503
504 if (mCore->mConsumerListener == NULL) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700505 BQ_LOGE("disconnect: no consumer is connected");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800506 return BAD_VALUE;
Dan Stoza289ade12014-02-28 11:17:17 -0800507 }
508
509 mCore->mIsAbandoned = true;
510 mCore->mConsumerListener = NULL;
511 mCore->mQueue.clear();
512 mCore->freeAllBuffersLocked();
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700513 mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
Dan Stoza289ade12014-02-28 11:17:17 -0800514 mCore->mDequeueCondition.broadcast();
515 return NO_ERROR;
516}
517
Dan Stozafebd4f42014-04-09 16:14:51 -0700518status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) {
Dan Stoza289ade12014-02-28 11:17:17 -0800519 ATRACE_CALL();
520
521 if (outSlotMask == NULL) {
522 BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL");
523 return BAD_VALUE;
524 }
525
526 Mutex::Autolock lock(mCore->mMutex);
527
528 if (mCore->mIsAbandoned) {
529 BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned");
530 return NO_INIT;
531 }
532
Dan Stozafebd4f42014-04-09 16:14:51 -0700533 uint64_t mask = 0;
Dan Stoza3e96f192014-03-03 10:16:19 -0800534 for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
Dan Stoza289ade12014-02-28 11:17:17 -0800535 if (!mSlots[s].mAcquireCalled) {
Dan Stozafebd4f42014-04-09 16:14:51 -0700536 mask |= (1ULL << s);
Dan Stoza289ade12014-02-28 11:17:17 -0800537 }
538 }
539
540 // Remove from the mask queued buffers for which acquire has been called,
541 // since the consumer will not receive their buffer addresses and so must
542 // retain their cached information
543 BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
544 while (current != mCore->mQueue.end()) {
545 if (current->mAcquireCalled) {
Dan Stozafebd4f42014-04-09 16:14:51 -0700546 mask &= ~(1ULL << current->mSlot);
Dan Stoza289ade12014-02-28 11:17:17 -0800547 }
548 ++current;
549 }
550
Dan Stozafebd4f42014-04-09 16:14:51 -0700551 BQ_LOGV("getReleasedBuffers: returning mask %#" PRIx64, mask);
Dan Stoza289ade12014-02-28 11:17:17 -0800552 *outSlotMask = mask;
553 return NO_ERROR;
554}
555
556status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width,
557 uint32_t height) {
558 ATRACE_CALL();
559
560 if (width == 0 || height == 0) {
561 BQ_LOGV("setDefaultBufferSize: dimensions cannot be 0 (width=%u "
562 "height=%u)", width, height);
563 return BAD_VALUE;
564 }
565
566 BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height);
567
568 Mutex::Autolock lock(mCore->mMutex);
569 mCore->mDefaultWidth = width;
570 mCore->mDefaultHeight = height;
571 return NO_ERROR;
572}
573
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700574status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) {
Dan Stoza289ade12014-02-28 11:17:17 -0800575 ATRACE_CALL();
Dan Stoza289ade12014-02-28 11:17:17 -0800576
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700577 if (bufferCount < 1 || bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
578 BQ_LOGE("setMaxBufferCount: invalid count %d", bufferCount);
579 return BAD_VALUE;
580 }
Dan Stoza289ade12014-02-28 11:17:17 -0800581
Pablo Ceballos38273792016-03-02 01:38:10 +0000582 Mutex::Autolock lock(mCore->mMutex);
Dan Stoza289ade12014-02-28 11:17:17 -0800583
Pablo Ceballos38273792016-03-02 01:38:10 +0000584 if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
585 BQ_LOGE("setMaxBufferCount: producer is already connected");
586 return INVALID_OPERATION;
Dan Stoza289ade12014-02-28 11:17:17 -0800587 }
588
Pablo Ceballos38273792016-03-02 01:38:10 +0000589 if (bufferCount < mCore->mMaxAcquiredBufferCount) {
590 BQ_LOGE("setMaxBufferCount: invalid buffer count (%d) less than"
591 "mMaxAcquiredBufferCount (%d)", bufferCount,
592 mCore->mMaxAcquiredBufferCount);
593 return BAD_VALUE;
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700594 }
Pablo Ceballos38273792016-03-02 01:38:10 +0000595
596 int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
597 mCore->mDequeueBufferCannotBlock, bufferCount) -
598 mCore->getMaxBufferCountLocked();
599 if (!mCore->adjustAvailableSlotsLocked(delta)) {
600 BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number of "
601 "available slots. Delta = %d", delta);
602 return BAD_VALUE;
603 }
604
605 mCore->mMaxBufferCount = bufferCount;
Dan Stoza289ade12014-02-28 11:17:17 -0800606 return NO_ERROR;
607}
608
609status_t BufferQueueConsumer::setMaxAcquiredBufferCount(
610 int maxAcquiredBuffers) {
611 ATRACE_CALL();
612
613 if (maxAcquiredBuffers < 1 ||
614 maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) {
615 BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d",
616 maxAcquiredBuffers);
617 return BAD_VALUE;
618 }
619
Pablo Ceballos38273792016-03-02 01:38:10 +0000620 sp<IConsumerListener> listener;
Pablo Ceballos72daab62015-12-07 16:38:43 -0800621 { // Autolock scope
622 Mutex::Autolock lock(mCore->mMutex);
623 mCore->waitWhileAllocatingLocked();
Dan Stoza289ade12014-02-28 11:17:17 -0800624
Pablo Ceballos72daab62015-12-07 16:38:43 -0800625 if (mCore->mIsAbandoned) {
626 BQ_LOGE("setMaxAcquiredBufferCount: consumer is abandoned");
627 return NO_INIT;
628 }
629
Pablo Ceballos245cc5b2016-04-19 11:33:00 -0700630 if (maxAcquiredBuffers == mCore->mMaxAcquiredBufferCount) {
631 return NO_ERROR;
632 }
633
Pablo Ceballos72daab62015-12-07 16:38:43 -0800634 // The new maxAcquiredBuffers count should not be violated by the number
635 // of currently acquired buffers
636 int acquiredCount = 0;
637 for (int slot : mCore->mActiveBuffers) {
638 if (mSlots[slot].mBufferState.isAcquired()) {
639 acquiredCount++;
640 }
641 }
642 if (acquiredCount > maxAcquiredBuffers) {
643 BQ_LOGE("setMaxAcquiredBufferCount: the requested maxAcquiredBuffer"
644 "count (%d) exceeds the current acquired buffer count (%d)",
645 maxAcquiredBuffers, acquiredCount);
646 return BAD_VALUE;
647 }
648
649 if ((maxAcquiredBuffers + mCore->mMaxDequeuedBufferCount +
650 (mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock ? 1 : 0))
651 > mCore->mMaxBufferCount) {
652 BQ_LOGE("setMaxAcquiredBufferCount: %d acquired buffers would "
653 "exceed the maxBufferCount (%d) (maxDequeued %d async %d)",
654 maxAcquiredBuffers, mCore->mMaxBufferCount,
655 mCore->mMaxDequeuedBufferCount, mCore->mAsyncMode ||
656 mCore->mDequeueBufferCannotBlock);
657 return BAD_VALUE;
658 }
659
660 int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount;
Pablo Ceballos38273792016-03-02 01:38:10 +0000661 if (!mCore->adjustAvailableSlotsLocked(delta)) {
Pablo Ceballos72daab62015-12-07 16:38:43 -0800662 return BAD_VALUE;
663 }
664
665 BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
666 mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
667 VALIDATE_CONSISTENCY();
668 if (delta < 0) {
Pablo Ceballos38273792016-03-02 01:38:10 +0000669 listener = mCore->mConsumerListener;
Pablo Ceballos72daab62015-12-07 16:38:43 -0800670 }
671 }
672 // Call back without lock held
Pablo Ceballos38273792016-03-02 01:38:10 +0000673 if (listener != NULL) {
674 listener->onBuffersReleased();
Dan Stoza289ade12014-02-28 11:17:17 -0800675 }
676
Dan Stoza289ade12014-02-28 11:17:17 -0800677 return NO_ERROR;
678}
679
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700680status_t BufferQueueConsumer::setConsumerName(const String8& name) {
Dan Stoza289ade12014-02-28 11:17:17 -0800681 ATRACE_CALL();
682 BQ_LOGV("setConsumerName: '%s'", name.string());
683 Mutex::Autolock lock(mCore->mMutex);
684 mCore->mConsumerName = name;
685 mConsumerName = name;
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700686 return NO_ERROR;
Dan Stoza289ade12014-02-28 11:17:17 -0800687}
688
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800689status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
Dan Stoza289ade12014-02-28 11:17:17 -0800690 ATRACE_CALL();
691 BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat);
692 Mutex::Autolock lock(mCore->mMutex);
693 mCore->mDefaultBufferFormat = defaultFormat;
694 return NO_ERROR;
695}
696
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800697status_t BufferQueueConsumer::setDefaultBufferDataSpace(
698 android_dataspace defaultDataSpace) {
699 ATRACE_CALL();
700 BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace);
701 Mutex::Autolock lock(mCore->mMutex);
702 mCore->mDefaultBufferDataSpace = defaultDataSpace;
703 return NO_ERROR;
704}
705
Dan Stoza289ade12014-02-28 11:17:17 -0800706status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) {
707 ATRACE_CALL();
708 BQ_LOGV("setConsumerUsageBits: %#x", usage);
709 Mutex::Autolock lock(mCore->mMutex);
710 mCore->mConsumerUsageBits = usage;
711 return NO_ERROR;
712}
713
Jiwen 'Steve' Cai20419132017-04-21 18:49:53 -0700714status_t BufferQueueConsumer::setConsumerIsProtected(bool isProtected) {
715 ATRACE_CALL();
716 BQ_LOGV("setConsumerIsProtected: %s", isProtected ? "true" : "false");
717 Mutex::Autolock lock(mCore->mMutex);
718 mCore->mConsumerIsProtected = isProtected;
719 return NO_ERROR;
720}
721
Dan Stoza289ade12014-02-28 11:17:17 -0800722status_t BufferQueueConsumer::setTransformHint(uint32_t hint) {
723 ATRACE_CALL();
724 BQ_LOGV("setTransformHint: %#x", hint);
725 Mutex::Autolock lock(mCore->mMutex);
726 mCore->mTransformHint = hint;
727 return NO_ERROR;
728}
729
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700730status_t BufferQueueConsumer::getSidebandStream(sp<NativeHandle>* outStream) const {
Fabien Sanglard2d8a2432016-11-08 15:31:32 -0800731 Mutex::Autolock lock(mCore->mMutex);
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700732 *outStream = mCore->mSidebandStream;
733 return NO_ERROR;
Jesse Hall399184a2014-03-03 15:42:54 -0800734}
735
Dan Stozae77c7662016-05-13 11:37:28 -0700736status_t BufferQueueConsumer::getOccupancyHistory(bool forceFlush,
737 std::vector<OccupancyTracker::Segment>* outHistory) {
738 Mutex::Autolock lock(mCore->mMutex);
739 *outHistory = mCore->mOccupancyTracker.getSegmentHistory(forceFlush);
740 return NO_ERROR;
741}
742
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -0700743status_t BufferQueueConsumer::discardFreeBuffers() {
744 Mutex::Autolock lock(mCore->mMutex);
745 mCore->discardFreeBuffersLocked();
746 return NO_ERROR;
747}
748
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700749status_t BufferQueueConsumer::dumpState(const String8& prefix, String8* outResult) const {
Pablo Ceballos88f69282016-02-11 18:01:49 -0800750 const IPCThreadState* ipc = IPCThreadState::self();
751 const pid_t pid = ipc->getCallingPid();
752 const uid_t uid = ipc->getCallingUid();
753 if ((uid != AID_SHELL)
754 && !PermissionCache::checkPermission(String16(
755 "android.permission.DUMP"), pid, uid)) {
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700756 outResult->appendFormat("Permission Denial: can't dump BufferQueueConsumer "
Pablo Ceballos88f69282016-02-11 18:01:49 -0800757 "from pid=%d, uid=%d\n", pid, uid);
Colin Cross6e7e2b42016-09-27 14:08:19 -0700758 android_errorWriteWithInfoLog(0x534e4554, "27046057",
759 static_cast<int32_t>(uid), NULL, 0);
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700760 return PERMISSION_DENIED;
Pablo Ceballos88f69282016-02-11 18:01:49 -0800761 }
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700762
763 mCore->dumpState(prefix, outResult);
764 return NO_ERROR;
Dan Stoza289ade12014-02-28 11:17:17 -0800765}
766
767} // namespace android