blob: 17cf677e092de22f9b291706b73a07e9c5de0c7f [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>
Yifan Hong65799c32017-07-26 10:47:14 -070018#include <pwd.h>
19#include <sys/types.h>
Mark Salyzyn8f515ce2014-06-09 14:32:04 -070020
Dan Stoza3e96f192014-03-03 10:16:19 -080021#define LOG_TAG "BufferQueueConsumer"
22#define ATRACE_TAG ATRACE_TAG_GRAPHICS
23//#define LOG_NDEBUG 0
24
Pablo Ceballos9e314332016-01-12 13:49:19 -080025#if DEBUG_ONLY_CODE
26#define VALIDATE_CONSISTENCY() do { mCore->validateConsistencyLocked(); } while (0)
27#else
28#define VALIDATE_CONSISTENCY()
29#endif
30
Dan Stoza289ade12014-02-28 11:17:17 -080031#include <gui/BufferItem.h>
32#include <gui/BufferQueueConsumer.h>
33#include <gui/BufferQueueCore.h>
34#include <gui/IConsumerListener.h>
Dan Stozad1c10362014-03-28 15:19:08 -070035#include <gui/IProducerListener.h>
Dan Stoza289ade12014-02-28 11:17:17 -080036
Pablo Ceballos88f69282016-02-11 18:01:49 -080037#include <binder/IPCThreadState.h>
38#include <binder/PermissionCache.h>
Pablo Ceballos88f69282016-02-11 18:01:49 -080039
Mathias Agopian6a3c05b2017-04-27 20:06:55 -070040#include <system/window.h>
41
Dan Stoza289ade12014-02-28 11:17:17 -080042namespace android {
43
44BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
45 mCore(core),
46 mSlots(core->mSlots),
47 mConsumerName() {}
48
49BufferQueueConsumer::~BufferQueueConsumer() {}
50
51status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
Dan Stozaa4650a52015-05-12 12:56:16 -070052 nsecs_t expectedPresent, uint64_t maxFrameNumber) {
Dan Stoza289ade12014-02-28 11:17:17 -080053 ATRACE_CALL();
Dan Stoza289ade12014-02-28 11:17:17 -080054
Lajos Molnar5f920c12015-07-13 16:04:24 -070055 int numDroppedBuffers = 0;
56 sp<IProducerListener> listener;
57 {
58 Mutex::Autolock lock(mCore->mMutex);
59
60 // Check that the consumer doesn't currently have the maximum number of
61 // buffers acquired. We allow the max buffer count to be exceeded by one
62 // buffer so that the consumer can successfully set up the newly acquired
63 // buffer before releasing the old one.
64 int numAcquiredBuffers = 0;
Pablo Ceballos23b4abe2016-01-08 12:15:22 -080065 for (int s : mCore->mActiveBuffers) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -070066 if (mSlots[s].mBufferState.isAcquired()) {
Lajos Molnar5f920c12015-07-13 16:04:24 -070067 ++numAcquiredBuffers;
68 }
Dan Stoza289ade12014-02-28 11:17:17 -080069 }
Lajos Molnar5f920c12015-07-13 16:04:24 -070070 if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
71 BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)",
72 numAcquiredBuffers, mCore->mMaxAcquiredBufferCount);
73 return INVALID_OPERATION;
74 }
Dan Stoza289ade12014-02-28 11:17:17 -080075
Pablo Ceballos3559fbf2016-03-17 15:50:23 -070076 bool sharedBufferAvailable = mCore->mSharedBufferMode &&
77 mCore->mAutoRefresh && mCore->mSharedBufferSlot !=
Pablo Ceballosccdfd602015-10-07 15:05:45 -070078 BufferQueueCore::INVALID_BUFFER_SLOT;
79
Lajos Molnar5f920c12015-07-13 16:04:24 -070080 // In asynchronous mode the list is guaranteed to be one buffer deep,
81 // while in synchronous mode we use the oldest buffer.
Pablo Ceballosccdfd602015-10-07 15:05:45 -070082 if (mCore->mQueue.empty() && !sharedBufferAvailable) {
Lajos Molnar5f920c12015-07-13 16:04:24 -070083 return NO_BUFFER_AVAILABLE;
84 }
Dan Stoza289ade12014-02-28 11:17:17 -080085
Lajos Molnar5f920c12015-07-13 16:04:24 -070086 BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
Dan Stoza289ade12014-02-28 11:17:17 -080087
Lajos Molnar5f920c12015-07-13 16:04:24 -070088 // If expectedPresent is specified, we may not want to return a buffer yet.
89 // If it's specified and there's more than one buffer queued, we may want
90 // to drop a buffer.
Pablo Ceballos3559fbf2016-03-17 15:50:23 -070091 // Skip this if we're in shared buffer mode and the queue is empty,
Pablo Ceballosccdfd602015-10-07 15:05:45 -070092 // since in that case we'll just return the shared buffer.
93 if (expectedPresent != 0 && !mCore->mQueue.empty()) {
Lajos Molnar5f920c12015-07-13 16:04:24 -070094 const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second
Dan Stoza289ade12014-02-28 11:17:17 -080095
Lajos Molnar5f920c12015-07-13 16:04:24 -070096 // The 'expectedPresent' argument indicates when the buffer is expected
97 // to be presented on-screen. If the buffer's desired present time is
98 // earlier (less) than expectedPresent -- meaning it will be displayed
99 // on time or possibly late if we show it as soon as possible -- we
100 // acquire and return it. If we don't want to display it until after the
101 // expectedPresent time, we return PRESENT_LATER without acquiring it.
102 //
103 // To be safe, we don't defer acquisition if expectedPresent is more
104 // than one second in the future beyond the desired present time
105 // (i.e., we'd be holding the buffer for a long time).
106 //
107 // NOTE: Code assumes monotonic time values from the system clock
108 // are positive.
Dan Stoza289ade12014-02-28 11:17:17 -0800109
Lajos Molnar5f920c12015-07-13 16:04:24 -0700110 // Start by checking to see if we can drop frames. We skip this check if
111 // the timestamps are being auto-generated by Surface. If the app isn't
112 // generating timestamps explicitly, it probably doesn't want frames to
113 // be discarded based on them.
114 while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) {
115 const BufferItem& bufferItem(mCore->mQueue[1]);
Dan Stozaa4650a52015-05-12 12:56:16 -0700116
Lajos Molnar5f920c12015-07-13 16:04:24 -0700117 // If dropping entry[0] would leave us with a buffer that the
118 // consumer is not yet ready for, don't drop it.
119 if (maxFrameNumber && bufferItem.mFrameNumber > maxFrameNumber) {
120 break;
121 }
122
123 // If entry[1] is timely, drop entry[0] (and repeat). We apply an
124 // additional criterion here: we only drop the earlier buffer if our
125 // desiredPresent falls within +/- 1 second of the expected present.
126 // Otherwise, bogus desiredPresent times (e.g., 0 or a small
127 // relative timestamp), which normally mean "ignore the timestamp
128 // and acquire immediately", would cause us to drop frames.
129 //
130 // We may want to add an additional criterion: don't drop the
131 // earlier buffer if entry[1]'s fence hasn't signaled yet.
132 nsecs_t desiredPresent = bufferItem.mTimestamp;
133 if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC ||
134 desiredPresent > expectedPresent) {
135 // This buffer is set to display in the near future, or
136 // desiredPresent is garbage. Either way we don't want to drop
137 // the previous buffer just to get this on the screen sooner.
138 BQ_LOGV("acquireBuffer: nodrop desire=%" PRId64 " expect=%"
139 PRId64 " (%" PRId64 ") now=%" PRId64,
140 desiredPresent, expectedPresent,
141 desiredPresent - expectedPresent,
142 systemTime(CLOCK_MONOTONIC));
143 break;
144 }
145
146 BQ_LOGV("acquireBuffer: drop desire=%" PRId64 " expect=%" PRId64
147 " size=%zu",
148 desiredPresent, expectedPresent, mCore->mQueue.size());
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800149
150 if (!front->mIsStale) {
Lajos Molnar5f920c12015-07-13 16:04:24 -0700151 // Front buffer is still in mSlots, so mark the slot as free
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700152 mSlots[front->mSlot].mBufferState.freeQueued();
153
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700154 // After leaving shared buffer mode, the shared buffer will
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700155 // still be around. Mark it as no longer shared if this
156 // operation causes it to be free.
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700157 if (!mCore->mSharedBufferMode &&
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700158 mSlots[front->mSlot].mBufferState.isFree()) {
159 mSlots[front->mSlot].mBufferState.mShared = false;
160 }
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800161
162 // Don't put the shared buffer on the free list
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700163 if (!mSlots[front->mSlot].mBufferState.isShared()) {
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800164 mCore->mActiveBuffers.erase(front->mSlot);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700165 mCore->mFreeBuffers.push_back(front->mSlot);
166 }
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800167
Lajos Molnar5f920c12015-07-13 16:04:24 -0700168 listener = mCore->mConnectedProducerListener;
169 ++numDroppedBuffers;
170 }
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800171
Lajos Molnar5f920c12015-07-13 16:04:24 -0700172 mCore->mQueue.erase(front);
173 front = mCore->mQueue.begin();
Dan Stozaecc50402015-04-28 14:42:06 -0700174 }
175
Lajos Molnar5f920c12015-07-13 16:04:24 -0700176 // See if the front buffer is ready to be acquired
177 nsecs_t desiredPresent = front->mTimestamp;
178 bool bufferIsDue = desiredPresent <= expectedPresent ||
179 desiredPresent > expectedPresent + MAX_REASONABLE_NSEC;
180 bool consumerIsReady = maxFrameNumber > 0 ?
181 front->mFrameNumber <= maxFrameNumber : true;
182 if (!bufferIsDue || !consumerIsReady) {
183 BQ_LOGV("acquireBuffer: defer desire=%" PRId64 " expect=%" PRId64
184 " (%" PRId64 ") now=%" PRId64 " frame=%" PRIu64
185 " consumer=%" PRIu64,
Mark Salyzyn8f515ce2014-06-09 14:32:04 -0700186 desiredPresent, expectedPresent,
Dan Stoza289ade12014-02-28 11:17:17 -0800187 desiredPresent - expectedPresent,
Lajos Molnar5f920c12015-07-13 16:04:24 -0700188 systemTime(CLOCK_MONOTONIC),
189 front->mFrameNumber, maxFrameNumber);
190 return PRESENT_LATER;
Dan Stoza289ade12014-02-28 11:17:17 -0800191 }
192
Lajos Molnar5f920c12015-07-13 16:04:24 -0700193 BQ_LOGV("acquireBuffer: accept desire=%" PRId64 " expect=%" PRId64 " "
194 "(%" PRId64 ") now=%" PRId64, desiredPresent, expectedPresent,
Dan Stoza289ade12014-02-28 11:17:17 -0800195 desiredPresent - expectedPresent,
Lajos Molnar5f920c12015-07-13 16:04:24 -0700196 systemTime(CLOCK_MONOTONIC));
Dan Stoza289ade12014-02-28 11:17:17 -0800197 }
198
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700199 int slot = BufferQueueCore::INVALID_BUFFER_SLOT;
200
201 if (sharedBufferAvailable && mCore->mQueue.empty()) {
202 // make sure the buffer has finished allocating before acquiring it
203 mCore->waitWhileAllocatingLocked();
204
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700205 slot = mCore->mSharedBufferSlot;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700206
207 // Recreate the BufferItem for the shared buffer from the data that
208 // was cached when it was last queued.
209 outBuffer->mGraphicBuffer = mSlots[slot].mGraphicBuffer;
210 outBuffer->mFence = Fence::NO_FENCE;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700211 outBuffer->mFenceTime = FenceTime::NO_FENCE;
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700212 outBuffer->mCrop = mCore->mSharedBufferCache.crop;
213 outBuffer->mTransform = mCore->mSharedBufferCache.transform &
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700214 ~static_cast<uint32_t>(
215 NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700216 outBuffer->mScalingMode = mCore->mSharedBufferCache.scalingMode;
217 outBuffer->mDataSpace = mCore->mSharedBufferCache.dataspace;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700218 outBuffer->mFrameNumber = mCore->mFrameCounter;
219 outBuffer->mSlot = slot;
220 outBuffer->mAcquireCalled = mSlots[slot].mAcquireCalled;
221 outBuffer->mTransformToDisplayInverse =
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700222 (mCore->mSharedBufferCache.transform &
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700223 NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
224 outBuffer->mSurfaceDamage = Region::INVALID_REGION;
Pablo Ceballos06312182015-10-07 16:32:12 -0700225 outBuffer->mQueuedBuffer = false;
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800226 outBuffer->mIsStale = false;
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700227 outBuffer->mAutoRefresh = mCore->mSharedBufferMode &&
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800228 mCore->mAutoRefresh;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700229 } else {
230 slot = front->mSlot;
231 *outBuffer = *front;
232 }
233
Lajos Molnar5f920c12015-07-13 16:04:24 -0700234 ATRACE_BUFFER_INDEX(slot);
235
236 BQ_LOGV("acquireBuffer: acquiring { slot=%d/%" PRIu64 " buffer=%p }",
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700237 slot, outBuffer->mFrameNumber, outBuffer->mGraphicBuffer->handle);
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800238
239 if (!outBuffer->mIsStale) {
Lajos Molnar5f920c12015-07-13 16:04:24 -0700240 mSlots[slot].mAcquireCalled = true;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700241 // Don't decrease the queue count if the BufferItem wasn't
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700242 // previously in the queue. This happens in shared buffer mode when
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700243 // the queue is empty and the BufferItem is created above.
244 if (mCore->mQueue.empty()) {
245 mSlots[slot].mBufferState.acquireNotInQueue();
246 } else {
247 mSlots[slot].mBufferState.acquire();
248 }
Lajos Molnar5f920c12015-07-13 16:04:24 -0700249 mSlots[slot].mFence = Fence::NO_FENCE;
250 }
251
252 // If the buffer has previously been acquired by the consumer, set
253 // mGraphicBuffer to NULL to avoid unnecessarily remapping this buffer
254 // on the consumer side
255 if (outBuffer->mAcquireCalled) {
256 outBuffer->mGraphicBuffer = NULL;
257 }
258
259 mCore->mQueue.erase(front);
260
261 // We might have freed a slot while dropping old buffers, or the producer
262 // may be blocked waiting for the number of buffers in the queue to
263 // decrease.
264 mCore->mDequeueCondition.broadcast();
265
Colin Cross6e7e2b42016-09-27 14:08:19 -0700266 ATRACE_INT(mCore->mConsumerName.string(),
267 static_cast<int32_t>(mCore->mQueue.size()));
Dan Stozae77c7662016-05-13 11:37:28 -0700268 mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size());
Lajos Molnar5f920c12015-07-13 16:04:24 -0700269
Pablo Ceballos9e314332016-01-12 13:49:19 -0800270 VALIDATE_CONSISTENCY();
Dan Stoza289ade12014-02-28 11:17:17 -0800271 }
272
Lajos Molnar5f920c12015-07-13 16:04:24 -0700273 if (listener != NULL) {
274 for (int i = 0; i < numDroppedBuffers; ++i) {
275 listener->onBufferReleased();
276 }
Dan Stoza289ade12014-02-28 11:17:17 -0800277 }
278
Dan Stoza289ade12014-02-28 11:17:17 -0800279 return NO_ERROR;
280}
281
Dan Stoza9f3053d2014-03-06 15:14:33 -0800282status_t BufferQueueConsumer::detachBuffer(int slot) {
283 ATRACE_CALL();
284 ATRACE_BUFFER_INDEX(slot);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700285 BQ_LOGV("detachBuffer: slot %d", slot);
Pablo Ceballos38273792016-03-02 01:38:10 +0000286 Mutex::Autolock lock(mCore->mMutex);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800287
Pablo Ceballos38273792016-03-02 01:38:10 +0000288 if (mCore->mIsAbandoned) {
289 BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
290 return NO_INIT;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800291 }
292
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700293 if (mCore->mSharedBufferMode || slot == mCore->mSharedBufferSlot) {
294 BQ_LOGE("detachBuffer: detachBuffer not allowed in shared buffer mode");
Pablo Ceballos38273792016-03-02 01:38:10 +0000295 return BAD_VALUE;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800296 }
297
Pablo Ceballos38273792016-03-02 01:38:10 +0000298 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
299 BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
300 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
301 return BAD_VALUE;
302 } else if (!mSlots[slot].mBufferState.isAcquired()) {
303 BQ_LOGE("detachBuffer: slot %d is not owned by the consumer "
304 "(state = %s)", slot, mSlots[slot].mBufferState.string());
305 return BAD_VALUE;
306 }
307
308 mSlots[slot].mBufferState.detachConsumer();
309 mCore->mActiveBuffers.erase(slot);
310 mCore->mFreeSlots.insert(slot);
311 mCore->clearBufferSlotLocked(slot);
312 mCore->mDequeueCondition.broadcast();
313 VALIDATE_CONSISTENCY();
Dan Stoza9f3053d2014-03-06 15:14:33 -0800314
315 return NO_ERROR;
316}
317
318status_t BufferQueueConsumer::attachBuffer(int* outSlot,
319 const sp<android::GraphicBuffer>& buffer) {
320 ATRACE_CALL();
321
322 if (outSlot == NULL) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700323 BQ_LOGE("attachBuffer: outSlot must not be NULL");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800324 return BAD_VALUE;
325 } else if (buffer == NULL) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700326 BQ_LOGE("attachBuffer: cannot attach NULL buffer");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800327 return BAD_VALUE;
328 }
329
330 Mutex::Autolock lock(mCore->mMutex);
331
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700332 if (mCore->mSharedBufferMode) {
333 BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700334 return BAD_VALUE;
335 }
336
Dan Stoza0de7ea72015-04-23 13:20:51 -0700337 // Make sure we don't have too many acquired buffers
Dan Stoza9f3053d2014-03-06 15:14:33 -0800338 int numAcquiredBuffers = 0;
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800339 for (int s : mCore->mActiveBuffers) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700340 if (mSlots[s].mBufferState.isAcquired()) {
Dan Stoza9f3053d2014-03-06 15:14:33 -0800341 ++numAcquiredBuffers;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800342 }
343 }
344
345 if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700346 BQ_LOGE("attachBuffer: max acquired buffer count reached: %d "
Dan Stoza9f3053d2014-03-06 15:14:33 -0800347 "(max %d)", numAcquiredBuffers,
348 mCore->mMaxAcquiredBufferCount);
349 return INVALID_OPERATION;
350 }
Dan Stoza0de7ea72015-04-23 13:20:51 -0700351
Dan Stoza812ed062015-06-02 15:45:22 -0700352 if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
353 BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
354 "[queue %u]", buffer->getGenerationNumber(),
355 mCore->mGenerationNumber);
356 return BAD_VALUE;
357 }
358
Dan Stoza0de7ea72015-04-23 13:20:51 -0700359 // Find a free slot to put the buffer into
360 int found = BufferQueueCore::INVALID_BUFFER_SLOT;
361 if (!mCore->mFreeSlots.empty()) {
362 auto slot = mCore->mFreeSlots.begin();
363 found = *slot;
364 mCore->mFreeSlots.erase(slot);
365 } else if (!mCore->mFreeBuffers.empty()) {
366 found = mCore->mFreeBuffers.front();
367 mCore->mFreeBuffers.remove(found);
368 }
Dan Stoza9f3053d2014-03-06 15:14:33 -0800369 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700370 BQ_LOGE("attachBuffer: could not find free buffer slot");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800371 return NO_MEMORY;
372 }
373
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800374 mCore->mActiveBuffers.insert(found);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800375 *outSlot = found;
376 ATRACE_BUFFER_INDEX(*outSlot);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700377 BQ_LOGV("attachBuffer: returning slot %d", *outSlot);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800378
379 mSlots[*outSlot].mGraphicBuffer = buffer;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700380 mSlots[*outSlot].mBufferState.attachConsumer();
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800381 mSlots[*outSlot].mNeedsReallocation = true;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800382 mSlots[*outSlot].mFence = Fence::NO_FENCE;
383 mSlots[*outSlot].mFrameNumber = 0;
384
Dan Stoza99b18b42014-03-28 15:34:33 -0700385 // mAcquireCalled tells BufferQueue that it doesn't need to send a valid
386 // GraphicBuffer pointer on the next acquireBuffer call, which decreases
387 // Binder traffic by not un/flattening the GraphicBuffer. However, it
388 // requires that the consumer maintain a cached copy of the slot <--> buffer
389 // mappings, which is why the consumer doesn't need the valid pointer on
390 // acquire.
391 //
392 // The StreamSplitter is one of the primary users of the attach/detach
393 // logic, and while it is running, all buffers it acquires are immediately
394 // detached, and all buffers it eventually releases are ones that were
395 // attached (as opposed to having been obtained from acquireBuffer), so it
396 // doesn't make sense to maintain the slot/buffer mappings, which would
397 // become invalid for every buffer during detach/attach. By setting this to
398 // false, the valid GraphicBuffer pointer will always be sent with acquire
399 // for attached buffers.
400 mSlots[*outSlot].mAcquireCalled = false;
401
Pablo Ceballos9e314332016-01-12 13:49:19 -0800402 VALIDATE_CONSISTENCY();
Dan Stoza0de7ea72015-04-23 13:20:51 -0700403
Dan Stoza9f3053d2014-03-06 15:14:33 -0800404 return NO_ERROR;
405}
406
Dan Stoza289ade12014-02-28 11:17:17 -0800407status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
408 const sp<Fence>& releaseFence, EGLDisplay eglDisplay,
409 EGLSyncKHR eglFence) {
410 ATRACE_CALL();
411 ATRACE_BUFFER_INDEX(slot);
412
Dan Stoza9f3053d2014-03-06 15:14:33 -0800413 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS ||
414 releaseFence == NULL) {
Dan Stoza52937cd2015-05-01 16:42:55 -0700415 BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot,
416 releaseFence.get());
Dan Stoza289ade12014-02-28 11:17:17 -0800417 return BAD_VALUE;
418 }
419
Dan Stozad1c10362014-03-28 15:19:08 -0700420 sp<IProducerListener> listener;
421 { // Autolock scope
422 Mutex::Autolock lock(mCore->mMutex);
Dan Stoza289ade12014-02-28 11:17:17 -0800423
Dan Stozad1c10362014-03-28 15:19:08 -0700424 // If the frame number has changed because the buffer has been reallocated,
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700425 // we can ignore this releaseBuffer for the old buffer.
426 // Ignore this for the shared buffer where the frame number can easily
427 // get out of sync due to the buffer being queued and acquired at the
428 // same time.
429 if (frameNumber != mSlots[slot].mFrameNumber &&
430 !mSlots[slot].mBufferState.isShared()) {
Dan Stozad1c10362014-03-28 15:19:08 -0700431 return STALE_BUFFER_SLOT;
432 }
Dan Stoza289ade12014-02-28 11:17:17 -0800433
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800434 if (!mSlots[slot].mBufferState.isAcquired()) {
Dan Stoza52937cd2015-05-01 16:42:55 -0700435 BQ_LOGE("releaseBuffer: attempted to release buffer slot %d "
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700436 "but its state was %s", slot,
437 mSlots[slot].mBufferState.string());
Dan Stoza9f3053d2014-03-06 15:14:33 -0800438 return BAD_VALUE;
Dan Stoza289ade12014-02-28 11:17:17 -0800439 }
Dan Stoza289ade12014-02-28 11:17:17 -0800440
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800441 mSlots[slot].mEglDisplay = eglDisplay;
442 mSlots[slot].mEglFence = eglFence;
443 mSlots[slot].mFence = releaseFence;
444 mSlots[slot].mBufferState.release();
445
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700446 // After leaving shared buffer mode, the shared buffer will
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800447 // still be around. Mark it as no longer shared if this
448 // operation causes it to be free.
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700449 if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800450 mSlots[slot].mBufferState.mShared = false;
451 }
452 // Don't put the shared buffer on the free list.
453 if (!mSlots[slot].mBufferState.isShared()) {
454 mCore->mActiveBuffers.erase(slot);
455 mCore->mFreeBuffers.push_back(slot);
456 }
457
458 listener = mCore->mConnectedProducerListener;
459 BQ_LOGV("releaseBuffer: releasing slot %d", slot);
460
Dan Stozad1c10362014-03-28 15:19:08 -0700461 mCore->mDequeueCondition.broadcast();
Pablo Ceballos9e314332016-01-12 13:49:19 -0800462 VALIDATE_CONSISTENCY();
Dan Stozad1c10362014-03-28 15:19:08 -0700463 } // Autolock scope
Dan Stoza289ade12014-02-28 11:17:17 -0800464
Dan Stozad1c10362014-03-28 15:19:08 -0700465 // Call back without lock held
466 if (listener != NULL) {
467 listener->onBufferReleased();
468 }
Dan Stoza289ade12014-02-28 11:17:17 -0800469
470 return NO_ERROR;
471}
472
473status_t BufferQueueConsumer::connect(
474 const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
475 ATRACE_CALL();
476
477 if (consumerListener == NULL) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700478 BQ_LOGE("connect: consumerListener may not be NULL");
Dan Stoza289ade12014-02-28 11:17:17 -0800479 return BAD_VALUE;
480 }
481
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700482 BQ_LOGV("connect: controlledByApp=%s",
Dan Stoza289ade12014-02-28 11:17:17 -0800483 controlledByApp ? "true" : "false");
484
485 Mutex::Autolock lock(mCore->mMutex);
486
487 if (mCore->mIsAbandoned) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700488 BQ_LOGE("connect: BufferQueue has been abandoned");
Dan Stoza289ade12014-02-28 11:17:17 -0800489 return NO_INIT;
490 }
491
492 mCore->mConsumerListener = consumerListener;
493 mCore->mConsumerControlledByApp = controlledByApp;
494
495 return NO_ERROR;
496}
497
498status_t BufferQueueConsumer::disconnect() {
499 ATRACE_CALL();
500
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700501 BQ_LOGV("disconnect");
Dan Stoza289ade12014-02-28 11:17:17 -0800502
503 Mutex::Autolock lock(mCore->mMutex);
504
505 if (mCore->mConsumerListener == NULL) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700506 BQ_LOGE("disconnect: no consumer is connected");
Dan Stoza9f3053d2014-03-06 15:14:33 -0800507 return BAD_VALUE;
Dan Stoza289ade12014-02-28 11:17:17 -0800508 }
509
510 mCore->mIsAbandoned = true;
511 mCore->mConsumerListener = NULL;
512 mCore->mQueue.clear();
513 mCore->freeAllBuffersLocked();
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700514 mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
Dan Stoza289ade12014-02-28 11:17:17 -0800515 mCore->mDequeueCondition.broadcast();
516 return NO_ERROR;
517}
518
Dan Stozafebd4f42014-04-09 16:14:51 -0700519status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) {
Dan Stoza289ade12014-02-28 11:17:17 -0800520 ATRACE_CALL();
521
522 if (outSlotMask == NULL) {
523 BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL");
524 return BAD_VALUE;
525 }
526
527 Mutex::Autolock lock(mCore->mMutex);
528
529 if (mCore->mIsAbandoned) {
530 BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned");
531 return NO_INIT;
532 }
533
Dan Stozafebd4f42014-04-09 16:14:51 -0700534 uint64_t mask = 0;
Dan Stoza3e96f192014-03-03 10:16:19 -0800535 for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
Dan Stoza289ade12014-02-28 11:17:17 -0800536 if (!mSlots[s].mAcquireCalled) {
Dan Stozafebd4f42014-04-09 16:14:51 -0700537 mask |= (1ULL << s);
Dan Stoza289ade12014-02-28 11:17:17 -0800538 }
539 }
540
541 // Remove from the mask queued buffers for which acquire has been called,
542 // since the consumer will not receive their buffer addresses and so must
543 // retain their cached information
544 BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
545 while (current != mCore->mQueue.end()) {
546 if (current->mAcquireCalled) {
Dan Stozafebd4f42014-04-09 16:14:51 -0700547 mask &= ~(1ULL << current->mSlot);
Dan Stoza289ade12014-02-28 11:17:17 -0800548 }
549 ++current;
550 }
551
Dan Stozafebd4f42014-04-09 16:14:51 -0700552 BQ_LOGV("getReleasedBuffers: returning mask %#" PRIx64, mask);
Dan Stoza289ade12014-02-28 11:17:17 -0800553 *outSlotMask = mask;
554 return NO_ERROR;
555}
556
557status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width,
558 uint32_t height) {
559 ATRACE_CALL();
560
561 if (width == 0 || height == 0) {
562 BQ_LOGV("setDefaultBufferSize: dimensions cannot be 0 (width=%u "
563 "height=%u)", width, height);
564 return BAD_VALUE;
565 }
566
567 BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height);
568
569 Mutex::Autolock lock(mCore->mMutex);
570 mCore->mDefaultWidth = width;
571 mCore->mDefaultHeight = height;
572 return NO_ERROR;
573}
574
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700575status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) {
Dan Stoza289ade12014-02-28 11:17:17 -0800576 ATRACE_CALL();
Dan Stoza289ade12014-02-28 11:17:17 -0800577
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700578 if (bufferCount < 1 || bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
579 BQ_LOGE("setMaxBufferCount: invalid count %d", bufferCount);
580 return BAD_VALUE;
581 }
Dan Stoza289ade12014-02-28 11:17:17 -0800582
Pablo Ceballos38273792016-03-02 01:38:10 +0000583 Mutex::Autolock lock(mCore->mMutex);
Dan Stoza289ade12014-02-28 11:17:17 -0800584
Pablo Ceballos38273792016-03-02 01:38:10 +0000585 if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
586 BQ_LOGE("setMaxBufferCount: producer is already connected");
587 return INVALID_OPERATION;
Dan Stoza289ade12014-02-28 11:17:17 -0800588 }
589
Pablo Ceballos38273792016-03-02 01:38:10 +0000590 if (bufferCount < mCore->mMaxAcquiredBufferCount) {
591 BQ_LOGE("setMaxBufferCount: invalid buffer count (%d) less than"
592 "mMaxAcquiredBufferCount (%d)", bufferCount,
593 mCore->mMaxAcquiredBufferCount);
594 return BAD_VALUE;
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700595 }
Pablo Ceballos38273792016-03-02 01:38:10 +0000596
597 int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
598 mCore->mDequeueBufferCannotBlock, bufferCount) -
599 mCore->getMaxBufferCountLocked();
600 if (!mCore->adjustAvailableSlotsLocked(delta)) {
601 BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number of "
602 "available slots. Delta = %d", delta);
603 return BAD_VALUE;
604 }
605
606 mCore->mMaxBufferCount = bufferCount;
Dan Stoza289ade12014-02-28 11:17:17 -0800607 return NO_ERROR;
608}
609
610status_t BufferQueueConsumer::setMaxAcquiredBufferCount(
611 int maxAcquiredBuffers) {
612 ATRACE_CALL();
613
614 if (maxAcquiredBuffers < 1 ||
615 maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) {
616 BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d",
617 maxAcquiredBuffers);
618 return BAD_VALUE;
619 }
620
Pablo Ceballos38273792016-03-02 01:38:10 +0000621 sp<IConsumerListener> listener;
Pablo Ceballos72daab62015-12-07 16:38:43 -0800622 { // Autolock scope
623 Mutex::Autolock lock(mCore->mMutex);
624 mCore->waitWhileAllocatingLocked();
Dan Stoza289ade12014-02-28 11:17:17 -0800625
Pablo Ceballos72daab62015-12-07 16:38:43 -0800626 if (mCore->mIsAbandoned) {
627 BQ_LOGE("setMaxAcquiredBufferCount: consumer is abandoned");
628 return NO_INIT;
629 }
630
Pablo Ceballos245cc5b2016-04-19 11:33:00 -0700631 if (maxAcquiredBuffers == mCore->mMaxAcquiredBufferCount) {
632 return NO_ERROR;
633 }
634
Pablo Ceballos72daab62015-12-07 16:38:43 -0800635 // The new maxAcquiredBuffers count should not be violated by the number
636 // of currently acquired buffers
637 int acquiredCount = 0;
638 for (int slot : mCore->mActiveBuffers) {
639 if (mSlots[slot].mBufferState.isAcquired()) {
640 acquiredCount++;
641 }
642 }
643 if (acquiredCount > maxAcquiredBuffers) {
644 BQ_LOGE("setMaxAcquiredBufferCount: the requested maxAcquiredBuffer"
645 "count (%d) exceeds the current acquired buffer count (%d)",
646 maxAcquiredBuffers, acquiredCount);
647 return BAD_VALUE;
648 }
649
650 if ((maxAcquiredBuffers + mCore->mMaxDequeuedBufferCount +
651 (mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock ? 1 : 0))
652 > mCore->mMaxBufferCount) {
653 BQ_LOGE("setMaxAcquiredBufferCount: %d acquired buffers would "
654 "exceed the maxBufferCount (%d) (maxDequeued %d async %d)",
655 maxAcquiredBuffers, mCore->mMaxBufferCount,
656 mCore->mMaxDequeuedBufferCount, mCore->mAsyncMode ||
657 mCore->mDequeueBufferCannotBlock);
658 return BAD_VALUE;
659 }
660
661 int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount;
Pablo Ceballos38273792016-03-02 01:38:10 +0000662 if (!mCore->adjustAvailableSlotsLocked(delta)) {
Pablo Ceballos72daab62015-12-07 16:38:43 -0800663 return BAD_VALUE;
664 }
665
666 BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
667 mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
668 VALIDATE_CONSISTENCY();
669 if (delta < 0) {
Pablo Ceballos38273792016-03-02 01:38:10 +0000670 listener = mCore->mConsumerListener;
Pablo Ceballos72daab62015-12-07 16:38:43 -0800671 }
672 }
673 // Call back without lock held
Pablo Ceballos38273792016-03-02 01:38:10 +0000674 if (listener != NULL) {
675 listener->onBuffersReleased();
Dan Stoza289ade12014-02-28 11:17:17 -0800676 }
677
Dan Stoza289ade12014-02-28 11:17:17 -0800678 return NO_ERROR;
679}
680
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700681status_t BufferQueueConsumer::setConsumerName(const String8& name) {
Dan Stoza289ade12014-02-28 11:17:17 -0800682 ATRACE_CALL();
683 BQ_LOGV("setConsumerName: '%s'", name.string());
684 Mutex::Autolock lock(mCore->mMutex);
685 mCore->mConsumerName = name;
686 mConsumerName = name;
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700687 return NO_ERROR;
Dan Stoza289ade12014-02-28 11:17:17 -0800688}
689
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800690status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
Dan Stoza289ade12014-02-28 11:17:17 -0800691 ATRACE_CALL();
692 BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat);
693 Mutex::Autolock lock(mCore->mMutex);
694 mCore->mDefaultBufferFormat = defaultFormat;
695 return NO_ERROR;
696}
697
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800698status_t BufferQueueConsumer::setDefaultBufferDataSpace(
699 android_dataspace defaultDataSpace) {
700 ATRACE_CALL();
701 BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace);
702 Mutex::Autolock lock(mCore->mMutex);
703 mCore->mDefaultBufferDataSpace = defaultDataSpace;
704 return NO_ERROR;
705}
706
Mathias Agopiancb496ac2017-05-22 14:21:00 -0700707status_t BufferQueueConsumer::setConsumerUsageBits(uint64_t usage) {
Dan Stoza289ade12014-02-28 11:17:17 -0800708 ATRACE_CALL();
Mathias Agopiancb496ac2017-05-22 14:21:00 -0700709 BQ_LOGV("setConsumerUsageBits: %#" PRIx64, usage);
Dan Stoza289ade12014-02-28 11:17:17 -0800710 Mutex::Autolock lock(mCore->mMutex);
711 mCore->mConsumerUsageBits = usage;
712 return NO_ERROR;
713}
714
Jiwen 'Steve' Cai20419132017-04-21 18:49:53 -0700715status_t BufferQueueConsumer::setConsumerIsProtected(bool isProtected) {
716 ATRACE_CALL();
717 BQ_LOGV("setConsumerIsProtected: %s", isProtected ? "true" : "false");
718 Mutex::Autolock lock(mCore->mMutex);
719 mCore->mConsumerIsProtected = isProtected;
720 return NO_ERROR;
721}
722
Dan Stoza289ade12014-02-28 11:17:17 -0800723status_t BufferQueueConsumer::setTransformHint(uint32_t hint) {
724 ATRACE_CALL();
725 BQ_LOGV("setTransformHint: %#x", hint);
726 Mutex::Autolock lock(mCore->mMutex);
727 mCore->mTransformHint = hint;
728 return NO_ERROR;
729}
730
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700731status_t BufferQueueConsumer::getSidebandStream(sp<NativeHandle>* outStream) const {
Fabien Sanglard2d8a2432016-11-08 15:31:32 -0800732 Mutex::Autolock lock(mCore->mMutex);
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700733 *outStream = mCore->mSidebandStream;
734 return NO_ERROR;
Jesse Hall399184a2014-03-03 15:42:54 -0800735}
736
Dan Stozae77c7662016-05-13 11:37:28 -0700737status_t BufferQueueConsumer::getOccupancyHistory(bool forceFlush,
738 std::vector<OccupancyTracker::Segment>* outHistory) {
739 Mutex::Autolock lock(mCore->mMutex);
740 *outHistory = mCore->mOccupancyTracker.getSegmentHistory(forceFlush);
741 return NO_ERROR;
742}
743
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -0700744status_t BufferQueueConsumer::discardFreeBuffers() {
745 Mutex::Autolock lock(mCore->mMutex);
746 mCore->discardFreeBuffersLocked();
747 return NO_ERROR;
748}
749
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700750status_t BufferQueueConsumer::dumpState(const String8& prefix, String8* outResult) const {
Yifan Hong65799c32017-07-26 10:47:14 -0700751 struct passwd* pwd = getpwnam("shell");
752 uid_t shellUid = pwd ? pwd->pw_uid : 0;
753 if (!shellUid) {
754 int savedErrno = errno;
755 BQ_LOGE("Cannot get AID_SHELL");
756 return savedErrno ? -savedErrno : UNKNOWN_ERROR;
757 }
758
Pablo Ceballos88f69282016-02-11 18:01:49 -0800759 const IPCThreadState* ipc = IPCThreadState::self();
760 const pid_t pid = ipc->getCallingPid();
761 const uid_t uid = ipc->getCallingUid();
Yifan Hong65799c32017-07-26 10:47:14 -0700762 if ((uid != shellUid) &&
763 !PermissionCache::checkPermission(String16("android.permission.DUMP"), pid, uid)) {
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700764 outResult->appendFormat("Permission Denial: can't dump BufferQueueConsumer "
Pablo Ceballos88f69282016-02-11 18:01:49 -0800765 "from pid=%d, uid=%d\n", pid, uid);
Colin Cross6e7e2b42016-09-27 14:08:19 -0700766 android_errorWriteWithInfoLog(0x534e4554, "27046057",
767 static_cast<int32_t>(uid), NULL, 0);
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700768 return PERMISSION_DENIED;
Pablo Ceballos88f69282016-02-11 18:01:49 -0800769 }
Dan Stoza0c9a1ed2017-04-06 15:10:21 -0700770
771 mCore->dumpState(prefix, outResult);
772 return NO_ERROR;
Dan Stoza289ade12014-02-28 11:17:17 -0800773}
774
775} // namespace android