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 23289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#define EGL_EGLEXT_PROTOTYPES 24289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 25289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/BufferItem.h> 26289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/BufferQueueCore.h> 27289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/BufferQueueProducer.h> 28289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/IConsumerListener.h> 29289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/IGraphicBufferAlloc.h> 30f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza#include <gui/IProducerListener.h> 31289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 32289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <utils/Log.h> 33289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <utils/Trace.h> 34289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 35289ade165e60b5f71734d30e535f16eb1f4313adDan Stozanamespace android { 36289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 37289ade165e60b5f71734d30e535f16eb1f4313adDan StozaBufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) : 38289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore(core), 39289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots(core->mSlots), 401681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk mConsumerName(), 4199a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner mStickyTransform(0), 428dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mLastQueueBufferFence(Fence::NO_FENCE), 438dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mCallbackMutex(), 448dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mNextCallbackTicket(0), 458dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mCurrentCallbackTicket(0), 468dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mCallbackCondition() {} 47289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 48289ade165e60b5f71734d30e535f16eb1f4313adDan StozaBufferQueueProducer::~BufferQueueProducer() {} 49289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 50289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 51289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 52289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("requestBuffer: slot %d", slot); 53289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 54289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 55289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 56289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("requestBuffer: BufferQueue has been abandoned"); 57289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 58289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 59289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 603e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 61289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)", 623e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 63289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 64289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 65289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("requestBuffer: slot %d is not owned by the producer " 66289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "(state = %d)", slot, mSlots[slot].mBufferState); 67289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 68289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 69289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 70289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mRequestBufferCalled = true; 71289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *buf = mSlots[slot].mGraphicBuffer; 72289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 73289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 74289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 75289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::setBufferCount(int bufferCount) { 76289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 77289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("setBufferCount: count = %d", bufferCount); 78289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 79289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<IConsumerListener> listener; 80289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 81289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 8278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 83289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 84289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 85289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("setBufferCount: BufferQueue has been abandoned"); 86289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 87289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 88289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 893e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) { 90289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("setBufferCount: bufferCount %d too large (max %d)", 913e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS); 92289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 93289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 94289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 95289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // There must be no dequeued buffers when changing the buffer count. 963e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 97289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mSlots[s].mBufferState == BufferSlot::DEQUEUED) { 98289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("setBufferCount: buffer owned by producer"); 999f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 100289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 101289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 102289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 103289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (bufferCount == 0) { 104289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mOverrideMaxBufferCount = 0; 105289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 106289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 107289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 108289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 109289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const int minBufferSlots = mCore->getMinMaxBufferCountLocked(false); 110289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (bufferCount < minBufferSlots) { 111289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("setBufferCount: requested buffer count %d is less than " 112289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "minimum %d", bufferCount, minBufferSlots); 113289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 114289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 115289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 116289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Here we are guaranteed that the producer doesn't have any dequeued 117289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // buffers and will release all of its buffer references. We don't 118289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // clear the queue, however, so that currently queued buffers still 119289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // get displayed. 120289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->freeAllBuffersLocked(); 121289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mOverrideMaxBufferCount = bufferCount; 122289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 123289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener = mCore->mConsumerListener; 124289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 125289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 126289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Call back without lock held 127289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (listener != NULL) { 128289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener->onBuffersReleased(); 129289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 130289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 131289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 132289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 133289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1349f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatus_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller, 1359f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza bool async, int* found, status_t* returnFlags) const { 1369f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza bool tryAgain = true; 1379f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza while (tryAgain) { 1389f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mCore->mIsAbandoned) { 1399f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("%s: BufferQueue has been abandoned", caller); 1409f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_INIT; 1419f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1429f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 1439f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza const int maxBufferCount = mCore->getMaxBufferCountLocked(async); 1449f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (async && mCore->mOverrideMaxBufferCount) { 1459f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // FIXME: Some drivers are manually setting the buffer count 1469f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // (which they shouldn't), so we do this extra test here to 1479f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // handle that case. This is TEMPORARY until we get this fixed. 1489f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mCore->mOverrideMaxBufferCount < maxBufferCount) { 1499f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("%s: async mode is invalid with buffer count override", 1509f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza caller); 1519f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 1529f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1539f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1549f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 1559f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // Free up any buffers that are in slots beyond the max buffer count 1569f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza for (int s = maxBufferCount; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 1579f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza assert(mSlots[s].mBufferState == BufferSlot::FREE); 1589f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mSlots[s].mGraphicBuffer != NULL) { 1599f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->freeBufferLocked(s); 1609f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *returnFlags |= RELEASE_ALL_BUFFERS; 1619f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1629f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1639f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 1649f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // Look for a free buffer to give to the client 1659f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *found = BufferQueueCore::INVALID_BUFFER_SLOT; 1669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int dequeuedCount = 0; 1679f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int acquiredCount = 0; 1689f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza for (int s = 0; s < maxBufferCount; ++s) { 1699f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza switch (mSlots[s].mBufferState) { 1709f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza case BufferSlot::DEQUEUED: 1719f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ++dequeuedCount; 1729f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza break; 1739f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza case BufferSlot::ACQUIRED: 1749f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ++acquiredCount; 1759f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza break; 1769f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza case BufferSlot::FREE: 1779f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // We return the oldest of the free buffers to avoid 1789f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // stalling the producer if possible, since the consumer 1799f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // may still have pending reads of in-flight buffers 1809f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (*found == BufferQueueCore::INVALID_BUFFER_SLOT || 1819f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[s].mFrameNumber < mSlots[*found].mFrameNumber) { 1829f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *found = s; 1839f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1849f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza break; 1859f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza default: 1869f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza break; 1879f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1889f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1899f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 1909f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // Producers are not allowed to dequeue more than one buffer if they 1919f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // did not set a buffer count 1929f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (!mCore->mOverrideMaxBufferCount && dequeuedCount) { 1939f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("%s: can't dequeue multiple buffers without setting the " 1949f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza "buffer count", caller); 1959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return INVALID_OPERATION; 1969f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1979f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 1989f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // See whether a buffer has been queued since the last 1999f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // setBufferCount so we know whether to perform the min undequeued 2009f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // buffers check below 2019f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mCore->mBufferHasBeenQueued) { 2029f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // Make sure the producer is not trying to dequeue more buffers 2039f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // than allowed 2049f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza const int newUndequeuedCount = 2059f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza maxBufferCount - (dequeuedCount + 1); 2069f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza const int minUndequeuedCount = 2079f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->getMinUndequeuedBufferCountLocked(async); 2089f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (newUndequeuedCount < minUndequeuedCount) { 2099f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("%s: min undequeued buffer count (%d) exceeded " 2109f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza "(dequeued=%d undequeued=%d)", 2119f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza caller, minUndequeuedCount, 2129f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza dequeuedCount, newUndequeuedCount); 2139f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return INVALID_OPERATION; 2149f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2159f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2169f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 217ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // If we disconnect and reconnect quickly, we can be in a state where 218ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // our slots are empty but we have many buffers in the queue. This can 219ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // cause us to run out of memory if we outrun the consumer. Wait here if 220ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // it looks like we have too many buffers queued up. 2218f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn bool tooManyBuffers = mCore->mQueue.size() 2228f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn > static_cast<size_t>(maxBufferCount); 223ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (tooManyBuffers) { 2248f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn BQ_LOGV("%s: queue size is %zu, waiting", caller, 225ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza mCore->mQueue.size()); 226ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza } 227ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza 228ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // If no buffer is found, or if the queue has too many buffers 229ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // outstanding, wait for a buffer to be acquired or released, or for the 230ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // max buffer count to change. 231ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) || 232ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza tooManyBuffers; 2339f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (tryAgain) { 2349f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // Return an error if we're in non-blocking mode (producer and 2359f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // consumer are controlled by the application). 2369f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // However, the consumer is allowed to briefly acquire an extra 2379f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // buffer (which could cause us to have to wait here), which is 2389f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // okay, since it is only used to implement an atomic acquire + 2399f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // release (e.g., in GLConsumer::updateTexImage()) 2409f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mCore->mDequeueBufferCannotBlock && 2419f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza (acquiredCount <= mCore->mMaxAcquiredBufferCount)) { 2429f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return WOULD_BLOCK; 2439f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2449f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->mDequeueCondition.wait(mCore->mMutex); 2459f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2469f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } // while (tryAgain) 2479f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 2489f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_ERROR; 2499f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 2509f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 251289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::dequeueBuffer(int *outSlot, 252289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<android::Fence> *outFence, bool async, 253289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza uint32_t width, uint32_t height, uint32_t format, uint32_t usage) { 254289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 255289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 256289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 257289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mConsumerName = mCore->mConsumerName; 258289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 259289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 260289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("dequeueBuffer: async=%s w=%u h=%u format=%#x, usage=%#x", 261289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza async ? "true" : "false", width, height, format, usage); 262289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 263289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if ((width && !height) || (!width && height)) { 264289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height); 265289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 266289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 267289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 268289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status_t returnFlags = NO_ERROR; 269289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLDisplay eglDisplay = EGL_NO_DISPLAY; 270289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; 2719f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza bool attachedByConsumer = false; 272289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 273289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 274289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 27578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 276289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 277289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (format == 0) { 278289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza format = mCore->mDefaultBufferFormat; 279289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 280289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 281289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Enable the usage bits the consumer requested 282289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza usage |= mCore->mConsumerUsageBits; 283289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 2849f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int found; 2859f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async, 2869f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza &found, &returnFlags); 2879f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (status != NO_ERROR) { 2889f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return status; 2899f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 290289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 291289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // This should not happen 292289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 293289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: no available buffer slots"); 294289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return -EBUSY; 295289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 296289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 297289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outSlot = found; 298289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_BUFFER_INDEX(found); 299289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 3009f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza attachedByConsumer = mSlots[found].mAttachedByConsumer; 3019f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 302289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const bool useDefaultSize = !width && !height; 303289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (useDefaultSize) { 304289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza width = mCore->mDefaultWidth; 305289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza height = mCore->mDefaultHeight; 306289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 307289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 308289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mBufferState = BufferSlot::DEQUEUED; 309289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 310289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer); 311289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if ((buffer == NULL) || 312289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza (static_cast<uint32_t>(buffer->width) != width) || 313289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza (static_cast<uint32_t>(buffer->height) != height) || 314289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza (static_cast<uint32_t>(buffer->format) != format) || 315289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ((static_cast<uint32_t>(buffer->usage) & usage) != usage)) 316289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { 317289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mAcquireCalled = false; 318289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mGraphicBuffer = NULL; 319289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mRequestBufferCalled = false; 320289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglDisplay = EGL_NO_DISPLAY; 321289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglFence = EGL_NO_SYNC_KHR; 322289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mFence = Fence::NO_FENCE; 323289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 324289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza returnFlags |= BUFFER_NEEDS_REALLOCATION; 325289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 326289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 327289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (CC_UNLIKELY(mSlots[found].mFence == NULL)) { 328289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: about to return a NULL fence - " 329289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "slot=%d w=%d h=%d format=%u", 330289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza found, buffer->width, buffer->height, buffer->format); 331289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 332289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 333289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglDisplay = mSlots[found].mEglDisplay; 334289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglFence = mSlots[found].mEglFence; 335289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outFence = mSlots[found].mFence; 336289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglFence = EGL_NO_SYNC_KHR; 337289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mFence = Fence::NO_FENCE; 338289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 339289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 340289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (returnFlags & BUFFER_NEEDS_REALLOCATION) { 341289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status_t error; 34229a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot); 343289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 344289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza width, height, format, usage, &error)); 345289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (graphicBuffer == NULL) { 346289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: createGraphicBuffer failed"); 347289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return error; 348289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 349289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 350289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 351289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 352289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 353289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 354289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned"); 355289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 356289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 357289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 3589f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mFrameNumber = UINT32_MAX; 359289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[*outSlot].mGraphicBuffer = graphicBuffer; 360289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 361289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 362289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 3639f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (attachedByConsumer) { 3649f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza returnFlags |= BUFFER_NEEDS_REALLOCATION; 3659f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 3669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 367289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (eglFence != EGL_NO_SYNC_KHR) { 368289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0, 369289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1000000000); 370289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If something goes wrong, log the error, but return the buffer without 371289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // synchronizing access to it. It's too late at this point to abort the 372289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // dequeue operation. 373289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (result == EGL_FALSE) { 374289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: error %#x waiting for fence", 375289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglGetError()); 376289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 377289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: timeout waiting for fence"); 378289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 379289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglDestroySyncKHR(eglDisplay, eglFence); 380289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 381289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 3828f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x", 3838f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn *outSlot, 384289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[*outSlot].mFrameNumber, 385289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[*outSlot].mGraphicBuffer->handle, returnFlags); 386289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 387289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return returnFlags; 388289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 389289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 3909f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatus_t BufferQueueProducer::detachBuffer(int slot) { 3919f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_CALL(); 3929f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_BUFFER_INDEX(slot); 3939f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGV("detachBuffer(P): slot %d", slot); 3949f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza Mutex::Autolock lock(mCore->mMutex); 3959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 3969f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mCore->mIsAbandoned) { 3979f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("detachBuffer(P): BufferQueue has been abandoned"); 3989f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_INIT; 3999f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 4009f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4019f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 4029f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("detachBuffer(P): slot index %d out of range [0, %d)", 4039f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 4049f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 4059f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 4069f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("detachBuffer(P): slot %d is not owned by the producer " 4079f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza "(state = %d)", slot, mSlots[slot].mBufferState); 4089f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 4099f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } else if (!mSlots[slot].mRequestBufferCalled) { 4109f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("detachBuffer(P): buffer in slot %d has not been requested", 4119f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza slot); 4129f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 4139f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 4149f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4159f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->freeBufferLocked(slot); 4169f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->mDequeueCondition.broadcast(); 4179f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4189f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_ERROR; 4199f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 4209f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 421d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stozastatus_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, 422d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza sp<Fence>* outFence) { 423d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza ATRACE_CALL(); 424d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 425d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if (outBuffer == NULL) { 426d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza BQ_LOGE("detachNextBuffer: outBuffer must not be NULL"); 427d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return BAD_VALUE; 428d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } else if (outFence == NULL) { 429d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza BQ_LOGE("detachNextBuffer: outFence must not be NULL"); 430d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return BAD_VALUE; 431d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 432d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 433d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza Mutex::Autolock lock(mCore->mMutex); 43478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 435d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 436d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if (mCore->mIsAbandoned) { 437d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned"); 438d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return NO_INIT; 439d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 440d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 441d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza // Find the oldest valid slot 442d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza int found = BufferQueueCore::INVALID_BUFFER_SLOT; 443d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 444d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if (mSlots[s].mBufferState == BufferSlot::FREE && 445d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mSlots[s].mGraphicBuffer != NULL) { 446d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT || 447d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) { 448d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza found = s; 449d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 450d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 451d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 452d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 453d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 454d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return NO_MEMORY; 455d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 456d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 457d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza BQ_LOGV("detachNextBuffer detached slot %d", found); 458d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 459d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza *outBuffer = mSlots[found].mGraphicBuffer; 460d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza *outFence = mSlots[found].mFence; 461d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mCore->freeBufferLocked(found); 462d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 463d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return NO_ERROR; 464d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza} 465d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 4669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatus_t BufferQueueProducer::attachBuffer(int* outSlot, 4679f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza const sp<android::GraphicBuffer>& buffer) { 4689f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_CALL(); 4699f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4709f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (outSlot == NULL) { 4719f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("attachBuffer(P): outSlot must not be NULL"); 4729f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 4739f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } else if (buffer == NULL) { 4749f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("attachBuffer(P): cannot attach NULL buffer"); 4759f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 4769f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 4779f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4789f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza Mutex::Autolock lock(mCore->mMutex); 47978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 4809f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4819f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status_t returnFlags = NO_ERROR; 4829f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int found; 4839f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // TODO: Should we provide an async flag to attachBuffer? It seems 4849f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // unlikely that buffers which we are attaching to a BufferQueue will 4859f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // be asynchronous (droppable), but it may not be impossible. 4869f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status_t status = waitForFreeSlotThenRelock("attachBuffer(P)", false, 4879f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza &found, &returnFlags); 4889f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (status != NO_ERROR) { 4899f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return status; 4909f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 4919f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4929f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // This should not happen 4939f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 4949f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("attachBuffer(P): no available buffer slots"); 4959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return -EBUSY; 4969f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 4979f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4989f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *outSlot = found; 4999f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_BUFFER_INDEX(*outSlot); 5009f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGV("attachBuffer(P): returning slot %d flags=%#x", 5019f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *outSlot, returnFlags); 5029f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 5039f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mGraphicBuffer = buffer; 5049f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mBufferState = BufferSlot::DEQUEUED; 5059f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR; 5069f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mFence = Fence::NO_FENCE; 5072443c7903c6910b57bcc615a4bf2e60068c15dbdDan Stoza mSlots[*outSlot].mRequestBufferCalled = true; 5089f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 5099f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return returnFlags; 5109f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 5119f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 512289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::queueBuffer(int slot, 513289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const QueueBufferInput &input, QueueBufferOutput *output) { 514289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 515289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_BUFFER_INDEX(slot); 516289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 517289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int64_t timestamp; 518289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza bool isAutoTimestamp; 519289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Rect crop; 520289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int scalingMode; 521289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza uint32_t transform; 5221681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk uint32_t stickyTransform; 523289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza bool async; 524289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<Fence> fence; 525289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza input.deflate(×tamp, &isAutoTimestamp, &crop, &scalingMode, &transform, 5261681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk &async, &fence, &stickyTransform); 527289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 528289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (fence == NULL) { 529289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: fence is NULL"); 530de288fe2d43adfa1b2243ae534faaf832bf50491Jesse Hall return BAD_VALUE; 531289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 532289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 533289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (scalingMode) { 534289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_FREEZE: 535289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 536289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 537289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: 538289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 539289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 540289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode); 5419f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 542289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 543289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 5448dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza sp<IConsumerListener> frameAvailableListener; 5458dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza sp<IConsumerListener> frameReplacedListener; 5468dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza int callbackTicket = 0; 5478dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza BufferItem item; 548289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 549289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 550289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 551289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 552289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: BufferQueue has been abandoned"); 553289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 554289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 555289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 556289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const int maxBufferCount = mCore->getMaxBufferCountLocked(async); 557289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (async && mCore->mOverrideMaxBufferCount) { 558289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // FIXME: Some drivers are manually setting the buffer count 559289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // (which they shouldn't), so we do this extra test here to 560289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // handle that case. This is TEMPORARY until we get this fixed. 561289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mOverrideMaxBufferCount < maxBufferCount) { 562289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: async mode is invalid with " 563289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "buffer count override"); 564289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 565289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 566289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 567289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 568289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (slot < 0 || slot >= maxBufferCount) { 569289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)", 570289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza slot, maxBufferCount); 5719f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 572289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 573289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot %d is not owned by the producer " 574289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "(state = %d)", slot, mSlots[slot].mBufferState); 5759f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 576289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (!mSlots[slot].mRequestBufferCalled) { 577289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot %d was queued without requesting " 578289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "a buffer", slot); 5799f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 580289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 581289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 5828f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 5838f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn " crop=[%d,%d,%d,%d] transform=%#x scale=%s", 584289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza slot, mCore->mFrameCounter + 1, timestamp, 585289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza crop.left, crop.top, crop.right, crop.bottom, 586289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza transform, BufferItem::scalingModeName(scalingMode)); 587289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 588289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer); 589289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight()); 590289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Rect croppedRect; 591289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza crop.intersect(bufferRect, &croppedRect); 592289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (croppedRect != crop) { 593289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: crop rect is not contained within the " 594289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "buffer in slot %d", slot); 5959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 596289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 597289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 598289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFence = fence; 599289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mBufferState = BufferSlot::QUEUED; 600289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ++mCore->mFrameCounter; 601289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFrameNumber = mCore->mFrameCounter; 602289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 603289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mAcquireCalled = mSlots[slot].mAcquireCalled; 604289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mGraphicBuffer = mSlots[slot].mGraphicBuffer; 605289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mCrop = crop; 606289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mTransform = transform & ~NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; 607289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mTransformToDisplayInverse = 608289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza bool(transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY); 609289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mScalingMode = scalingMode; 610289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mTimestamp = timestamp; 611289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mIsAutoTimestamp = isAutoTimestamp; 612289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mFrameNumber = mCore->mFrameCounter; 613289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mSlot = slot; 614289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mFence = fence; 615289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mIsDroppable = mCore->mDequeueBufferCannotBlock || async; 616289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 6171681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk mStickyTransform = stickyTransform; 6181681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk 619289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mQueue.empty()) { 620289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // When the queue is empty, we can ignore mDequeueBufferCannotBlock 621289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // and simply queue this buffer 622289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mQueue.push_back(item); 6238dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameAvailableListener = mCore->mConsumerListener; 624289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else { 625289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // When the queue is not empty, we need to look at the front buffer 626289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // state to see if we need to replace it 627289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin()); 628289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (front->mIsDroppable) { 629289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If the front queued buffer is still being tracked, we first 630289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // mark it as freed 631289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->stillTracking(front)) { 632289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[front->mSlot].mBufferState = BufferSlot::FREE; 633289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Reset the frame number of the freed buffer so that it is 634289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // the first in line to be dequeued again 635289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[front->mSlot].mFrameNumber = 0; 636289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 637289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Overwrite the droppable buffer with the incoming one 638289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *front = item; 6398dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameReplacedListener = mCore->mConsumerListener; 640289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else { 641289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mQueue.push_back(item); 6428dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameAvailableListener = mCore->mConsumerListener; 643289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 644289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 645289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 646289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mBufferHasBeenQueued = true; 647289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 648289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 649289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, 650289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mTransformHint, mCore->mQueue.size()); 651289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 652289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); 6538dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza 6548dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // Take a ticket for the callback functions 6558dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza callbackTicket = mNextCallbackTicket++; 656289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 657289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 65899a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner // Wait without lock held 65999a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) { 66099a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner // Waiting here allows for two full buffers to be queued but not a 66199a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner // third. In the event that frames take varying time, this makes a 66299a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner // small trade-off in favor of latency rather than throughput. 66399a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner mLastQueueBufferFence->waitForever("Throttling EGL Production"); 66499a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner mLastQueueBufferFence = fence; 66599a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner } 66699a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner 6678dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // Don't send the GraphicBuffer through the callback, and don't send 6688dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // the slot number, since the consumer shouldn't need it 6698dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza item.mGraphicBuffer.clear(); 6708dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza item.mSlot = BufferItem::INVALID_BUFFER_SLOT; 6718dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza 6728dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // Call back without the main BufferQueue lock held, but with the callback 6738dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // lock held so we can ensure that callbacks occur in order 6748dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza { 6758dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza Mutex::Autolock lock(mCallbackMutex); 6768dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza while (callbackTicket != mCurrentCallbackTicket) { 6778dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mCallbackCondition.wait(mCallbackMutex); 6788dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza } 6798dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza 6808dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza if (frameAvailableListener != NULL) { 6818dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameAvailableListener->onFrameAvailable(item); 6828dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza } else if (frameReplacedListener != NULL) { 6838dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameReplacedListener->onFrameReplaced(item); 6848dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza } 6858dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza 6868dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza ++mCurrentCallbackTicket; 6878dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mCallbackCondition.broadcast(); 688289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 689289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 690289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 691289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 692289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 693289ade165e60b5f71734d30e535f16eb1f4313adDan Stozavoid BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) { 694289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 695289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("cancelBuffer: slot %d", slot); 696289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 697289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 698289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 699289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: BufferQueue has been abandoned"); 700289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return; 701289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 702289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 7033e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 704289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", 7053e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 706289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return; 707289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 708289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " 709289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "(state = %d)", slot, mSlots[slot].mBufferState); 710289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return; 711289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (fence == NULL) { 712289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: fence is NULL"); 713289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return; 714289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 715289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 716289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mBufferState = BufferSlot::FREE; 717289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFrameNumber = 0; 718289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFence = fence; 719289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 720289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 721289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 722289ade165e60b5f71734d30e535f16eb1f4313adDan Stozaint BufferQueueProducer::query(int what, int *outValue) { 723289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 724289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 725289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 726289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (outValue == NULL) { 727289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("query: outValue was NULL"); 728289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 729289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 730289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 731289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 732289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("query: BufferQueue has been abandoned"); 733289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 734289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 735289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 736289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int value; 737289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (what) { 738289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_WIDTH: 739289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->mDefaultWidth; 740289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 741289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_HEIGHT: 742289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->mDefaultHeight; 743289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 744289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_FORMAT: 745289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->mDefaultBufferFormat; 746289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 747289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 748289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->getMinUndequeuedBufferCountLocked(false); 749289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 7501681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk case NATIVE_WINDOW_STICKY_TRANSFORM: 7511681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk value = static_cast<int>(mStickyTransform); 7521681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk break; 753289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: 754289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = (mCore->mQueue.size() > 1); 755289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 756289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_CONSUMER_USAGE_BITS: 757289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->mConsumerUsageBits; 758289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 759289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 760289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 761289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 762289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 763289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("query: %d? %d", what, value); 764289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outValue = value; 765289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 766289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 767289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 768f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stozastatus_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, 769289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int api, bool producerControlledByApp, QueueBufferOutput *output) { 770289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 771289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 772289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mConsumerName = mCore->mConsumerName; 773289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("connect(P): api=%d producerControlledByApp=%s", api, 774289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza producerControlledByApp ? "true" : "false"); 775289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 776ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (mCore->mIsAbandoned) { 777ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza BQ_LOGE("connect(P): BufferQueue has been abandoned"); 778ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza return NO_INIT; 779ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza } 780289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 781ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (mCore->mConsumerListener == NULL) { 782ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza BQ_LOGE("connect(P): BufferQueue has no consumer"); 783ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza return NO_INIT; 784ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza } 785289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 786ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (output == NULL) { 787ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza BQ_LOGE("connect(P): output was NULL"); 788ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza return BAD_VALUE; 789ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza } 790289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 791ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 792ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza BQ_LOGE("connect(P): already connected (cur=%d req=%d)", 793ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza mCore->mConnectedApi, api); 794ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza return BAD_VALUE; 795289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 796289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 797289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int status = NO_ERROR; 798289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (api) { 799289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_EGL: 800289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CPU: 801289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_MEDIA: 802289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CAMERA: 803289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConnectedApi = api; 804289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, 805289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mTransformHint, mCore->mQueue.size()); 806289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 807289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Set up a death notification so that we can disconnect 808289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // automatically if the remote producer dies 809f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza if (listener != NULL && 810f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza listener->asBinder()->remoteBinder() != NULL) { 811f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza status = listener->asBinder()->linkToDeath( 812289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza static_cast<IBinder::DeathRecipient*>(this)); 813f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza if (status != NO_ERROR) { 814289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("connect(P): linkToDeath failed: %s (%d)", 815289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza strerror(-status), status); 816289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 817289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 818f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza mCore->mConnectedProducerListener = listener; 819289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 820289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 821289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("connect(P): unknown API %d", api); 822289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status = BAD_VALUE; 823289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 824289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 825289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 826289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mBufferHasBeenQueued = false; 827289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueBufferCannotBlock = 828289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConsumerControlledByApp && producerControlledByApp; 829289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 830289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return status; 831289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 832289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 833289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::disconnect(int api) { 834289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 835289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("disconnect(P): api %d", api); 836289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 837289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int status = NO_ERROR; 838289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<IConsumerListener> listener; 839289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 840289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 84178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 842289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 843289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 844289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // It's not really an error to disconnect after the surface has 845289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // been abandoned; it should just be a no-op. 846289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 847289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 848289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 849289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (api) { 850289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_EGL: 851289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CPU: 852289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_MEDIA: 853289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CAMERA: 854289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mConnectedApi == api) { 855289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->freeAllBuffersLocked(); 856289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 857289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Remove our death notification callback if we have one 858f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza if (mCore->mConnectedProducerListener != NULL) { 859f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza sp<IBinder> token = 860f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza mCore->mConnectedProducerListener->asBinder(); 861289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // This can fail if we're here because of the death 862289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // notification, but we just ignore it 863289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza token->unlinkToDeath( 864289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza static_cast<IBinder::DeathRecipient*>(this)); 865289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 866f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza mCore->mConnectedProducerListener = NULL; 867289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; 868399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall mCore->mSidebandStream.clear(); 869289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 870289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener = mCore->mConsumerListener; 87145e2fc22261cb8ecac4901b4425bcb7352c71174Michael Lentine } else { 87245e2fc22261cb8ecac4901b4425bcb7352c71174Michael Lentine BQ_LOGE("disconnect(P): connected to another API " 873289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "(cur=%d req=%d)", mCore->mConnectedApi, api); 8749f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status = BAD_VALUE; 875289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 876289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 877289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 878289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("disconnect(P): unknown API %d", api); 8799f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status = BAD_VALUE; 880289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 881289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 882289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 883289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 884289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Call back without lock held 885289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (listener != NULL) { 886289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener->onBuffersReleased(); 887289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 888289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 889289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return status; 890289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 891289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 892399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallstatus_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) { 893afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim sp<IConsumerListener> listener; 894afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim { // Autolock scope 895afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim Mutex::Autolock _l(mCore->mMutex); 896afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim mCore->mSidebandStream = stream; 897afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim listener = mCore->mConsumerListener; 898afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim } // Autolock scope 899afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim 900afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim if (listener != NULL) { 901afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim listener->onSidebandStreamChanged(); 902afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim } 903399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall return NO_ERROR; 904399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall} 905399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall 90629a3e90879fd96404c971e7187cd0e05927bbce0Dan Stozavoid BufferQueueProducer::allocateBuffers(bool async, uint32_t width, 90729a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza uint32_t height, uint32_t format, uint32_t usage) { 90878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour ATRACE_CALL(); 90978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour while (true) { 91078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Vector<int> freeSlots; 91178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour size_t newBufferCount = 0; 91278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t allocWidth = 0; 91378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t allocHeight = 0; 91478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t allocFormat = 0; 91578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t allocUsage = 0; 91678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour { // Autolock scope 91778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Mutex::Autolock lock(mCore->mMutex); 91878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 91929a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 92078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour int currentBufferCount = 0; 92178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) { 92278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (mSlots[slot].mGraphicBuffer != NULL) { 92378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour ++currentBufferCount; 92478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } else { 92578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (mSlots[slot].mBufferState != BufferSlot::FREE) { 92678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGE("allocateBuffers: slot %d without buffer is not FREE", 92778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour slot); 92878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour continue; 92978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 93029a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 93111f14871db607718090ae6aa2e5dee3f490b8830Antoine Labour freeSlots.push_back(slot); 93278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 93329a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza } 93429a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 93578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour int maxBufferCount = mCore->getMaxBufferCountLocked(async); 93678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGV("allocateBuffers: allocating from %d buffers up to %d buffers", 93778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour currentBufferCount, maxBufferCount); 93878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (maxBufferCount <= currentBufferCount) 93978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour return; 94078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour newBufferCount = maxBufferCount - currentBufferCount; 94178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (freeSlots.size() < newBufferCount) { 94278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGE("allocateBuffers: ran out of free slots"); 94378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour return; 94478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 94578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocWidth = width > 0 ? width : mCore->mDefaultWidth; 94678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocHeight = height > 0 ? height : mCore->mDefaultHeight; 94778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat; 94878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocUsage = usage | mCore->mConsumerUsageBits; 94929a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 95078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = true; 95178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } // Autolock scope 95278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour 95378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Vector<sp<GraphicBuffer> > buffers; 95478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour for (size_t i = 0; i < newBufferCount; ++i) { 95578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour status_t result = NO_ERROR; 95678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 95778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocWidth, allocHeight, allocFormat, allocUsage, &result)); 95878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (result != NO_ERROR) { 95978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format" 96078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour " %u, usage %u)", width, height, format, usage); 96178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Mutex::Autolock lock(mCore->mMutex); 96278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = false; 96378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocatingCondition.broadcast(); 96478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour return; 96578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 96678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour buffers.push_back(graphicBuffer); 96729a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza } 96829a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 96978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour { // Autolock scope 97078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Mutex::Autolock lock(mCore->mMutex); 97178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth; 97278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight; 97378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t checkFormat = format != 0 ? format : mCore->mDefaultBufferFormat; 97478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t checkUsage = usage | mCore->mConsumerUsageBits; 97578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (checkWidth != allocWidth || checkHeight != allocHeight || 97678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour checkFormat != allocFormat || checkUsage != allocUsage) { 97778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour // Something changed while we released the lock. Retry. 97878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying."); 97978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = false; 98078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocatingCondition.broadcast(); 98178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour continue; 98278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 98329a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 98478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour for (size_t i = 0; i < newBufferCount; ++i) { 98578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour int slot = freeSlots[i]; 98678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (mSlots[slot].mBufferState != BufferSlot::FREE) { 98778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour // A consumer allocated the FREE slot with attachBuffer. Discard the buffer we 98878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour // allocated. 98978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGV("allocateBuffers: slot %d was acquired while allocating. " 99078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour "Dropping allocated buffer.", slot); 99178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour continue; 99278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 99378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->freeBufferLocked(slot); // Clean up the slot first 99478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mSlots[slot].mGraphicBuffer = buffers[i]; 99578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mSlots[slot].mFrameNumber = 0; 99678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mSlots[slot].mFence = Fence::NO_FENCE; 99778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", slot); 99878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 99929a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 100078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = false; 100178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocatingCondition.broadcast(); 100278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } // Autolock scope 100329a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza } 100429a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza} 100529a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 1006289ade165e60b5f71734d30e535f16eb1f4313adDan Stozavoid BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) { 1007289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If we're here, it means that a producer we were connected to died. 1008289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // We're guaranteed that we are still connected to it because we remove 1009289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // this callback upon disconnect. It's therefore safe to read mConnectedApi 1010289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // without synchronization here. 1011289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int api = mCore->mConnectedApi; 1012289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza disconnect(api); 1013289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 1014289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1015289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} // namespace android 1016