1289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza/* 2289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * Copyright 2014 The Android Open Source Project 3289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * 4289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * Licensed under the Apache License, Version 2.0 (the "License"); 5289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * you may not use this file except in compliance with the License. 6289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * You may obtain a copy of the License at 7289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * 8289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * http://www.apache.org/licenses/LICENSE-2.0 9289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * 10289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * Unless required by applicable law or agreed to in writing, software 11289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * distributed under the License is distributed on an "AS IS" BASIS, 12289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * See the License for the specific language governing permissions and 14289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * limitations under the License. 15289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza */ 16289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 178f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn#include <inttypes.h> 188f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn 193e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza#define LOG_TAG "BufferQueueConsumer" 203e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza#define ATRACE_TAG ATRACE_TAG_GRAPHICS 213e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza//#define LOG_NDEBUG 0 223e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza 239e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos#if DEBUG_ONLY_CODE 249e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos#define VALIDATE_CONSISTENCY() do { mCore->validateConsistencyLocked(); } while (0) 259e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos#else 269e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos#define VALIDATE_CONSISTENCY() 279e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos#endif 289e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos 29289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/BufferItem.h> 30289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/BufferQueueConsumer.h> 31289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/BufferQueueCore.h> 32289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/IConsumerListener.h> 33d1c103655533321b5c74fbefff656838a8196153Dan Stoza#include <gui/IProducerListener.h> 34289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 3588f692852f99a7d0ae3990211d193b06ad209818Pablo Ceballos#include <binder/IPCThreadState.h> 3688f692852f99a7d0ae3990211d193b06ad209818Pablo Ceballos#include <binder/PermissionCache.h> 3788f692852f99a7d0ae3990211d193b06ad209818Pablo Ceballos#include <private/android_filesystem_config.h> 3888f692852f99a7d0ae3990211d193b06ad209818Pablo Ceballos 39289ade165e60b5f71734d30e535f16eb1f4313adDan Stozanamespace android { 40289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 41289ade165e60b5f71734d30e535f16eb1f4313adDan StozaBufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) : 42289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore(core), 43289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots(core->mSlots), 44289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mConsumerName() {} 45289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 46289ade165e60b5f71734d30e535f16eb1f4313adDan StozaBufferQueueConsumer::~BufferQueueConsumer() {} 47289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 48289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, 49a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza nsecs_t expectedPresent, uint64_t maxFrameNumber) { 50289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 515f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar 525f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar int numDroppedBuffers = 0; 535f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar sp<IProducerListener> listener; 545f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar { 555f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar Mutex::Autolock lock(mCore->mMutex); 565f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar 575f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // Check that the consumer doesn't currently have the maximum number of 585f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // buffers acquired. We allow the max buffer count to be exceeded by one 595f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // buffer so that the consumer can successfully set up the newly acquired 605f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // buffer before releasing the old one. 615f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar int numAcquiredBuffers = 0; 6223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos for (int s : mCore->mActiveBuffers) { 63ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mSlots[s].mBufferState.isAcquired()) { 645f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar ++numAcquiredBuffers; 655f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar } 665f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar } 675f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) { 685f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)", 695f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar numAcquiredBuffers, mCore->mMaxAcquiredBufferCount); 705f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar return INVALID_OPERATION; 71289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 72289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 733559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos bool sharedBufferAvailable = mCore->mSharedBufferMode && 743559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos mCore->mAutoRefresh && mCore->mSharedBufferSlot != 75ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BufferQueueCore::INVALID_BUFFER_SLOT; 76ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 775f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // In asynchronous mode the list is guaranteed to be one buffer deep, 785f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // while in synchronous mode we use the oldest buffer. 79ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mCore->mQueue.empty() && !sharedBufferAvailable) { 805f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar return NO_BUFFER_AVAILABLE; 815f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar } 82289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 835f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin()); 845f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar 855f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // If expectedPresent is specified, we may not want to return a buffer yet. 865f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // If it's specified and there's more than one buffer queued, we may want 875f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // to drop a buffer. 883559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos // Skip this if we're in shared buffer mode and the queue is empty, 89ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // since in that case we'll just return the shared buffer. 90ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (expectedPresent != 0 && !mCore->mQueue.empty()) { 915f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second 92ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza 935f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // The 'expectedPresent' argument indicates when the buffer is expected 945f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // to be presented on-screen. If the buffer's desired present time is 955f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // earlier (less) than expectedPresent -- meaning it will be displayed 965f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // on time or possibly late if we show it as soon as possible -- we 975f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // acquire and return it. If we don't want to display it until after the 985f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // expectedPresent time, we return PRESENT_LATER without acquiring it. 99289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // 1005f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // To be safe, we don't defer acquisition if expectedPresent is more 1015f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // than one second in the future beyond the desired present time 1025f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // (i.e., we'd be holding the buffer for a long time). 1035f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // 1045f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // NOTE: Code assumes monotonic time values from the system clock 1055f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // are positive. 1065f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar 1075f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // Start by checking to see if we can drop frames. We skip this check if 1085f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // the timestamps are being auto-generated by Surface. If the app isn't 1095f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // generating timestamps explicitly, it probably doesn't want frames to 1105f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // be discarded based on them. 1115f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) { 1125f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar const BufferItem& bufferItem(mCore->mQueue[1]); 1135f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar 1145f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // If dropping entry[0] would leave us with a buffer that the 1155f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // consumer is not yet ready for, don't drop it. 1165f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar if (maxFrameNumber && bufferItem.mFrameNumber > maxFrameNumber) { 1175f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar break; 1185f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar } 1195f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar 1205f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // If entry[1] is timely, drop entry[0] (and repeat). We apply an 1215f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // additional criterion here: we only drop the earlier buffer if our 1225f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // desiredPresent falls within +/- 1 second of the expected present. 1235f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // Otherwise, bogus desiredPresent times (e.g., 0 or a small 1245f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // relative timestamp), which normally mean "ignore the timestamp 1255f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // and acquire immediately", would cause us to drop frames. 1265f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // 1275f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // We may want to add an additional criterion: don't drop the 1285f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // earlier buffer if entry[1]'s fence hasn't signaled yet. 1295f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar nsecs_t desiredPresent = bufferItem.mTimestamp; 1305f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC || 1315f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar desiredPresent > expectedPresent) { 1325f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // This buffer is set to display in the near future, or 1335f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // desiredPresent is garbage. Either way we don't want to drop 1345f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // the previous buffer just to get this on the screen sooner. 1355f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar BQ_LOGV("acquireBuffer: nodrop desire=%" PRId64 " expect=%" 1365f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar PRId64 " (%" PRId64 ") now=%" PRId64, 1375f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar desiredPresent, expectedPresent, 1385f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar desiredPresent - expectedPresent, 1395f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar systemTime(CLOCK_MONOTONIC)); 1405f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar break; 1415f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar } 1425f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar 1435f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar BQ_LOGV("acquireBuffer: drop desire=%" PRId64 " expect=%" PRId64 1445f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar " size=%zu", 1455f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar desiredPresent, expectedPresent, mCore->mQueue.size()); 14623b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 14723b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos if (!front->mIsStale) { 1485f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // Front buffer is still in mSlots, so mark the slot as free 149ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[front->mSlot].mBufferState.freeQueued(); 150ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 1513559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos // After leaving shared buffer mode, the shared buffer will 152ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // still be around. Mark it as no longer shared if this 153ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // operation causes it to be free. 1543559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (!mCore->mSharedBufferMode && 155ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[front->mSlot].mBufferState.isFree()) { 156ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[front->mSlot].mBufferState.mShared = false; 157ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 15823b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 15923b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos // Don't put the shared buffer on the free list 160ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (!mSlots[front->mSlot].mBufferState.isShared()) { 16123b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mCore->mActiveBuffers.erase(front->mSlot); 162ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mFreeBuffers.push_back(front->mSlot); 163ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 16423b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 1655f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar listener = mCore->mConnectedProducerListener; 1665f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar ++numDroppedBuffers; 1675f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar } 16823b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 1695f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar mCore->mQueue.erase(front); 1705f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar front = mCore->mQueue.begin(); 171289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 172289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1735f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // See if the front buffer is ready to be acquired 1745f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar nsecs_t desiredPresent = front->mTimestamp; 1755f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar bool bufferIsDue = desiredPresent <= expectedPresent || 1765f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar desiredPresent > expectedPresent + MAX_REASONABLE_NSEC; 1775f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar bool consumerIsReady = maxFrameNumber > 0 ? 1785f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar front->mFrameNumber <= maxFrameNumber : true; 1795f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar if (!bufferIsDue || !consumerIsReady) { 1805f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar BQ_LOGV("acquireBuffer: defer desire=%" PRId64 " expect=%" PRId64 1815f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar " (%" PRId64 ") now=%" PRId64 " frame=%" PRIu64 1825f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar " consumer=%" PRIu64, 1835f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar desiredPresent, expectedPresent, 1845f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar desiredPresent - expectedPresent, 1855f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar systemTime(CLOCK_MONOTONIC), 1865f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar front->mFrameNumber, maxFrameNumber); 1875f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar return PRESENT_LATER; 188289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 189289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1905f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar BQ_LOGV("acquireBuffer: accept desire=%" PRId64 " expect=%" PRId64 " " 1915f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar "(%" PRId64 ") now=%" PRId64, desiredPresent, expectedPresent, 192289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza desiredPresent - expectedPresent, 1935f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar systemTime(CLOCK_MONOTONIC)); 194289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 195289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 196ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos int slot = BufferQueueCore::INVALID_BUFFER_SLOT; 197ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 198ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (sharedBufferAvailable && mCore->mQueue.empty()) { 199ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // make sure the buffer has finished allocating before acquiring it 200ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->waitWhileAllocatingLocked(); 201ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 2023559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos slot = mCore->mSharedBufferSlot; 203ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 204ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // Recreate the BufferItem for the shared buffer from the data that 205ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // was cached when it was last queued. 206ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos outBuffer->mGraphicBuffer = mSlots[slot].mGraphicBuffer; 207ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos outBuffer->mFence = Fence::NO_FENCE; 2083d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson outBuffer->mFenceTime = FenceTime::NO_FENCE; 2093559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos outBuffer->mCrop = mCore->mSharedBufferCache.crop; 2103559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos outBuffer->mTransform = mCore->mSharedBufferCache.transform & 211ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos ~static_cast<uint32_t>( 212ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY); 2133559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos outBuffer->mScalingMode = mCore->mSharedBufferCache.scalingMode; 2143559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos outBuffer->mDataSpace = mCore->mSharedBufferCache.dataspace; 215ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos outBuffer->mFrameNumber = mCore->mFrameCounter; 216ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos outBuffer->mSlot = slot; 217ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos outBuffer->mAcquireCalled = mSlots[slot].mAcquireCalled; 218ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos outBuffer->mTransformToDisplayInverse = 2193559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos (mCore->mSharedBufferCache.transform & 220ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0; 221ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos outBuffer->mSurfaceDamage = Region::INVALID_REGION; 222063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos outBuffer->mQueuedBuffer = false; 22323b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos outBuffer->mIsStale = false; 2243559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos outBuffer->mAutoRefresh = mCore->mSharedBufferMode && 225ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos mCore->mAutoRefresh; 226ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } else { 227ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos slot = front->mSlot; 228ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos *outBuffer = *front; 229ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 230ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 2315f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar ATRACE_BUFFER_INDEX(slot); 2325f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar 2335f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar BQ_LOGV("acquireBuffer: acquiring { slot=%d/%" PRIu64 " buffer=%p }", 234ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos slot, outBuffer->mFrameNumber, outBuffer->mGraphicBuffer->handle); 23523b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 23623b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos if (!outBuffer->mIsStale) { 2375f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar mSlots[slot].mAcquireCalled = true; 238ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // Don't decrease the queue count if the BufferItem wasn't 2393559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos // previously in the queue. This happens in shared buffer mode when 240ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // the queue is empty and the BufferItem is created above. 241ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mCore->mQueue.empty()) { 242ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[slot].mBufferState.acquireNotInQueue(); 243ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } else { 244ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[slot].mBufferState.acquire(); 245ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 2465f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar mSlots[slot].mFence = Fence::NO_FENCE; 2475f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar } 248289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 2495f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // If the buffer has previously been acquired by the consumer, set 2505f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // mGraphicBuffer to NULL to avoid unnecessarily remapping this buffer 2515f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // on the consumer side 2525f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar if (outBuffer->mAcquireCalled) { 2535f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar outBuffer->mGraphicBuffer = NULL; 2545f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar } 255289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 2565f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar mCore->mQueue.erase(front); 257289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 2585f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // We might have freed a slot while dropping old buffers, or the producer 2595f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // may be blocked waiting for the number of buffers in the queue to 2605f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar // decrease. 2615f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar mCore->mDequeueCondition.broadcast(); 262ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza 2636e7e2b44efa6427cc106b20cea76d9a80dadcac9Colin Cross ATRACE_INT(mCore->mConsumerName.string(), 2646e7e2b44efa6427cc106b20cea76d9a80dadcac9Colin Cross static_cast<int32_t>(mCore->mQueue.size())); 265e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size()); 266289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 2679e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos VALIDATE_CONSISTENCY(); 2685f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar } 269289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 2705f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar if (listener != NULL) { 2715f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar for (int i = 0; i < numDroppedBuffers; ++i) { 2725f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar listener->onBufferReleased(); 2735f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar } 2745f920c1a2cf12c0638c05fbddee8ff6c1193731cLajos Molnar } 2750de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 276289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 277289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 278289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 2799f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatus_t BufferQueueConsumer::detachBuffer(int slot) { 2809f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_CALL(); 2819f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_BUFFER_INDEX(slot); 282ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGV("detachBuffer: slot %d", slot); 2833827379b2e414b4c96793dd3555302638db02562Pablo Ceballos Mutex::Autolock lock(mCore->mMutex); 2849f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 2853827379b2e414b4c96793dd3555302638db02562Pablo Ceballos if (mCore->mIsAbandoned) { 2863827379b2e414b4c96793dd3555302638db02562Pablo Ceballos BQ_LOGE("detachBuffer: BufferQueue has been abandoned"); 2873827379b2e414b4c96793dd3555302638db02562Pablo Ceballos return NO_INIT; 288789a0c82cb370d6b82f401cc130af58c85802cbfPablo Ceballos } 289981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos 2903559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (mCore->mSharedBufferMode || slot == mCore->mSharedBufferSlot) { 2913559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos BQ_LOGE("detachBuffer: detachBuffer not allowed in shared buffer mode"); 2923827379b2e414b4c96793dd3555302638db02562Pablo Ceballos return BAD_VALUE; 29316c9c304a33af36faa352d32777bc48c50bf7b74Pablo Ceballos } 2943827379b2e414b4c96793dd3555302638db02562Pablo Ceballos 2953827379b2e414b4c96793dd3555302638db02562Pablo Ceballos if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 2963827379b2e414b4c96793dd3555302638db02562Pablo Ceballos BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", 2973827379b2e414b4c96793dd3555302638db02562Pablo Ceballos slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 2983827379b2e414b4c96793dd3555302638db02562Pablo Ceballos return BAD_VALUE; 2993827379b2e414b4c96793dd3555302638db02562Pablo Ceballos } else if (!mSlots[slot].mBufferState.isAcquired()) { 3003827379b2e414b4c96793dd3555302638db02562Pablo Ceballos BQ_LOGE("detachBuffer: slot %d is not owned by the consumer " 3013827379b2e414b4c96793dd3555302638db02562Pablo Ceballos "(state = %s)", slot, mSlots[slot].mBufferState.string()); 3023827379b2e414b4c96793dd3555302638db02562Pablo Ceballos return BAD_VALUE; 3039f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 3049f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 3053827379b2e414b4c96793dd3555302638db02562Pablo Ceballos mSlots[slot].mBufferState.detachConsumer(); 3063827379b2e414b4c96793dd3555302638db02562Pablo Ceballos mCore->mActiveBuffers.erase(slot); 3073827379b2e414b4c96793dd3555302638db02562Pablo Ceballos mCore->mFreeSlots.insert(slot); 3083827379b2e414b4c96793dd3555302638db02562Pablo Ceballos mCore->clearBufferSlotLocked(slot); 3093827379b2e414b4c96793dd3555302638db02562Pablo Ceballos mCore->mDequeueCondition.broadcast(); 3103827379b2e414b4c96793dd3555302638db02562Pablo Ceballos VALIDATE_CONSISTENCY(); 3119f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 3129f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_ERROR; 3139f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 3149f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 3159f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatus_t BufferQueueConsumer::attachBuffer(int* outSlot, 3169f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza const sp<android::GraphicBuffer>& buffer) { 3179f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_CALL(); 3189f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 3199f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (outSlot == NULL) { 320ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: outSlot must not be NULL"); 3219f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 3229f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } else if (buffer == NULL) { 323ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: cannot attach NULL buffer"); 3249f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 3259f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 3269f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 3279f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza Mutex::Autolock lock(mCore->mMutex); 3289f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 3293559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (mCore->mSharedBufferMode) { 3303559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode"); 331ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos return BAD_VALUE; 332ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 333ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 3340de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza // Make sure we don't have too many acquired buffers 3359f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int numAcquiredBuffers = 0; 33623b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos for (int s : mCore->mActiveBuffers) { 337ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mSlots[s].mBufferState.isAcquired()) { 3389f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ++numAcquiredBuffers; 3399f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 3409f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 3419f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 3429f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) { 343ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: max acquired buffer count reached: %d " 3449f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza "(max %d)", numAcquiredBuffers, 3459f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->mMaxAcquiredBufferCount); 3469f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return INVALID_OPERATION; 3479f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 3480de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 349812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza if (buffer->getGenerationNumber() != mCore->mGenerationNumber) { 350812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] " 351812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza "[queue %u]", buffer->getGenerationNumber(), 352812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza mCore->mGenerationNumber); 353812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza return BAD_VALUE; 354812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza } 355812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza 3560de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza // Find a free slot to put the buffer into 3570de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza int found = BufferQueueCore::INVALID_BUFFER_SLOT; 3580de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza if (!mCore->mFreeSlots.empty()) { 3590de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza auto slot = mCore->mFreeSlots.begin(); 3600de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza found = *slot; 3610de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza mCore->mFreeSlots.erase(slot); 3620de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza } else if (!mCore->mFreeBuffers.empty()) { 3630de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza found = mCore->mFreeBuffers.front(); 3640de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza mCore->mFreeBuffers.remove(found); 3650de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza } 3669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 367ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: could not find free buffer slot"); 3689f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_MEMORY; 3699f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 3709f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 37123b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mCore->mActiveBuffers.insert(found); 3729f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *outSlot = found; 3739f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_BUFFER_INDEX(*outSlot); 374ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGV("attachBuffer: returning slot %d", *outSlot); 3759f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 3769f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mGraphicBuffer = buffer; 377ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[*outSlot].mBufferState.attachConsumer(); 37823b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mSlots[*outSlot].mNeedsReallocation = true; 3799f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mFence = Fence::NO_FENCE; 3809f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mFrameNumber = 0; 3819f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 38299b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // mAcquireCalled tells BufferQueue that it doesn't need to send a valid 38399b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // GraphicBuffer pointer on the next acquireBuffer call, which decreases 38499b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // Binder traffic by not un/flattening the GraphicBuffer. However, it 38599b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // requires that the consumer maintain a cached copy of the slot <--> buffer 38699b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // mappings, which is why the consumer doesn't need the valid pointer on 38799b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // acquire. 38899b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // 38999b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // The StreamSplitter is one of the primary users of the attach/detach 39099b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // logic, and while it is running, all buffers it acquires are immediately 39199b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // detached, and all buffers it eventually releases are ones that were 39299b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // attached (as opposed to having been obtained from acquireBuffer), so it 39399b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // doesn't make sense to maintain the slot/buffer mappings, which would 39499b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // become invalid for every buffer during detach/attach. By setting this to 39599b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // false, the valid GraphicBuffer pointer will always be sent with acquire 39699b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza // for attached buffers. 39799b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza mSlots[*outSlot].mAcquireCalled = false; 39899b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza 3999e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos VALIDATE_CONSISTENCY(); 4000de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 4019f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_ERROR; 4029f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 4039f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 404289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, 405289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const sp<Fence>& releaseFence, EGLDisplay eglDisplay, 406289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLSyncKHR eglFence) { 407289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 408289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_BUFFER_INDEX(slot); 409289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 4109f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS || 4119f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza releaseFence == NULL) { 41252937cd9a543fe66696c38ae50ec141aa70ec1e4Dan Stoza BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot, 41352937cd9a543fe66696c38ae50ec141aa70ec1e4Dan Stoza releaseFence.get()); 414289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 415289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 416289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 417d1c103655533321b5c74fbefff656838a8196153Dan Stoza sp<IProducerListener> listener; 418d1c103655533321b5c74fbefff656838a8196153Dan Stoza { // Autolock scope 419d1c103655533321b5c74fbefff656838a8196153Dan Stoza Mutex::Autolock lock(mCore->mMutex); 420289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 421d1c103655533321b5c74fbefff656838a8196153Dan Stoza // If the frame number has changed because the buffer has been reallocated, 422ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // we can ignore this releaseBuffer for the old buffer. 423ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // Ignore this for the shared buffer where the frame number can easily 424ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // get out of sync due to the buffer being queued and acquired at the 425ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // same time. 426ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (frameNumber != mSlots[slot].mFrameNumber && 427ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos !mSlots[slot].mBufferState.isShared()) { 428d1c103655533321b5c74fbefff656838a8196153Dan Stoza return STALE_BUFFER_SLOT; 429d1c103655533321b5c74fbefff656838a8196153Dan Stoza } 430289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 43123b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos if (!mSlots[slot].mBufferState.isAcquired()) { 43252937cd9a543fe66696c38ae50ec141aa70ec1e4Dan Stoza BQ_LOGE("releaseBuffer: attempted to release buffer slot %d " 433ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos "but its state was %s", slot, 434ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[slot].mBufferState.string()); 4359f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 436289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 437289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 43823b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mSlots[slot].mEglDisplay = eglDisplay; 43923b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mSlots[slot].mEglFence = eglFence; 44023b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mSlots[slot].mFence = releaseFence; 44123b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mSlots[slot].mBufferState.release(); 44223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 4433559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos // After leaving shared buffer mode, the shared buffer will 44423b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos // still be around. Mark it as no longer shared if this 44523b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos // operation causes it to be free. 4463559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) { 44723b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mSlots[slot].mBufferState.mShared = false; 44823b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos } 44923b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos // Don't put the shared buffer on the free list. 45023b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos if (!mSlots[slot].mBufferState.isShared()) { 45123b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mCore->mActiveBuffers.erase(slot); 45223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mCore->mFreeBuffers.push_back(slot); 45323b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos } 45423b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 45523b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos listener = mCore->mConnectedProducerListener; 45623b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos BQ_LOGV("releaseBuffer: releasing slot %d", slot); 45723b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 458d1c103655533321b5c74fbefff656838a8196153Dan Stoza mCore->mDequeueCondition.broadcast(); 4599e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos VALIDATE_CONSISTENCY(); 460d1c103655533321b5c74fbefff656838a8196153Dan Stoza } // Autolock scope 461289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 462d1c103655533321b5c74fbefff656838a8196153Dan Stoza // Call back without lock held 463d1c103655533321b5c74fbefff656838a8196153Dan Stoza if (listener != NULL) { 464d1c103655533321b5c74fbefff656838a8196153Dan Stoza listener->onBufferReleased(); 465d1c103655533321b5c74fbefff656838a8196153Dan Stoza } 466289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 467289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 468289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 469289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 470289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueConsumer::connect( 471289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const sp<IConsumerListener>& consumerListener, bool controlledByApp) { 472289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 473289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 474289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (consumerListener == NULL) { 475ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("connect: consumerListener may not be NULL"); 476289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 477289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 478289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 479ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGV("connect: controlledByApp=%s", 480289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza controlledByApp ? "true" : "false"); 481289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 482289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 483289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 484289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 485ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("connect: BufferQueue has been abandoned"); 486289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 487289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 488289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 489289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConsumerListener = consumerListener; 490289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConsumerControlledByApp = controlledByApp; 491289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 492289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 493289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 494289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 495289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueConsumer::disconnect() { 496289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 497289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 498ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGV("disconnect"); 499289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 500289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 501289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 502289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mConsumerListener == NULL) { 503ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("disconnect: no consumer is connected"); 5049f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 505289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 506289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 507289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mIsAbandoned = true; 508289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConsumerListener = NULL; 509289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mQueue.clear(); 510289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->freeAllBuffersLocked(); 5113559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT; 512289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 513289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 514289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 515289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 516febd4f4f462444bfcb3f0618d07ac77e3fc1f6adDan Stozastatus_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) { 517289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 518289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 519289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (outSlotMask == NULL) { 520289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL"); 521289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 522289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 523289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 524289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 525289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 526289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 527289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned"); 528289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 529289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 530289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 531febd4f4f462444bfcb3f0618d07ac77e3fc1f6adDan Stoza uint64_t mask = 0; 5323e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 533289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (!mSlots[s].mAcquireCalled) { 534febd4f4f462444bfcb3f0618d07ac77e3fc1f6adDan Stoza mask |= (1ULL << s); 535289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 536289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 537289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 538289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Remove from the mask queued buffers for which acquire has been called, 539289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // since the consumer will not receive their buffer addresses and so must 540289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // retain their cached information 541289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin()); 542289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza while (current != mCore->mQueue.end()) { 543289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (current->mAcquireCalled) { 544febd4f4f462444bfcb3f0618d07ac77e3fc1f6adDan Stoza mask &= ~(1ULL << current->mSlot); 545289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 546289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ++current; 547289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 548289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 549febd4f4f462444bfcb3f0618d07ac77e3fc1f6adDan Stoza BQ_LOGV("getReleasedBuffers: returning mask %#" PRIx64, mask); 550289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outSlotMask = mask; 551289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 552289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 553289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 554289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width, 555289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza uint32_t height) { 556289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 557289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 558289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (width == 0 || height == 0) { 559289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("setDefaultBufferSize: dimensions cannot be 0 (width=%u " 560289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "height=%u)", width, height); 561289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 562289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 563289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 564289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height); 565289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 566289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 567289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDefaultWidth = width; 568289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDefaultHeight = height; 569289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 570289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 571289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 57219e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballosstatus_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) { 573289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 574289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 57519e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos if (bufferCount < 1 || bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) { 57619e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos BQ_LOGE("setMaxBufferCount: invalid count %d", bufferCount); 57719e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos return BAD_VALUE; 57819e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos } 579289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 5803827379b2e414b4c96793dd3555302638db02562Pablo Ceballos Mutex::Autolock lock(mCore->mMutex); 58119e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos 5823827379b2e414b4c96793dd3555302638db02562Pablo Ceballos if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 5833827379b2e414b4c96793dd3555302638db02562Pablo Ceballos BQ_LOGE("setMaxBufferCount: producer is already connected"); 5843827379b2e414b4c96793dd3555302638db02562Pablo Ceballos return INVALID_OPERATION; 5853827379b2e414b4c96793dd3555302638db02562Pablo Ceballos } 58623b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 5873827379b2e414b4c96793dd3555302638db02562Pablo Ceballos if (bufferCount < mCore->mMaxAcquiredBufferCount) { 5883827379b2e414b4c96793dd3555302638db02562Pablo Ceballos BQ_LOGE("setMaxBufferCount: invalid buffer count (%d) less than" 5893827379b2e414b4c96793dd3555302638db02562Pablo Ceballos "mMaxAcquiredBufferCount (%d)", bufferCount, 5903827379b2e414b4c96793dd3555302638db02562Pablo Ceballos mCore->mMaxAcquiredBufferCount); 5913827379b2e414b4c96793dd3555302638db02562Pablo Ceballos return BAD_VALUE; 592789a0c82cb370d6b82f401cc130af58c85802cbfPablo Ceballos } 593981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos 5943827379b2e414b4c96793dd3555302638db02562Pablo Ceballos int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, 5953827379b2e414b4c96793dd3555302638db02562Pablo Ceballos mCore->mDequeueBufferCannotBlock, bufferCount) - 5963827379b2e414b4c96793dd3555302638db02562Pablo Ceballos mCore->getMaxBufferCountLocked(); 5973827379b2e414b4c96793dd3555302638db02562Pablo Ceballos if (!mCore->adjustAvailableSlotsLocked(delta)) { 5983827379b2e414b4c96793dd3555302638db02562Pablo Ceballos BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number of " 5993827379b2e414b4c96793dd3555302638db02562Pablo Ceballos "available slots. Delta = %d", delta); 6003827379b2e414b4c96793dd3555302638db02562Pablo Ceballos return BAD_VALUE; 60116c9c304a33af36faa352d32777bc48c50bf7b74Pablo Ceballos } 6023827379b2e414b4c96793dd3555302638db02562Pablo Ceballos 6033827379b2e414b4c96793dd3555302638db02562Pablo Ceballos mCore->mMaxBufferCount = bufferCount; 604289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 605289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 606289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 607289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueConsumer::setMaxAcquiredBufferCount( 608289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int maxAcquiredBuffers) { 609289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 610289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 611289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (maxAcquiredBuffers < 1 || 612289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) { 613289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d", 614289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza maxAcquiredBuffers); 615289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 616289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 617289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 6183827379b2e414b4c96793dd3555302638db02562Pablo Ceballos sp<IConsumerListener> listener; 61972daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos { // Autolock scope 62072daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos Mutex::Autolock lock(mCore->mMutex); 62172daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos mCore->waitWhileAllocatingLocked(); 622289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 62372daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos if (mCore->mIsAbandoned) { 62472daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos BQ_LOGE("setMaxAcquiredBufferCount: consumer is abandoned"); 62572daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos return NO_INIT; 62672daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos } 627289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 628245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos if (maxAcquiredBuffers == mCore->mMaxAcquiredBufferCount) { 629245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos return NO_ERROR; 630245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos } 631245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos 63272daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos // The new maxAcquiredBuffers count should not be violated by the number 63372daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos // of currently acquired buffers 63472daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos int acquiredCount = 0; 63572daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos for (int slot : mCore->mActiveBuffers) { 63672daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos if (mSlots[slot].mBufferState.isAcquired()) { 63772daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos acquiredCount++; 63872daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos } 63972daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos } 64072daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos if (acquiredCount > maxAcquiredBuffers) { 64172daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos BQ_LOGE("setMaxAcquiredBufferCount: the requested maxAcquiredBuffer" 64272daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos "count (%d) exceeds the current acquired buffer count (%d)", 64372daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos maxAcquiredBuffers, acquiredCount); 64472daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos return BAD_VALUE; 64572daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos } 64619e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos 64772daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos if ((maxAcquiredBuffers + mCore->mMaxDequeuedBufferCount + 64872daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos (mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock ? 1 : 0)) 64972daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos > mCore->mMaxBufferCount) { 65072daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos BQ_LOGE("setMaxAcquiredBufferCount: %d acquired buffers would " 65172daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos "exceed the maxBufferCount (%d) (maxDequeued %d async %d)", 65272daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos maxAcquiredBuffers, mCore->mMaxBufferCount, 65372daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos mCore->mMaxDequeuedBufferCount, mCore->mAsyncMode || 65472daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos mCore->mDequeueBufferCannotBlock); 65572daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos return BAD_VALUE; 65672daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos } 65772daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos 65872daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount; 6593827379b2e414b4c96793dd3555302638db02562Pablo Ceballos if (!mCore->adjustAvailableSlotsLocked(delta)) { 66072daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos return BAD_VALUE; 66172daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos } 66272daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos 66372daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers); 66472daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers; 66572daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos VALIDATE_CONSISTENCY(); 66672daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos if (delta < 0) { 6673827379b2e414b4c96793dd3555302638db02562Pablo Ceballos listener = mCore->mConsumerListener; 66872daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos } 66972daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos } 67072daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos // Call back without lock held 6713827379b2e414b4c96793dd3555302638db02562Pablo Ceballos if (listener != NULL) { 6723827379b2e414b4c96793dd3555302638db02562Pablo Ceballos listener->onBuffersReleased(); 67323b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos } 67423b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 675289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 676289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 677289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 6780c9a1ed91f8e19887ac43eff5af16e59878c8226Dan Stozastatus_t BufferQueueConsumer::setConsumerName(const String8& name) { 679289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 680289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("setConsumerName: '%s'", name.string()); 681289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 682289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConsumerName = name; 683289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mConsumerName = name; 6840c9a1ed91f8e19887ac43eff5af16e59878c8226Dan Stoza return NO_ERROR; 685289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 686289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 6873be1c6b60a188dc10025e2ce156c11fac050625dDan Stozastatus_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) { 688289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 689289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat); 690289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 691289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDefaultBufferFormat = defaultFormat; 692289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 693289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 694289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 69582c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvalastatus_t BufferQueueConsumer::setDefaultBufferDataSpace( 69682c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala android_dataspace defaultDataSpace) { 69782c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala ATRACE_CALL(); 69882c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace); 69982c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala Mutex::Autolock lock(mCore->mMutex); 70082c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala mCore->mDefaultBufferDataSpace = defaultDataSpace; 70182c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala return NO_ERROR; 70282c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala} 70382c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala 704289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) { 705289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 706289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("setConsumerUsageBits: %#x", usage); 707289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 708289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConsumerUsageBits = usage; 709289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 710289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 711289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 7122041913a05b79b96c5c084f30bb8944049a976c8Jiwen 'Steve' Caistatus_t BufferQueueConsumer::setConsumerIsProtected(bool isProtected) { 7132041913a05b79b96c5c084f30bb8944049a976c8Jiwen 'Steve' Cai ATRACE_CALL(); 7142041913a05b79b96c5c084f30bb8944049a976c8Jiwen 'Steve' Cai BQ_LOGV("setConsumerIsProtected: %s", isProtected ? "true" : "false"); 7152041913a05b79b96c5c084f30bb8944049a976c8Jiwen 'Steve' Cai Mutex::Autolock lock(mCore->mMutex); 7162041913a05b79b96c5c084f30bb8944049a976c8Jiwen 'Steve' Cai mCore->mConsumerIsProtected = isProtected; 7172041913a05b79b96c5c084f30bb8944049a976c8Jiwen 'Steve' Cai return NO_ERROR; 7182041913a05b79b96c5c084f30bb8944049a976c8Jiwen 'Steve' Cai} 7192041913a05b79b96c5c084f30bb8944049a976c8Jiwen 'Steve' Cai 720289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueConsumer::setTransformHint(uint32_t hint) { 721289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 722289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("setTransformHint: %#x", hint); 723289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 724289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mTransformHint = hint; 725289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 726289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 727289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 7280c9a1ed91f8e19887ac43eff5af16e59878c8226Dan Stozastatus_t BufferQueueConsumer::getSidebandStream(sp<NativeHandle>* outStream) const { 7292d8a2432e04234d9edbb3b099f9bbbaa36ad4843Fabien Sanglard Mutex::Autolock lock(mCore->mMutex); 7300c9a1ed91f8e19887ac43eff5af16e59878c8226Dan Stoza *outStream = mCore->mSidebandStream; 7310c9a1ed91f8e19887ac43eff5af16e59878c8226Dan Stoza return NO_ERROR; 732399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall} 733399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall 734e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozastatus_t BufferQueueConsumer::getOccupancyHistory(bool forceFlush, 735e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::vector<OccupancyTracker::Segment>* outHistory) { 736e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza Mutex::Autolock lock(mCore->mMutex); 737e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza *outHistory = mCore->mOccupancyTracker.getSegmentHistory(forceFlush); 738e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza return NO_ERROR; 739e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 740e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 741bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvalastatus_t BufferQueueConsumer::discardFreeBuffers() { 742bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala Mutex::Autolock lock(mCore->mMutex); 743bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala mCore->discardFreeBuffersLocked(); 744bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala return NO_ERROR; 745bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala} 746bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala 7470c9a1ed91f8e19887ac43eff5af16e59878c8226Dan Stozastatus_t BufferQueueConsumer::dumpState(const String8& prefix, String8* outResult) const { 74888f692852f99a7d0ae3990211d193b06ad209818Pablo Ceballos const IPCThreadState* ipc = IPCThreadState::self(); 74988f692852f99a7d0ae3990211d193b06ad209818Pablo Ceballos const pid_t pid = ipc->getCallingPid(); 75088f692852f99a7d0ae3990211d193b06ad209818Pablo Ceballos const uid_t uid = ipc->getCallingUid(); 75188f692852f99a7d0ae3990211d193b06ad209818Pablo Ceballos if ((uid != AID_SHELL) 75288f692852f99a7d0ae3990211d193b06ad209818Pablo Ceballos && !PermissionCache::checkPermission(String16( 75388f692852f99a7d0ae3990211d193b06ad209818Pablo Ceballos "android.permission.DUMP"), pid, uid)) { 7540c9a1ed91f8e19887ac43eff5af16e59878c8226Dan Stoza outResult->appendFormat("Permission Denial: can't dump BufferQueueConsumer " 75588f692852f99a7d0ae3990211d193b06ad209818Pablo Ceballos "from pid=%d, uid=%d\n", pid, uid); 7566e7e2b44efa6427cc106b20cea76d9a80dadcac9Colin Cross android_errorWriteWithInfoLog(0x534e4554, "27046057", 7576e7e2b44efa6427cc106b20cea76d9a80dadcac9Colin Cross static_cast<int32_t>(uid), NULL, 0); 7580c9a1ed91f8e19887ac43eff5af16e59878c8226Dan Stoza return PERMISSION_DENIED; 75988f692852f99a7d0ae3990211d193b06ad209818Pablo Ceballos } 7600c9a1ed91f8e19887ac43eff5af16e59878c8226Dan Stoza 7610c9a1ed91f8e19887ac43eff5af16e59878c8226Dan Stoza mCore->dumpState(prefix, outResult); 7620c9a1ed91f8e19887ac43eff5af16e59878c8226Dan Stoza return NO_ERROR; 763289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 764289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 765289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} // namespace android 766