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 "BufferQueueProducer" 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#define EGL_EGLEXT_PROTOTYPES 30289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 31289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/BufferItem.h> 32289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/BufferQueueCore.h> 33289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/BufferQueueProducer.h> 341a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck#include <gui/GLConsumer.h> 35289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/IConsumerListener.h> 36289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/IGraphicBufferAlloc.h> 37f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza#include <gui/IProducerListener.h> 38289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 39289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <utils/Log.h> 40289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <utils/Trace.h> 41289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 42289ade165e60b5f71734d30e535f16eb1f4313adDan Stozanamespace android { 43289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 44289ade165e60b5f71734d30e535f16eb1f4313adDan StozaBufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) : 45289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore(core), 46289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots(core->mSlots), 471681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk mConsumerName(), 4899a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner mStickyTransform(0), 498dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mLastQueueBufferFence(Fence::NO_FENCE), 508dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mCallbackMutex(), 518dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mNextCallbackTicket(0), 528dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mCurrentCallbackTicket(0), 53127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza mCallbackCondition(), 54127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza mDequeueTimeout(-1) {} 55289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 56289ade165e60b5f71734d30e535f16eb1f4313adDan StozaBufferQueueProducer::~BufferQueueProducer() {} 57289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 58289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 59289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 60289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("requestBuffer: slot %d", slot); 61289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 62289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 63289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 64289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("requestBuffer: BufferQueue has been abandoned"); 65289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 66289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 67289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 68583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 69583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos BQ_LOGE("requestBuffer: BufferQueue has no connected producer"); 70583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 71583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 72583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 733e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 74289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)", 753e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 76289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 77ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } else if (!mSlots[slot].mBufferState.isDequeued()) { 78289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("requestBuffer: slot %d is not owned by the producer " 79ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos "(state = %s)", slot, mSlots[slot].mBufferState.string()); 80289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 81289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 82289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 83289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mRequestBufferCalled = true; 84289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *buf = mSlots[slot].mGraphicBuffer; 85289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 86289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 87289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 88fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballosstatus_t BufferQueueProducer::setMaxDequeuedBufferCount( 89fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos int maxDequeuedBuffers) { 90fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos ATRACE_CALL(); 91fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos BQ_LOGV("setMaxDequeuedBufferCount: maxDequeuedBuffers = %d", 92fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos maxDequeuedBuffers); 93fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 94981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos sp<IConsumerListener> listener; 95fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos { // Autolock scope 96fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos Mutex::Autolock lock(mCore->mMutex); 97fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos mCore->waitWhileAllocatingLocked(); 98fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 99fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if (mCore->mIsAbandoned) { 100fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue has been " 101fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos "abandoned"); 102fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return NO_INIT; 103fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 104fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 105245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos if (maxDequeuedBuffers == mCore->mMaxDequeuedBufferCount) { 106245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos return NO_ERROR; 107245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos } 108245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos 10972daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos // The new maxDequeuedBuffer count should not be violated by the number 11072daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos // of currently dequeued buffers 11172daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos int dequeuedCount = 0; 11223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos for (int s : mCore->mActiveBuffers) { 113ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mSlots[s].mBufferState.isDequeued()) { 11472daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos dequeuedCount++; 115fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 116fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 11772daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos if (dequeuedCount > maxDequeuedBuffers) { 11872daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos BQ_LOGE("setMaxDequeuedBufferCount: the requested maxDequeuedBuffer" 11972daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos "count (%d) exceeds the current dequeued buffer count (%d)", 12072daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos maxDequeuedBuffers, dequeuedCount); 12172daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos return BAD_VALUE; 12272daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos } 123fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 124567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos int bufferCount = mCore->getMinUndequeuedBufferCountLocked(); 125fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos bufferCount += maxDequeuedBuffers; 126fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 127fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) { 128fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos BQ_LOGE("setMaxDequeuedBufferCount: bufferCount %d too large " 129fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos "(max %d)", bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS); 130fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return BAD_VALUE; 131fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 132fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 133567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos const int minBufferSlots = mCore->getMinMaxBufferCountLocked(); 134fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if (bufferCount < minBufferSlots) { 135fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos BQ_LOGE("setMaxDequeuedBufferCount: requested buffer count %d is " 136fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos "less than minimum %d", bufferCount, minBufferSlots); 137fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return BAD_VALUE; 138fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 139fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 14019e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos if (bufferCount > mCore->mMaxBufferCount) { 14119e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos BQ_LOGE("setMaxDequeuedBufferCount: %d dequeued buffers would " 142567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos "exceed the maxBufferCount (%d) (maxAcquired %d async %d " 143567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos "mDequeuedBufferCannotBlock %d)", maxDequeuedBuffers, 144567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos mCore->mMaxBufferCount, mCore->mMaxAcquiredBufferCount, 145567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos mCore->mAsyncMode, mCore->mDequeueBufferCannotBlock); 14619e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos return BAD_VALUE; 14719e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos } 14819e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos 14972daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos int delta = maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount; 150981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (!mCore->adjustAvailableSlotsLocked(delta)) { 15123b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos return BAD_VALUE; 15223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos } 153fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers; 1549e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos VALIDATE_CONSISTENCY(); 15572daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos if (delta < 0) { 156981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos listener = mCore->mConsumerListener; 15772daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos } 158fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos mCore->mDequeueCondition.broadcast(); 159fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } // Autolock scope 160fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 161fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos // Call back without lock held 162981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (listener != NULL) { 163981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos listener->onBuffersReleased(); 164fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 165fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 166fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return NO_ERROR; 167fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos} 168fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 169fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballosstatus_t BufferQueueProducer::setAsyncMode(bool async) { 170fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos ATRACE_CALL(); 171fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos BQ_LOGV("setAsyncMode: async = %d", async); 172fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 173981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos sp<IConsumerListener> listener; 174fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos { // Autolock scope 175fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos Mutex::Autolock lock(mCore->mMutex); 176fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos mCore->waitWhileAllocatingLocked(); 177fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 178fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if (mCore->mIsAbandoned) { 179fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos BQ_LOGE("setAsyncMode: BufferQueue has been abandoned"); 180fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return NO_INIT; 181fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 182fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 183245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos if (async == mCore->mAsyncMode) { 184245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos return NO_ERROR; 185245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos } 186245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos 18719e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos if ((mCore->mMaxAcquiredBufferCount + mCore->mMaxDequeuedBufferCount + 188567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos (async || mCore->mDequeueBufferCannotBlock ? 1 : 0)) > 189567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos mCore->mMaxBufferCount) { 19019e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos BQ_LOGE("setAsyncMode(%d): this call would cause the " 19119e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos "maxBufferCount (%d) to be exceeded (maxAcquired %d " 192567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos "maxDequeued %d mDequeueBufferCannotBlock %d)", async, 193567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos mCore->mMaxBufferCount, mCore->mMaxAcquiredBufferCount, 194567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos mCore->mMaxDequeuedBufferCount, 195567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos mCore->mDequeueBufferCannotBlock); 19619e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos return BAD_VALUE; 19719e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos } 19819e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos 19923b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos int delta = mCore->getMaxBufferCountLocked(async, 20023b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mCore->mDequeueBufferCannotBlock, mCore->mMaxBufferCount) 20123b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos - mCore->getMaxBufferCountLocked(); 20223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 203981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (!mCore->adjustAvailableSlotsLocked(delta)) { 20423b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos BQ_LOGE("setAsyncMode: BufferQueue failed to adjust the number of " 20523b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos "available slots. Delta = %d", delta); 20623b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos return BAD_VALUE; 20723b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos } 208fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos mCore->mAsyncMode = async; 2099e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos VALIDATE_CONSISTENCY(); 210fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos mCore->mDequeueCondition.broadcast(); 211245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos if (delta < 0) { 212245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos listener = mCore->mConsumerListener; 213245cc5b57da46d5852aa820be2a96f37425b3337Pablo Ceballos } 214fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } // Autolock scope 215fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 216fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos // Call back without lock held 217981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (listener != NULL) { 218981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos listener->onBuffersReleased(); 219fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 220fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return NO_ERROR; 221fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos} 222fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 2235ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stozaint BufferQueueProducer::getFreeBufferLocked() const { 2245ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza if (mCore->mFreeBuffers.empty()) { 2255ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza return BufferQueueCore::INVALID_BUFFER_SLOT; 2265ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza } 22723b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos int slot = mCore->mFreeBuffers.front(); 2285ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza mCore->mFreeBuffers.pop_front(); 2295ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza return slot; 2305ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza} 2315ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza 23223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballosint BufferQueueProducer::getFreeSlotLocked() const { 2335ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza if (mCore->mFreeSlots.empty()) { 2345ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza return BufferQueueCore::INVALID_BUFFER_SLOT; 2355ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza } 236dce5c559712031b3cb8039067819c11c1a4e16f9Pablo Ceballos int slot = *(mCore->mFreeSlots.begin()); 23723b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mCore->mFreeSlots.erase(slot); 238dce5c559712031b3cb8039067819c11c1a4e16f9Pablo Ceballos return slot; 2395ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza} 2405ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza 2415ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stozastatus_t BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller, 24223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos int* found) const { 2435ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza auto callerString = (caller == FreeSlotCaller::Dequeue) ? 2445ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza "dequeueBuffer" : "attachBuffer"; 2459f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza bool tryAgain = true; 2469f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza while (tryAgain) { 2479f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mCore->mIsAbandoned) { 2485ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza BQ_LOGE("%s: BufferQueue has been abandoned", callerString); 2499f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_INIT; 2509f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2519f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 2529f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int dequeuedCount = 0; 2539f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int acquiredCount = 0; 25423b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos for (int s : mCore->mActiveBuffers) { 255ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mSlots[s].mBufferState.isDequeued()) { 256ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos ++dequeuedCount; 257ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 258ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mSlots[s].mBufferState.isAcquired()) { 259ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos ++acquiredCount; 2609f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2619f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2629f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 263e5b755a045f4203fdd989047441259893c6fbe2dPablo Ceballos // Producers are not allowed to dequeue more than 264e5b755a045f4203fdd989047441259893c6fbe2dPablo Ceballos // mMaxDequeuedBufferCount buffers. 265e5b755a045f4203fdd989047441259893c6fbe2dPablo Ceballos // This check is only done if a buffer has already been queued 266e5b755a045f4203fdd989047441259893c6fbe2dPablo Ceballos if (mCore->mBufferHasBeenQueued && 267e5b755a045f4203fdd989047441259893c6fbe2dPablo Ceballos dequeuedCount >= mCore->mMaxDequeuedBufferCount) { 268e5b755a045f4203fdd989047441259893c6fbe2dPablo Ceballos BQ_LOGE("%s: attempting to exceed the max dequeued buffer count " 2695ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza "(%d)", callerString, mCore->mMaxDequeuedBufferCount); 2709f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return INVALID_OPERATION; 2719f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2729f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 2730de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza *found = BufferQueueCore::INVALID_BUFFER_SLOT; 2740de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 275ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // If we disconnect and reconnect quickly, we can be in a state where 276ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // our slots are empty but we have many buffers in the queue. This can 277ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // cause us to run out of memory if we outrun the consumer. Wait here if 278ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // it looks like we have too many buffers queued up. 27923b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos const int maxBufferCount = mCore->getMaxBufferCountLocked(); 2808f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn bool tooManyBuffers = mCore->mQueue.size() 2818f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn > static_cast<size_t>(maxBufferCount); 282ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (tooManyBuffers) { 2835ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza BQ_LOGV("%s: queue size is %zu, waiting", callerString, 284ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza mCore->mQueue.size()); 2850de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza } else { 2863559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos // If in shared buffer mode and a shared buffer exists, always 287ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // return it. 2883559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot != 289ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BufferQueueCore::INVALID_BUFFER_SLOT) { 2903559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos *found = mCore->mSharedBufferSlot; 2915ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza } else { 2925ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza if (caller == FreeSlotCaller::Dequeue) { 2935ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza // If we're calling this from dequeue, prefer free buffers 29423b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos int slot = getFreeBufferLocked(); 2955ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza if (slot != BufferQueueCore::INVALID_BUFFER_SLOT) { 2965ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza *found = slot; 2975ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza } else if (mCore->mAllowAllocation) { 29823b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos *found = getFreeSlotLocked(); 2995ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza } 3005ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza } else { 3015ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza // If we're calling this from attach, prefer free slots 30223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos int slot = getFreeSlotLocked(); 3035ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza if (slot != BufferQueueCore::INVALID_BUFFER_SLOT) { 3045ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza *found = slot; 3055ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza } else { 3065ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza *found = getFreeBufferLocked(); 3075ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza } 3080de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza } 3090de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza } 310ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza } 311ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza 312ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // If no buffer is found, or if the queue has too many buffers 313ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // outstanding, wait for a buffer to be acquired or released, or for the 314ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // max buffer count to change. 315ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) || 316ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza tooManyBuffers; 3179f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (tryAgain) { 3189f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // Return an error if we're in non-blocking mode (producer and 3199f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // consumer are controlled by the application). 3209f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // However, the consumer is allowed to briefly acquire an extra 3219f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // buffer (which could cause us to have to wait here), which is 3229f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // okay, since it is only used to implement an atomic acquire + 3239f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // release (e.g., in GLConsumer::updateTexImage()) 324fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if ((mCore->mDequeueBufferCannotBlock || mCore->mAsyncMode) && 3259f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza (acquiredCount <= mCore->mMaxAcquiredBufferCount)) { 3269f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return WOULD_BLOCK; 3279f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 328127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza if (mDequeueTimeout >= 0) { 329127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza status_t result = mCore->mDequeueCondition.waitRelative( 330127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza mCore->mMutex, mDequeueTimeout); 331127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza if (result == TIMED_OUT) { 332127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza return result; 333127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza } 334127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza } else { 335127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza mCore->mDequeueCondition.wait(mCore->mMutex); 336127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza } 3379f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 3389f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } // while (tryAgain) 3399f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 3409f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_ERROR; 3419f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 3429f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 343289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::dequeueBuffer(int *outSlot, 344567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos sp<android::Fence> *outFence, uint32_t width, uint32_t height, 345567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos PixelFormat format, uint32_t usage) { 346289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 347289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 348289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 349289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mConsumerName = mCore->mConsumerName; 350583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 351583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mIsAbandoned) { 352583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned"); 353583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 354583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 355583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 356583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 357583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos BQ_LOGE("dequeueBuffer: BufferQueue has no connected producer"); 358583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 359583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 360289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 361289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 362567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos BQ_LOGV("dequeueBuffer: w=%u h=%u format=%#x, usage=%#x", width, height, 363567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos format, usage); 364289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 365289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if ((width && !height) || (!width && height)) { 366289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height); 367289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 368289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 369289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 370289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status_t returnFlags = NO_ERROR; 371289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLDisplay eglDisplay = EGL_NO_DISPLAY; 372289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; 3739f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza bool attachedByConsumer = false; 374289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 375289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 376289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 37778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 378289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 379289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (format == 0) { 380289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza format = mCore->mDefaultBufferFormat; 381289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 382289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 383289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Enable the usage bits the consumer requested 384289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza usage |= mCore->mConsumerUsageBits; 385289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 3869de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza const bool useDefaultSize = !width && !height; 3879de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza if (useDefaultSize) { 3889de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza width = mCore->mDefaultWidth; 3899de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza height = mCore->mDefaultHeight; 3909f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 391289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 392981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos int found = BufferItem::INVALID_BUFFER_SLOT; 3939de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza while (found == BufferItem::INVALID_BUFFER_SLOT) { 3945ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue, 39523b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos &found); 3969de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza if (status != NO_ERROR) { 3979de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza return status; 3989de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza } 3999de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 4009de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza // This should not happen 4019de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 4029de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza BQ_LOGE("dequeueBuffer: no available buffer slots"); 4039de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza return -EBUSY; 4049de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza } 4059de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 4069de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer); 4079de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 4089de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza // If we are not allowed to allocate new buffers, 4099de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza // waitForFreeSlotThenRelock must have returned a slot containing a 4109de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza // buffer. If this buffer would require reallocation to meet the 4119de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza // requested attributes, we free it and attempt to get another one. 4129de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza if (!mCore->mAllowAllocation) { 4139de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza if (buffer->needsReallocation(width, height, format, usage)) { 4143559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (mCore->mSharedBufferSlot == found) { 415ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("dequeueBuffer: cannot re-allocate a shared" 416ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos "buffer"); 417ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos return BAD_VALUE; 418ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 41923b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mCore->mFreeSlots.insert(found); 42023b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mCore->clearBufferSlotLocked(found); 4219de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza found = BufferItem::INVALID_BUFFER_SLOT; 4229de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza continue; 4239de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza } 4249de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza } 425289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 426289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 42723b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer); 4283559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (mCore->mSharedBufferSlot == found && 42923b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos buffer->needsReallocation(width, height, format, usage)) { 43023b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos BQ_LOGE("dequeueBuffer: cannot re-allocate a shared" 43123b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos "buffer"); 43223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 43323b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos return BAD_VALUE; 43423b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos } 43523b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 4363559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (mCore->mSharedBufferSlot != found) { 43723b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mCore->mActiveBuffers.insert(found); 43823b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos } 439289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outSlot = found; 440289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_BUFFER_INDEX(found); 441289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 44223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos attachedByConsumer = mSlots[found].mNeedsReallocation; 44323b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mSlots[found].mNeedsReallocation = false; 4449f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 445ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[found].mBufferState.dequeue(); 446ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 447289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if ((buffer == NULL) || 4489de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza buffer->needsReallocation(width, height, format, usage)) 449289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { 450289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mAcquireCalled = false; 451289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mGraphicBuffer = NULL; 452289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mRequestBufferCalled = false; 453289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglDisplay = EGL_NO_DISPLAY; 454289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglFence = EGL_NO_SYNC_KHR; 455289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mFence = Fence::NO_FENCE; 4564afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza mCore->mBufferAge = 0; 457ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mIsAllocating = true; 458289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 459289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza returnFlags |= BUFFER_NEEDS_REALLOCATION; 4604afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza } else { 4614afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza // We add 1 because that will be the frame number when this buffer 4624afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza // is queued 4634afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza mCore->mBufferAge = 4644afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber; 465289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 466289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 467800b41ab8486b9d885124071659c774f6c1856e2Dan Stoza BQ_LOGV("dequeueBuffer: setting buffer age to %" PRIu64, 468800b41ab8486b9d885124071659c774f6c1856e2Dan Stoza mCore->mBufferAge); 4694afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza 470289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (CC_UNLIKELY(mSlots[found].mFence == NULL)) { 471289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: about to return a NULL fence - " 472289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "slot=%d w=%d h=%d format=%u", 473289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza found, buffer->width, buffer->height, buffer->format); 474289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 475289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 476289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglDisplay = mSlots[found].mEglDisplay; 477289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglFence = mSlots[found].mEglFence; 47828c65ad1a1bc2cfd232044e9ea704197483cf250Pablo Ceballos // Don't return a fence in shared buffer mode, except for the first 47928c65ad1a1bc2cfd232044e9ea704197483cf250Pablo Ceballos // frame. 48028c65ad1a1bc2cfd232044e9ea704197483cf250Pablo Ceballos *outFence = (mCore->mSharedBufferMode && 48128c65ad1a1bc2cfd232044e9ea704197483cf250Pablo Ceballos mCore->mSharedBufferSlot == found) ? 48228c65ad1a1bc2cfd232044e9ea704197483cf250Pablo Ceballos Fence::NO_FENCE : mSlots[found].mFence; 483289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglFence = EGL_NO_SYNC_KHR; 484289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mFence = Fence::NO_FENCE; 48528c65ad1a1bc2cfd232044e9ea704197483cf250Pablo Ceballos 48628c65ad1a1bc2cfd232044e9ea704197483cf250Pablo Ceballos // If shared buffer mode has just been enabled, cache the slot of the 48728c65ad1a1bc2cfd232044e9ea704197483cf250Pablo Ceballos // first buffer that is dequeued and mark it as the shared buffer. 48828c65ad1a1bc2cfd232044e9ea704197483cf250Pablo Ceballos if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == 48928c65ad1a1bc2cfd232044e9ea704197483cf250Pablo Ceballos BufferQueueCore::INVALID_BUFFER_SLOT) { 49028c65ad1a1bc2cfd232044e9ea704197483cf250Pablo Ceballos mCore->mSharedBufferSlot = found; 49128c65ad1a1bc2cfd232044e9ea704197483cf250Pablo Ceballos mSlots[found].mBufferState.mShared = true; 49228c65ad1a1bc2cfd232044e9ea704197483cf250Pablo Ceballos } 493289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 494289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 495289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (returnFlags & BUFFER_NEEDS_REALLOCATION) { 496289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status_t error; 49729a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot); 498289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 4993be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza width, height, format, usage, &error)); 500289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 501289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 502289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 503ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (graphicBuffer != NULL && !mCore->mIsAbandoned) { 504ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos graphicBuffer->setGenerationNumber(mCore->mGenerationNumber); 505ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[*outSlot].mGraphicBuffer = graphicBuffer; 506ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 507ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 508ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mIsAllocating = false; 509ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mIsAllocatingCondition.broadcast(); 510ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 511ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (graphicBuffer == NULL) { 512ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("dequeueBuffer: createGraphicBuffer failed"); 513ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos return error; 514ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 515ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 516289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 517289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned"); 518289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 519289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 52023b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 5219e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos VALIDATE_CONSISTENCY(); 522289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 523289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 524289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 5259f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (attachedByConsumer) { 5269f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza returnFlags |= BUFFER_NEEDS_REALLOCATION; 5279f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 5289f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 529289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (eglFence != EGL_NO_SYNC_KHR) { 530289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0, 531289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1000000000); 532289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If something goes wrong, log the error, but return the buffer without 533289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // synchronizing access to it. It's too late at this point to abort the 534289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // dequeue operation. 535289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (result == EGL_FALSE) { 536289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: error %#x waiting for fence", 537289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglGetError()); 538289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 539289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: timeout waiting for fence"); 540289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 541289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglDestroySyncKHR(eglDisplay, eglFence); 542289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 543289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 5448f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x", 5458f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn *outSlot, 546289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[*outSlot].mFrameNumber, 547289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[*outSlot].mGraphicBuffer->handle, returnFlags); 548289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 549289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return returnFlags; 550289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 551289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 5529f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatus_t BufferQueueProducer::detachBuffer(int slot) { 5539f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_CALL(); 5549f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_BUFFER_INDEX(slot); 555ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGV("detachBuffer: slot %d", slot); 5569f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 55793dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala sp<IConsumerListener> listener; 55893dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala { 55993dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala Mutex::Autolock lock(mCore->mMutex); 560789a0c82cb370d6b82f401cc130af58c85802cbfPablo Ceballos 56193dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala if (mCore->mIsAbandoned) { 56293dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala BQ_LOGE("detachBuffer: BufferQueue has been abandoned"); 56393dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala return NO_INIT; 56493dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala } 5659f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 56693dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 56793dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala BQ_LOGE("detachBuffer: BufferQueue has no connected producer"); 56893dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala return NO_INIT; 56993dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala } 570981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos 57193dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala if (mCore->mSharedBufferMode || mCore->mSharedBufferSlot == slot) { 57293dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala BQ_LOGE("detachBuffer: cannot detach a buffer in shared buffer mode"); 57393dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala return BAD_VALUE; 57493dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala } 57593dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala 57693dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 57793dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", 57893dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 57993dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala return BAD_VALUE; 58093dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala } else if (!mSlots[slot].mBufferState.isDequeued()) { 58193dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala BQ_LOGE("detachBuffer: slot %d is not owned by the producer " 58293dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala "(state = %s)", slot, mSlots[slot].mBufferState.string()); 58393dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala return BAD_VALUE; 58493dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala } else if (!mSlots[slot].mRequestBufferCalled) { 58593dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala BQ_LOGE("detachBuffer: buffer in slot %d has not been requested", 58693dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala slot); 58793dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala return BAD_VALUE; 58893dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala } 58993dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala 59093dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala mSlots[slot].mBufferState.detachProducer(); 59193dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala mCore->mActiveBuffers.erase(slot); 59293dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala mCore->mFreeSlots.insert(slot); 59393dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala mCore->clearBufferSlotLocked(slot); 59493dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala mCore->mDequeueCondition.broadcast(); 59593dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala VALIDATE_CONSISTENCY(); 59693dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala listener = mCore->mConsumerListener; 597789a0c82cb370d6b82f401cc130af58c85802cbfPablo Ceballos } 5989f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 59993dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala if (listener != NULL) { 60093dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala listener->onBuffersReleased(); 60193dd0518a0101844ef435a3425c803c986b38d87Eino-Ville Talvala } 602981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos 6039f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_ERROR; 6049f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 6059f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 606d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stozastatus_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, 607d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza sp<Fence>* outFence) { 608d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza ATRACE_CALL(); 609d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 610d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if (outBuffer == NULL) { 611d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza BQ_LOGE("detachNextBuffer: outBuffer must not be NULL"); 612d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return BAD_VALUE; 613d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } else if (outFence == NULL) { 614d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza BQ_LOGE("detachNextBuffer: outFence must not be NULL"); 615d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return BAD_VALUE; 616d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 617d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 618981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos Mutex::Autolock lock(mCore->mMutex); 619d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 620981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (mCore->mIsAbandoned) { 621981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned"); 622981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos return NO_INIT; 623981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos } 624d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 625981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 626981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos BQ_LOGE("detachNextBuffer: BufferQueue has no connected producer"); 627981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos return NO_INIT; 628981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos } 629583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 6303559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (mCore->mSharedBufferMode) { 6313559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos BQ_LOGE("detachNextBuffer: cannot detach a buffer in shared buffer " 6323559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos "mode"); 633981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos return BAD_VALUE; 634981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos } 635ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 636981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->waitWhileAllocatingLocked(); 637583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 638981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (mCore->mFreeBuffers.empty()) { 639981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos return NO_MEMORY; 640981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos } 6418dddc990103b71137be2a6365a26b1ac36598e68Dan Stoza 642981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos int found = mCore->mFreeBuffers.front(); 643981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mFreeBuffers.remove(found); 644981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mFreeSlots.insert(found); 6450de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 646981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos BQ_LOGV("detachNextBuffer detached slot %d", found); 647d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 648981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos *outBuffer = mSlots[found].mGraphicBuffer; 649981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos *outFence = mSlots[found].mFence; 650981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->clearBufferSlotLocked(found); 651981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos VALIDATE_CONSISTENCY(); 652d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 653d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return NO_ERROR; 654d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza} 655d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 6569f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatus_t BufferQueueProducer::attachBuffer(int* outSlot, 6579f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza const sp<android::GraphicBuffer>& buffer) { 6589f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_CALL(); 6599f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 6609f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (outSlot == NULL) { 661ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: outSlot must not be NULL"); 6629f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 6639f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } else if (buffer == NULL) { 664ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: cannot attach NULL buffer"); 6659f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 6669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 6679f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 6689f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza Mutex::Autolock lock(mCore->mMutex); 669583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 670583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mIsAbandoned) { 671ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: BufferQueue has been abandoned"); 672583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 673583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 674583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 675583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 676ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: BufferQueue has no connected producer"); 677583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 678583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 6799f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 6803559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (mCore->mSharedBufferMode) { 6813559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode"); 682ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos return BAD_VALUE; 683ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 684ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 685812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza if (buffer->getGenerationNumber() != mCore->mGenerationNumber) { 686812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] " 687812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza "[queue %u]", buffer->getGenerationNumber(), 688812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza mCore->mGenerationNumber); 689812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza return BAD_VALUE; 690812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza } 691812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza 692583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos mCore->waitWhileAllocatingLocked(); 693583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 6949f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status_t returnFlags = NO_ERROR; 6959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int found; 69623b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Attach, &found); 6979f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (status != NO_ERROR) { 6989f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return status; 6999f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 7009f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 7019f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // This should not happen 7029f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 703ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: no available buffer slots"); 7049f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return -EBUSY; 7059f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 7069f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 7079f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *outSlot = found; 7089f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_BUFFER_INDEX(*outSlot); 709ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGV("attachBuffer: returning slot %d flags=%#x", 7109f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *outSlot, returnFlags); 7119f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 7129f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mGraphicBuffer = buffer; 713ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[*outSlot].mBufferState.attachProducer(); 7149f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR; 7159f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mFence = Fence::NO_FENCE; 7162443c7903c6910b57bcc615a4bf2e60068c15dbdDan Stoza mSlots[*outSlot].mRequestBufferCalled = true; 71723b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mSlots[*outSlot].mAcquireCalled = false; 71823b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mCore->mActiveBuffers.insert(found); 7199e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos VALIDATE_CONSISTENCY(); 7200de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 7219f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return returnFlags; 7229f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 7239f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 724289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::queueBuffer(int slot, 725289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const QueueBufferInput &input, QueueBufferOutput *output) { 726289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 727289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_BUFFER_INDEX(slot); 728289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 729289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int64_t timestamp; 730289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza bool isAutoTimestamp; 73182c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala android_dataspace dataSpace; 73260d6922a011fe18c111b8d30fb6ef1f655b6b15ePablo Ceballos Rect crop(Rect::EMPTY_RECT); 733289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int scalingMode; 734289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza uint32_t transform; 7351681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk uint32_t stickyTransform; 736289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<Fence> fence; 73782c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala input.deflate(×tamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode, 738567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos &transform, &fence, &stickyTransform); 7395065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza Region surfaceDamage = input.getSurfaceDamage(); 740289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 741289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (fence == NULL) { 742289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: fence is NULL"); 743de288fe2d43adfa1b2243ae534faaf832bf50491Jesse Hall return BAD_VALUE; 744289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 745289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 746289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (scalingMode) { 747289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_FREEZE: 748289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 749289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 750289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: 751289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 752289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 753289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode); 7549f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 755289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 756289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 7578dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza sp<IConsumerListener> frameAvailableListener; 7588dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza sp<IConsumerListener> frameReplacedListener; 7598dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza int callbackTicket = 0; 7608dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza BufferItem item; 761289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 762289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 763289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 764289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 765289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: BufferQueue has been abandoned"); 766289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 767289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 768289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 769583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 770583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos BQ_LOGE("queueBuffer: BufferQueue has no connected producer"); 771583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 772583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 773583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 77423b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 775289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)", 77623b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 7779f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 778ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } else if (!mSlots[slot].mBufferState.isDequeued()) { 779289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot %d is not owned by the producer " 780ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos "(state = %s)", slot, mSlots[slot].mBufferState.string()); 7819f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 782289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (!mSlots[slot].mRequestBufferCalled) { 783289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot %d was queued without requesting " 784289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "a buffer", slot); 7859f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 786289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 787289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 7883559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos // If shared buffer mode has just been enabled, cache the slot of the 789295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos // first buffer that is queued and mark it as the shared buffer. 7903559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == 791295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos BufferQueueCore::INVALID_BUFFER_SLOT) { 7923559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos mCore->mSharedBufferSlot = slot; 793295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos mSlots[slot].mBufferState.mShared = true; 794295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos } 795295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos 79682c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d" 7978f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn " crop=[%d,%d,%d,%d] transform=%#x scale=%s", 79882c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala slot, mCore->mFrameCounter + 1, timestamp, dataSpace, 7993be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza crop.left, crop.top, crop.right, crop.bottom, transform, 8003be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode))); 801289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 802289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer); 803289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight()); 80460d6922a011fe18c111b8d30fb6ef1f655b6b15ePablo Ceballos Rect croppedRect(Rect::EMPTY_RECT); 805289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza crop.intersect(bufferRect, &croppedRect); 806289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (croppedRect != crop) { 807289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: crop rect is not contained within the " 808289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "buffer in slot %d", slot); 8099f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 810289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 811289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 81282c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala // Override UNKNOWN dataspace with consumer default 81382c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala if (dataSpace == HAL_DATASPACE_UNKNOWN) { 81482c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala dataSpace = mCore->mDefaultBufferDataSpace; 81582c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala } 81682c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala 817289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFence = fence; 818ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[slot].mBufferState.queue(); 819ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 820289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ++mCore->mFrameCounter; 821289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFrameNumber = mCore->mFrameCounter; 822289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 823289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mAcquireCalled = mSlots[slot].mAcquireCalled; 824289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mGraphicBuffer = mSlots[slot].mGraphicBuffer; 825289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mCrop = crop; 8263be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza item.mTransform = transform & 8273be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY); 828289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mTransformToDisplayInverse = 8293be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0; 8303be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza item.mScalingMode = static_cast<uint32_t>(scalingMode); 831289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mTimestamp = timestamp; 832289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mIsAutoTimestamp = isAutoTimestamp; 83382c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala item.mDataSpace = dataSpace; 834289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mFrameNumber = mCore->mFrameCounter; 835289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mSlot = slot; 836289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mFence = fence; 837567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos item.mIsDroppable = mCore->mAsyncMode || 838ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mDequeueBufferCannotBlock || 8393559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == slot); 8405065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza item.mSurfaceDamage = surfaceDamage; 841063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos item.mQueuedBuffer = true; 8423559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh; 843289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 8441681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk mStickyTransform = stickyTransform; 8451681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk 846ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // Cache the shared buffer data so that the BufferItem can be recreated. 8473559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (mCore->mSharedBufferMode) { 8483559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos mCore->mSharedBufferCache.crop = crop; 8493559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos mCore->mSharedBufferCache.transform = transform; 8503559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos mCore->mSharedBufferCache.scalingMode = static_cast<uint32_t>( 851ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos scalingMode); 8523559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos mCore->mSharedBufferCache.dataspace = dataSpace; 853ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 854ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 855289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mQueue.empty()) { 856289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // When the queue is empty, we can ignore mDequeueBufferCannotBlock 857289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // and simply queue this buffer 858289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mQueue.push_back(item); 8598dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameAvailableListener = mCore->mConsumerListener; 860289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else { 8614d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos // When the queue is not empty, we need to look at the last buffer 8624d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos // in the queue to see if we need to replace it 8634d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos const BufferItem& last = mCore->mQueue.itemAt( 8644d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos mCore->mQueue.size() - 1); 8654d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos if (last.mIsDroppable) { 86623b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 8674d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos if (!last.mIsStale) { 8684d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos mSlots[last.mSlot].mBufferState.freeQueued(); 869ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 8703559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos // After leaving shared buffer mode, the shared buffer will 871ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // still be around. Mark it as no longer shared if this 872ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // operation causes it to be free. 8733559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (!mCore->mSharedBufferMode && 8744d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos mSlots[last.mSlot].mBufferState.isFree()) { 8754d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos mSlots[last.mSlot].mBufferState.mShared = false; 876ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 877ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // Don't put the shared buffer on the free list. 8784d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos if (!mSlots[last.mSlot].mBufferState.isShared()) { 8794d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos mCore->mActiveBuffers.erase(last.mSlot); 8804d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos mCore->mFreeBuffers.push_back(last.mSlot); 881ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 882289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 88323b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 884289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Overwrite the droppable buffer with the incoming one 8854d85da4a77203f4c361e48699e5598ebe8c77b32Pablo Ceballos mCore->mQueue.editItemAt(mCore->mQueue.size() - 1) = item; 8868dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameReplacedListener = mCore->mConsumerListener; 887289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else { 888289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mQueue.push_back(item); 8898dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameAvailableListener = mCore->mConsumerListener; 890289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 891289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 892289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 893289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mBufferHasBeenQueued = true; 894289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 89550101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza mCore->mLastQueuedSlot = slot; 896289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 897289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, 8983be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza mCore->mTransformHint, 8993be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza static_cast<uint32_t>(mCore->mQueue.size())); 900289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 901289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); 9028dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza 9038dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // Take a ticket for the callback functions 9048dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza callbackTicket = mNextCallbackTicket++; 9050de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 9069e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos VALIDATE_CONSISTENCY(); 907289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 908289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 9098dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // Don't send the GraphicBuffer through the callback, and don't send 9108dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // the slot number, since the consumer shouldn't need it 9118dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza item.mGraphicBuffer.clear(); 9128dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza item.mSlot = BufferItem::INVALID_BUFFER_SLOT; 9138dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza 9148dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // Call back without the main BufferQueue lock held, but with the callback 9158dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // lock held so we can ensure that callbacks occur in order 9168dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza { 9178dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza Mutex::Autolock lock(mCallbackMutex); 9188dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza while (callbackTicket != mCurrentCallbackTicket) { 9198dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mCallbackCondition.wait(mCallbackMutex); 9208dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza } 9218dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza 9228dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza if (frameAvailableListener != NULL) { 9238dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameAvailableListener->onFrameAvailable(item); 9248dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza } else if (frameReplacedListener != NULL) { 9258dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameReplacedListener->onFrameReplaced(item); 9268dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza } 9278dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza 9288dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza ++mCurrentCallbackTicket; 9298dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mCallbackCondition.broadcast(); 930289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 931289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 93282fbb121763e16dcf58fb2a3e65d2f93543d9078Christian Poetzsch // Wait without lock held 93382fbb121763e16dcf58fb2a3e65d2f93543d9078Christian Poetzsch if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) { 93482fbb121763e16dcf58fb2a3e65d2f93543d9078Christian Poetzsch // Waiting here allows for two full buffers to be queued but not a 93582fbb121763e16dcf58fb2a3e65d2f93543d9078Christian Poetzsch // third. In the event that frames take varying time, this makes a 93682fbb121763e16dcf58fb2a3e65d2f93543d9078Christian Poetzsch // small trade-off in favor of latency rather than throughput. 93782fbb121763e16dcf58fb2a3e65d2f93543d9078Christian Poetzsch mLastQueueBufferFence->waitForever("Throttling EGL Production"); 93882fbb121763e16dcf58fb2a3e65d2f93543d9078Christian Poetzsch } 93950101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza mLastQueueBufferFence = fence; 9401a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck mLastQueuedCrop = item.mCrop; 9411a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck mLastQueuedTransform = item.mTransform; 94282fbb121763e16dcf58fb2a3e65d2f93543d9078Christian Poetzsch 943289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 944289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 945289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 946583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballosstatus_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) { 947289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 948289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("cancelBuffer: slot %d", slot); 949289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 950289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 951289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 952289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: BufferQueue has been abandoned"); 953583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 954583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 955583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 956583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 957583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos BQ_LOGE("cancelBuffer: BufferQueue has no connected producer"); 958583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 959289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 960289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 9613559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (mCore->mSharedBufferMode) { 9623559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode"); 963ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos return BAD_VALUE; 964ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 965ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 9663e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 967289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", 9683e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 969583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return BAD_VALUE; 970ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } else if (!mSlots[slot].mBufferState.isDequeued()) { 971289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " 972ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos "(state = %s)", slot, mSlots[slot].mBufferState.string()); 973583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return BAD_VALUE; 974289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (fence == NULL) { 975289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: fence is NULL"); 976583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return BAD_VALUE; 977289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 978289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 979ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[slot].mBufferState.cancel(); 980ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 9813559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos // After leaving shared buffer mode, the shared buffer will still be around. 982ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // Mark it as no longer shared if this operation causes it to be free. 9833559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) { 984ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[slot].mBufferState.mShared = false; 985ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 986ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 987ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // Don't put the shared buffer on the free list. 988ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (!mSlots[slot].mBufferState.isShared()) { 98923b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mCore->mActiveBuffers.erase(slot); 99023b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mCore->mFreeBuffers.push_back(slot); 991ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 99223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 993289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFence = fence; 994289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 9959e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos VALIDATE_CONSISTENCY(); 996583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 997583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_ERROR; 998289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 999289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1000289ade165e60b5f71734d30e535f16eb1f4313adDan Stozaint BufferQueueProducer::query(int what, int *outValue) { 1001289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 1002289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 1003289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1004289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (outValue == NULL) { 1005289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("query: outValue was NULL"); 1006289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 1007289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1008289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1009289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 1010289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("query: BufferQueue has been abandoned"); 1011289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 1012289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1013289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1014289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int value; 1015289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (what) { 1016289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_WIDTH: 10173be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza value = static_cast<int32_t>(mCore->mDefaultWidth); 1018289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 1019289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_HEIGHT: 10203be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza value = static_cast<int32_t>(mCore->mDefaultHeight); 1021289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 1022289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_FORMAT: 10233be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza value = static_cast<int32_t>(mCore->mDefaultBufferFormat); 1024289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 1025289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 1026567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos value = mCore->getMinUndequeuedBufferCountLocked(); 1027289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 10281681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk case NATIVE_WINDOW_STICKY_TRANSFORM: 10293be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza value = static_cast<int32_t>(mStickyTransform); 10301681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk break; 1031289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: 1032289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = (mCore->mQueue.size() > 1); 1033289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 1034289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_CONSUMER_USAGE_BITS: 10353be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza value = static_cast<int32_t>(mCore->mConsumerUsageBits); 1036289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 103782c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala case NATIVE_WINDOW_DEFAULT_DATASPACE: 103882c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace); 103982c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala break; 10404afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza case NATIVE_WINDOW_BUFFER_AGE: 10414afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza if (mCore->mBufferAge > INT32_MAX) { 10424afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza value = 0; 10434afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza } else { 10444afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza value = static_cast<int32_t>(mCore->mBufferAge); 10454afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza } 10464afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza break; 1047289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 1048289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 1049289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1050289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1051289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("query: %d? %d", what, value); 1052289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outValue = value; 1053289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 1054289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 1055289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1056f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stozastatus_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, 1057289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int api, bool producerControlledByApp, QueueBufferOutput *output) { 1058289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 1059981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos Mutex::Autolock lock(mCore->mMutex); 1060981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mConsumerName = mCore->mConsumerName; 1061981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos BQ_LOGV("connect: api=%d producerControlledByApp=%s", api, 1062981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos producerControlledByApp ? "true" : "false"); 1063289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1064981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (mCore->mIsAbandoned) { 1065981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos BQ_LOGE("connect: BufferQueue has been abandoned"); 1066981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos return NO_INIT; 1067981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos } 1068289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1069981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (mCore->mConsumerListener == NULL) { 1070981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos BQ_LOGE("connect: BufferQueue has no consumer"); 1071981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos return NO_INIT; 1072981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos } 1073289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1074981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (output == NULL) { 1075981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos BQ_LOGE("connect: output was NULL"); 1076981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos return BAD_VALUE; 1077981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos } 1078289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1079981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 1080981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos BQ_LOGE("connect: already connected (cur=%d req=%d)", 1081981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mConnectedApi, api); 1082981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos return BAD_VALUE; 1083981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos } 108423b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 1085981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, 1086981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mDequeueTimeout < 0 ? 1087981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mConsumerControlledByApp && producerControlledByApp : false, 1088981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mMaxBufferCount) - 1089981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->getMaxBufferCountLocked(); 1090981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (!mCore->adjustAvailableSlotsLocked(delta)) { 1091981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos BQ_LOGE("connect: BufferQueue failed to adjust the number of available " 1092981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos "slots. Delta = %d", delta); 1093981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos return BAD_VALUE; 1094981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos } 1095789a0c82cb370d6b82f401cc130af58c85802cbfPablo Ceballos 1096981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos int status = NO_ERROR; 1097981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos switch (api) { 1098981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos case NATIVE_WINDOW_API_EGL: 1099981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos case NATIVE_WINDOW_API_CPU: 1100981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos case NATIVE_WINDOW_API_MEDIA: 1101981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos case NATIVE_WINDOW_API_CAMERA: 1102981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mConnectedApi = api; 1103981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, 1104981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mTransformHint, 1105981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos static_cast<uint32_t>(mCore->mQueue.size())); 1106981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos 1107981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos // Set up a death notification so that we can disconnect 1108981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos // automatically if the remote producer dies 1109981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (listener != NULL && 1110981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos IInterface::asBinder(listener)->remoteBinder() != NULL) { 1111981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos status = IInterface::asBinder(listener)->linkToDeath( 1112981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos static_cast<IBinder::DeathRecipient*>(this)); 1113981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (status != NO_ERROR) { 1114981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos BQ_LOGE("connect: linkToDeath failed: %s (%d)", 1115981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos strerror(-status), status); 1116289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1117981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos } 1118981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mConnectedProducerListener = listener; 1119981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos break; 1120981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos default: 1121981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos BQ_LOGE("connect: unknown API %d", api); 1122981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos status = BAD_VALUE; 1123981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos break; 1124289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1125289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1126981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mBufferHasBeenQueued = false; 1127981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mDequeueBufferCannotBlock = false; 1128981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (mDequeueTimeout < 0) { 1129981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mDequeueBufferCannotBlock = 1130981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mConsumerControlledByApp && producerControlledByApp; 1131127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza } 1132289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1133981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mAllowAllocation = true; 1134981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos VALIDATE_CONSISTENCY(); 1135289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return status; 1136289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 1137289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1138289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::disconnect(int api) { 1139289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 1140ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGV("disconnect: api %d", api); 1141289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1142289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int status = NO_ERROR; 1143289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<IConsumerListener> listener; 1144289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 1145289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 114678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 1147289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1148289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 1149289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // It's not really an error to disconnect after the surface has 1150289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // been abandoned; it should just be a no-op. 1151289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 1152289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1153289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 11541b3a9acb77ee12568fa19740d8eeab165a0dcd98Chong Zhang if (api == BufferQueueCore::CURRENTLY_CONNECTED_API) { 11551b3a9acb77ee12568fa19740d8eeab165a0dcd98Chong Zhang api = mCore->mConnectedApi; 115626bb2b1c0d8f7b05feb40b0e5bf1bb384e1b5f55Chong Zhang // If we're asked to disconnect the currently connected api but 115726bb2b1c0d8f7b05feb40b0e5bf1bb384e1b5f55Chong Zhang // nobody is connected, it's not really an error. 115826bb2b1c0d8f7b05feb40b0e5bf1bb384e1b5f55Chong Zhang if (api == BufferQueueCore::NO_CONNECTED_API) { 115926bb2b1c0d8f7b05feb40b0e5bf1bb384e1b5f55Chong Zhang return NO_ERROR; 116026bb2b1c0d8f7b05feb40b0e5bf1bb384e1b5f55Chong Zhang } 11611b3a9acb77ee12568fa19740d8eeab165a0dcd98Chong Zhang } 11621b3a9acb77ee12568fa19740d8eeab165a0dcd98Chong Zhang 1163289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (api) { 1164289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_EGL: 1165289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CPU: 1166289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_MEDIA: 1167289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CAMERA: 1168289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mConnectedApi == api) { 1169289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->freeAllBuffersLocked(); 1170289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1171289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Remove our death notification callback if we have one 1172f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza if (mCore->mConnectedProducerListener != NULL) { 1173f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza sp<IBinder> token = 1174097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen IInterface::asBinder(mCore->mConnectedProducerListener); 1175289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // This can fail if we're here because of the death 1176289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // notification, but we just ignore it 1177289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza token->unlinkToDeath( 1178289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza static_cast<IBinder::DeathRecipient*>(this)); 1179289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 11803559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos mCore->mSharedBufferSlot = 118123b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos BufferQueueCore::INVALID_BUFFER_SLOT; 1182f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza mCore->mConnectedProducerListener = NULL; 1183289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; 1184399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall mCore->mSidebandStream.clear(); 1185289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 1186289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener = mCore->mConsumerListener; 11874f21a4cc22a94eeb65742fcbb0a8516624474fe5Amith Dsouza } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 1188ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("disconnect: still connected to another API " 1189289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "(cur=%d req=%d)", mCore->mConnectedApi, api); 11909f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status = BAD_VALUE; 1191289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1192289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 1193289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 1194ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("disconnect: unknown API %d", api); 11959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status = BAD_VALUE; 1196289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 1197289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1198289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 1199289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1200289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Call back without lock held 1201289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (listener != NULL) { 1202289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener->onBuffersReleased(); 1203289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1204289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1205289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return status; 1206289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 1207289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1208399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallstatus_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) { 1209afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim sp<IConsumerListener> listener; 1210afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim { // Autolock scope 1211afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim Mutex::Autolock _l(mCore->mMutex); 1212afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim mCore->mSidebandStream = stream; 1213afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim listener = mCore->mConsumerListener; 1214afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim } // Autolock scope 1215afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim 1216afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim if (listener != NULL) { 1217afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim listener->onSidebandStreamChanged(); 1218afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim } 1219399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall return NO_ERROR; 1220399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall} 1221399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall 1222567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballosvoid BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height, 1223567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos PixelFormat format, uint32_t usage) { 122478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour ATRACE_CALL(); 122578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour while (true) { 122678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour size_t newBufferCount = 0; 122778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t allocWidth = 0; 122878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t allocHeight = 0; 12293be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN; 123078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t allocUsage = 0; 123178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour { // Autolock scope 123278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Mutex::Autolock lock(mCore->mMutex); 123378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 123429a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 12359de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza if (!mCore->mAllowAllocation) { 12369de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza BQ_LOGE("allocateBuffers: allocation is not allowed for this " 12379de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza "BufferQueue"); 12389de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza return; 12399de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza } 12409de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 124123b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos newBufferCount = mCore->mFreeSlots.size(); 124223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos if (newBufferCount == 0) { 124378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour return; 124478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 124523b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 124678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocWidth = width > 0 ? width : mCore->mDefaultWidth; 124778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocHeight = height > 0 ? height : mCore->mDefaultHeight; 124878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat; 124978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocUsage = usage | mCore->mConsumerUsageBits; 125029a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 125178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = true; 125278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } // Autolock scope 125378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour 12543be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza Vector<sp<GraphicBuffer>> buffers; 125578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour for (size_t i = 0; i < newBufferCount; ++i) { 125678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour status_t result = NO_ERROR; 125778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 125878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocWidth, allocHeight, allocFormat, allocUsage, &result)); 125978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (result != NO_ERROR) { 126078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format" 126178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour " %u, usage %u)", width, height, format, usage); 126278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Mutex::Autolock lock(mCore->mMutex); 126378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = false; 126478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocatingCondition.broadcast(); 126578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour return; 126678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 126778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour buffers.push_back(graphicBuffer); 126829a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza } 126929a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 127078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour { // Autolock scope 127178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Mutex::Autolock lock(mCore->mMutex); 127278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth; 127378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight; 12743be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza PixelFormat checkFormat = format != 0 ? 12753be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza format : mCore->mDefaultBufferFormat; 127678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t checkUsage = usage | mCore->mConsumerUsageBits; 127778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (checkWidth != allocWidth || checkHeight != allocHeight || 127878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour checkFormat != allocFormat || checkUsage != allocUsage) { 127978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour // Something changed while we released the lock. Retry. 128078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying."); 128178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = false; 128278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocatingCondition.broadcast(); 128378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour continue; 128478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 128529a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 128678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour for (size_t i = 0; i < newBufferCount; ++i) { 128723b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos if (mCore->mFreeSlots.empty()) { 128823b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos BQ_LOGV("allocateBuffers: a slot was occupied while " 128923b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos "allocating. Dropping allocated buffer."); 129078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour continue; 129178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 129223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos auto slot = mCore->mFreeSlots.begin(); 129323b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mCore->clearBufferSlotLocked(*slot); // Clean up the slot first 129423b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mSlots[*slot].mGraphicBuffer = buffers[i]; 129523b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mSlots[*slot].mFence = Fence::NO_FENCE; 12960de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 12970de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza // freeBufferLocked puts this slot on the free slots list. Since 12980de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza // we then attached a buffer, move the slot to free buffer list. 129923b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mCore->mFreeBuffers.push_front(*slot); 13000de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 130123b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", 130223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos *slot); 130387e94cd1d16281051d5241a25035aa1db0b073d8Christopher Ferris 130487e94cd1d16281051d5241a25035aa1db0b073d8Christopher Ferris // Make sure the erase is done after all uses of the slot 130587e94cd1d16281051d5241a25035aa1db0b073d8Christopher Ferris // iterator since it will be invalid after this point. 130687e94cd1d16281051d5241a25035aa1db0b073d8Christopher Ferris mCore->mFreeSlots.erase(slot); 130778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 130829a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 130978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = false; 131078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocatingCondition.broadcast(); 13119e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos VALIDATE_CONSISTENCY(); 131278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } // Autolock scope 131329a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza } 131429a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza} 131529a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 13169de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stozastatus_t BufferQueueProducer::allowAllocation(bool allow) { 13179de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza ATRACE_CALL(); 13189de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza BQ_LOGV("allowAllocation: %s", allow ? "true" : "false"); 13199de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 13209de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza Mutex::Autolock lock(mCore->mMutex); 13219de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza mCore->mAllowAllocation = allow; 13229de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza return NO_ERROR; 13239de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza} 13249de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 1325812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stozastatus_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) { 1326812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza ATRACE_CALL(); 1327812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza BQ_LOGV("setGenerationNumber: %u", generationNumber); 1328812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza 1329812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza Mutex::Autolock lock(mCore->mMutex); 1330812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza mCore->mGenerationNumber = generationNumber; 1331812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza return NO_ERROR; 1332812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza} 1333812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza 1334c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan StozaString8 BufferQueueProducer::getConsumerName() const { 1335c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza ATRACE_CALL(); 1336c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza BQ_LOGV("getConsumerName: %s", mConsumerName.string()); 1337c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza return mConsumerName; 1338c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza} 1339c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza 13407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozauint64_t BufferQueueProducer::getNextFrameNumber() const { 13417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza ATRACE_CALL(); 13427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza 13437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza Mutex::Autolock lock(mCore->mMutex); 13447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza uint64_t nextFrameNumber = mCore->mFrameCounter + 1; 13457dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza return nextFrameNumber; 13467dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza} 13477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza 13483559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballosstatus_t BufferQueueProducer::setSharedBufferMode(bool sharedBufferMode) { 1349ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos ATRACE_CALL(); 13503559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode); 1351ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 1352ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos Mutex::Autolock lock(mCore->mMutex); 13533559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos if (!sharedBufferMode) { 13543559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT; 1355ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 13563559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos mCore->mSharedBufferMode = sharedBufferMode; 1357127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza return NO_ERROR; 1358127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza} 1359127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza 1360ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballosstatus_t BufferQueueProducer::setAutoRefresh(bool autoRefresh) { 1361ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos ATRACE_CALL(); 1362ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos BQ_LOGV("setAutoRefresh: %d", autoRefresh); 1363ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos 1364ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos Mutex::Autolock lock(mCore->mMutex); 1365ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos 1366ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos mCore->mAutoRefresh = autoRefresh; 1367ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos return NO_ERROR; 1368ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos} 1369ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos 1370127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stozastatus_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) { 1371127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza ATRACE_CALL(); 1372127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza BQ_LOGV("setDequeueTimeout: %" PRId64, timeout); 1373ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 1374981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos Mutex::Autolock lock(mCore->mMutex); 1375981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false, 1376981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked(); 1377981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos if (!mCore->adjustAvailableSlotsLocked(delta)) { 1378981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of " 1379981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos "available slots. Delta = %d", delta); 1380981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos return BAD_VALUE; 138123b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos } 138223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos 1383981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mDequeueTimeout = timeout; 1384981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos mCore->mDequeueBufferCannotBlock = false; 13859e314337cdc65b1fbf52060e9a6a4ddf2215c352Pablo Ceballos 1386981066c3a5be3e4775b6537ef32268f7e108c912Pablo Ceballos VALIDATE_CONSISTENCY(); 1387ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos return NO_ERROR; 1388ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos} 1389ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 139050101d02a8eae555887282a5f761fdec57bdaf30Dan Stozastatus_t BufferQueueProducer::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, 13911a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck sp<Fence>* outFence, float outTransformMatrix[16]) { 139250101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza ATRACE_CALL(); 139350101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza BQ_LOGV("getLastQueuedBuffer"); 139450101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza 139550101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza Mutex::Autolock lock(mCore->mMutex); 139650101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) { 139750101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza *outBuffer = nullptr; 139850101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza *outFence = Fence::NO_FENCE; 139950101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza return NO_ERROR; 140050101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza } 140150101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza 140250101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza *outBuffer = mSlots[mCore->mLastQueuedSlot].mGraphicBuffer; 140350101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza *outFence = mLastQueueBufferFence; 140450101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza 14051a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // Currently only SurfaceFlinger internally ever changes 14061a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // GLConsumer's filtering mode, so we just use 'true' here as 14071a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // this is slightly specialized for the current client of this API, 14081a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // which does want filtering. 14091a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck GLConsumer::computeTransformMatrix(outTransformMatrix, 14101a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck mSlots[mCore->mLastQueuedSlot].mGraphicBuffer, mLastQueuedCrop, 14111a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck mLastQueuedTransform, true /* filter */); 14121a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck 141350101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza return NO_ERROR; 141450101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza} 141550101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza 1416289ade165e60b5f71734d30e535f16eb1f4313adDan Stozavoid BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) { 1417289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If we're here, it means that a producer we were connected to died. 1418289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // We're guaranteed that we are still connected to it because we remove 1419289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // this callback upon disconnect. It's therefore safe to read mConnectedApi 1420289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // without synchronization here. 1421289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int api = mCore->mConnectedApi; 1422289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza disconnect(api); 1423289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 1424289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1425eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballosstatus_t BufferQueueProducer::getUniqueId(uint64_t* outId) const { 1426eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos BQ_LOGV("getUniqueId"); 1427eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos 1428eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos *outId = mCore->mUniqueId; 1429eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos return NO_ERROR; 1430eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos} 1431eb7980c224a54f860b7af5ecf30cbc633ae41289Pablo Ceballos 1432289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} // namespace android 1433