BufferQueueProducer.cpp revision 78014f32da6d0ebf52fb34ebb7663863000520a0
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(), 411681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk mStickyTransform(0) {} 42289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 43289ade165e60b5f71734d30e535f16eb1f4313adDan StozaBufferQueueProducer::~BufferQueueProducer() {} 44289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 45289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 46289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 47289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("requestBuffer: slot %d", slot); 48289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 49289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 50289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 51289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("requestBuffer: BufferQueue has been abandoned"); 52289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 53289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 54289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 553e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 56289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)", 573e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 58289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 59289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 60289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("requestBuffer: slot %d is not owned by the producer " 61289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "(state = %d)", slot, mSlots[slot].mBufferState); 62289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 63289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 64289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 65289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mRequestBufferCalled = true; 66289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *buf = mSlots[slot].mGraphicBuffer; 67289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 68289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 69289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 70289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::setBufferCount(int bufferCount) { 71289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 72289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("setBufferCount: count = %d", bufferCount); 73289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 74289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<IConsumerListener> listener; 75289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 76289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 7778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 78289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 79289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 80289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("setBufferCount: BufferQueue has been abandoned"); 81289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 82289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 83289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 843e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) { 85289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("setBufferCount: bufferCount %d too large (max %d)", 863e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS); 87289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 88289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 89289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 90289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // There must be no dequeued buffers when changing the buffer count. 913e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 92289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mSlots[s].mBufferState == BufferSlot::DEQUEUED) { 93289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("setBufferCount: buffer owned by producer"); 949f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 95289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 96289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 97289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 98289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (bufferCount == 0) { 99289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mOverrideMaxBufferCount = 0; 100289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 101289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 102289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 103289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 104289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const int minBufferSlots = mCore->getMinMaxBufferCountLocked(false); 105289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (bufferCount < minBufferSlots) { 106289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("setBufferCount: requested buffer count %d is less than " 107289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "minimum %d", bufferCount, minBufferSlots); 108289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 109289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 110289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 111289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Here we are guaranteed that the producer doesn't have any dequeued 112289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // buffers and will release all of its buffer references. We don't 113289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // clear the queue, however, so that currently queued buffers still 114289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // get displayed. 115289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->freeAllBuffersLocked(); 116289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mOverrideMaxBufferCount = bufferCount; 117289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 118289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener = mCore->mConsumerListener; 119289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 120289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 121289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Call back without lock held 122289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (listener != NULL) { 123289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener->onBuffersReleased(); 124289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 125289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 126289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 127289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 128289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1299f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatus_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller, 1309f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza bool async, int* found, status_t* returnFlags) const { 1319f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza bool tryAgain = true; 1329f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza while (tryAgain) { 1339f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mCore->mIsAbandoned) { 1349f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("%s: BufferQueue has been abandoned", caller); 1359f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_INIT; 1369f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1379f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 1389f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza const int maxBufferCount = mCore->getMaxBufferCountLocked(async); 1399f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (async && mCore->mOverrideMaxBufferCount) { 1409f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // FIXME: Some drivers are manually setting the buffer count 1419f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // (which they shouldn't), so we do this extra test here to 1429f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // handle that case. This is TEMPORARY until we get this fixed. 1439f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mCore->mOverrideMaxBufferCount < maxBufferCount) { 1449f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("%s: async mode is invalid with buffer count override", 1459f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza caller); 1469f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 1479f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1489f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1499f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 1509f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // Free up any buffers that are in slots beyond the max buffer count 1519f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza for (int s = maxBufferCount; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 1529f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza assert(mSlots[s].mBufferState == BufferSlot::FREE); 1539f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mSlots[s].mGraphicBuffer != NULL) { 1549f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->freeBufferLocked(s); 1559f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *returnFlags |= RELEASE_ALL_BUFFERS; 1569f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1579f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1589f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 1599f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // Look for a free buffer to give to the client 1609f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *found = BufferQueueCore::INVALID_BUFFER_SLOT; 1619f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int dequeuedCount = 0; 1629f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int acquiredCount = 0; 1639f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza for (int s = 0; s < maxBufferCount; ++s) { 1649f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza switch (mSlots[s].mBufferState) { 1659f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza case BufferSlot::DEQUEUED: 1669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ++dequeuedCount; 1679f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza break; 1689f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza case BufferSlot::ACQUIRED: 1699f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ++acquiredCount; 1709f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza break; 1719f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza case BufferSlot::FREE: 1729f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // We return the oldest of the free buffers to avoid 1739f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // stalling the producer if possible, since the consumer 1749f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // may still have pending reads of in-flight buffers 1759f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (*found == BufferQueueCore::INVALID_BUFFER_SLOT || 1769f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[s].mFrameNumber < mSlots[*found].mFrameNumber) { 1779f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *found = s; 1789f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1799f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza break; 1809f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza default: 1819f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza break; 1829f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1839f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1849f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 1859f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // Producers are not allowed to dequeue more than one buffer if they 1869f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // did not set a buffer count 1879f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (!mCore->mOverrideMaxBufferCount && dequeuedCount) { 1889f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("%s: can't dequeue multiple buffers without setting the " 1899f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza "buffer count", caller); 1909f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return INVALID_OPERATION; 1919f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1929f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 1939f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // See whether a buffer has been queued since the last 1949f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // setBufferCount so we know whether to perform the min undequeued 1959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // buffers check below 1969f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mCore->mBufferHasBeenQueued) { 1979f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // Make sure the producer is not trying to dequeue more buffers 1989f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // than allowed 1999f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza const int newUndequeuedCount = 2009f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza maxBufferCount - (dequeuedCount + 1); 2019f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza const int minUndequeuedCount = 2029f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->getMinUndequeuedBufferCountLocked(async); 2039f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (newUndequeuedCount < minUndequeuedCount) { 2049f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("%s: min undequeued buffer count (%d) exceeded " 2059f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza "(dequeued=%d undequeued=%d)", 2069f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza caller, minUndequeuedCount, 2079f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza dequeuedCount, newUndequeuedCount); 2089f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return INVALID_OPERATION; 2099f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2109f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2119f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 212ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // If we disconnect and reconnect quickly, we can be in a state where 213ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // our slots are empty but we have many buffers in the queue. This can 214ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // cause us to run out of memory if we outrun the consumer. Wait here if 215ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // it looks like we have too many buffers queued up. 2168f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn bool tooManyBuffers = mCore->mQueue.size() 2178f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn > static_cast<size_t>(maxBufferCount); 218ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (tooManyBuffers) { 2198f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn BQ_LOGV("%s: queue size is %zu, waiting", caller, 220ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza mCore->mQueue.size()); 221ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza } 222ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza 223ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // If no buffer is found, or if the queue has too many buffers 224ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // outstanding, wait for a buffer to be acquired or released, or for the 225ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // max buffer count to change. 226ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) || 227ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza tooManyBuffers; 2289f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (tryAgain) { 2299f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // Return an error if we're in non-blocking mode (producer and 2309f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // consumer are controlled by the application). 2319f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // However, the consumer is allowed to briefly acquire an extra 2329f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // buffer (which could cause us to have to wait here), which is 2339f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // okay, since it is only used to implement an atomic acquire + 2349f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // release (e.g., in GLConsumer::updateTexImage()) 2359f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mCore->mDequeueBufferCannotBlock && 2369f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza (acquiredCount <= mCore->mMaxAcquiredBufferCount)) { 2379f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return WOULD_BLOCK; 2389f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2399f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->mDequeueCondition.wait(mCore->mMutex); 2409f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2419f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } // while (tryAgain) 2429f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 2439f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_ERROR; 2449f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 2459f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 246289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::dequeueBuffer(int *outSlot, 247289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<android::Fence> *outFence, bool async, 248289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza uint32_t width, uint32_t height, uint32_t format, uint32_t usage) { 249289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 250289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 251289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 252289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mConsumerName = mCore->mConsumerName; 253289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 254289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 255289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("dequeueBuffer: async=%s w=%u h=%u format=%#x, usage=%#x", 256289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza async ? "true" : "false", width, height, format, usage); 257289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 258289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if ((width && !height) || (!width && height)) { 259289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height); 260289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 261289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 262289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 263289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status_t returnFlags = NO_ERROR; 264289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLDisplay eglDisplay = EGL_NO_DISPLAY; 265289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; 2669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza bool attachedByConsumer = false; 267289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 268289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 269289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 27078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 271289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 272289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (format == 0) { 273289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza format = mCore->mDefaultBufferFormat; 274289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 275289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 276289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Enable the usage bits the consumer requested 277289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza usage |= mCore->mConsumerUsageBits; 278289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 2799f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int found; 2809f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async, 2819f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza &found, &returnFlags); 2829f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (status != NO_ERROR) { 2839f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return status; 2849f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 285289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 286289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // This should not happen 287289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 288289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: no available buffer slots"); 289289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return -EBUSY; 290289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 291289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 292289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outSlot = found; 293289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_BUFFER_INDEX(found); 294289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 2959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza attachedByConsumer = mSlots[found].mAttachedByConsumer; 2969f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 297289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const bool useDefaultSize = !width && !height; 298289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (useDefaultSize) { 299289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza width = mCore->mDefaultWidth; 300289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza height = mCore->mDefaultHeight; 301289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 302289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 303289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mBufferState = BufferSlot::DEQUEUED; 304289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 305289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer); 306289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if ((buffer == NULL) || 307289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza (static_cast<uint32_t>(buffer->width) != width) || 308289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza (static_cast<uint32_t>(buffer->height) != height) || 309289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza (static_cast<uint32_t>(buffer->format) != format) || 310289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ((static_cast<uint32_t>(buffer->usage) & usage) != usage)) 311289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { 312289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mAcquireCalled = false; 313289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mGraphicBuffer = NULL; 314289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mRequestBufferCalled = false; 315289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglDisplay = EGL_NO_DISPLAY; 316289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglFence = EGL_NO_SYNC_KHR; 317289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mFence = Fence::NO_FENCE; 318289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 319289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza returnFlags |= BUFFER_NEEDS_REALLOCATION; 320289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 321289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 322289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (CC_UNLIKELY(mSlots[found].mFence == NULL)) { 323289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: about to return a NULL fence - " 324289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "slot=%d w=%d h=%d format=%u", 325289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza found, buffer->width, buffer->height, buffer->format); 326289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 327289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 328289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglDisplay = mSlots[found].mEglDisplay; 329289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglFence = mSlots[found].mEglFence; 330289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outFence = mSlots[found].mFence; 331289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglFence = EGL_NO_SYNC_KHR; 332289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mFence = Fence::NO_FENCE; 333289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 334289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 335289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (returnFlags & BUFFER_NEEDS_REALLOCATION) { 336289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status_t error; 33729a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot); 338289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 339289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza width, height, format, usage, &error)); 340289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (graphicBuffer == NULL) { 341289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: createGraphicBuffer failed"); 342289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return error; 343289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 344289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 345289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 346289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 347289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 348289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 349289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned"); 350289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 351289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 352289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 3539f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mFrameNumber = UINT32_MAX; 354289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[*outSlot].mGraphicBuffer = graphicBuffer; 355289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 356289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 357289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 3589f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (attachedByConsumer) { 3599f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza returnFlags |= BUFFER_NEEDS_REALLOCATION; 3609f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 3619f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 362289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (eglFence != EGL_NO_SYNC_KHR) { 363289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0, 364289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1000000000); 365289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If something goes wrong, log the error, but return the buffer without 366289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // synchronizing access to it. It's too late at this point to abort the 367289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // dequeue operation. 368289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (result == EGL_FALSE) { 369289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: error %#x waiting for fence", 370289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglGetError()); 371289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 372289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: timeout waiting for fence"); 373289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 374289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglDestroySyncKHR(eglDisplay, eglFence); 375289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 376289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 3778f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x", 3788f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn *outSlot, 379289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[*outSlot].mFrameNumber, 380289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[*outSlot].mGraphicBuffer->handle, returnFlags); 381289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 382289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return returnFlags; 383289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 384289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 3859f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatus_t BufferQueueProducer::detachBuffer(int slot) { 3869f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_CALL(); 3879f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_BUFFER_INDEX(slot); 3889f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGV("detachBuffer(P): slot %d", slot); 3899f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza Mutex::Autolock lock(mCore->mMutex); 3909f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 3919f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mCore->mIsAbandoned) { 3929f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("detachBuffer(P): BufferQueue has been abandoned"); 3939f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_INIT; 3949f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 3959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 3969f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 3979f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("detachBuffer(P): slot index %d out of range [0, %d)", 3989f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 3999f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 4009f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 4019f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("detachBuffer(P): slot %d is not owned by the producer " 4029f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza "(state = %d)", slot, mSlots[slot].mBufferState); 4039f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 4049f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } else if (!mSlots[slot].mRequestBufferCalled) { 4059f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("detachBuffer(P): buffer in slot %d has not been requested", 4069f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza slot); 4079f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 4089f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 4099f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4109f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->freeBufferLocked(slot); 4119f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->mDequeueCondition.broadcast(); 4129f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4139f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_ERROR; 4149f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 4159f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 416d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stozastatus_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, 417d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza sp<Fence>* outFence) { 418d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza ATRACE_CALL(); 419d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 420d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if (outBuffer == NULL) { 421d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza BQ_LOGE("detachNextBuffer: outBuffer must not be NULL"); 422d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return BAD_VALUE; 423d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } else if (outFence == NULL) { 424d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza BQ_LOGE("detachNextBuffer: outFence must not be NULL"); 425d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return BAD_VALUE; 426d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 427d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 428d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza Mutex::Autolock lock(mCore->mMutex); 42978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 430d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 431d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if (mCore->mIsAbandoned) { 432d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned"); 433d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return NO_INIT; 434d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 435d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 436d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza // Find the oldest valid slot 437d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza int found = BufferQueueCore::INVALID_BUFFER_SLOT; 438d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 439d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if (mSlots[s].mBufferState == BufferSlot::FREE && 440d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mSlots[s].mGraphicBuffer != NULL) { 441d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT || 442d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) { 443d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza found = s; 444d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 445d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 446d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 447d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 448d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 449d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return NO_MEMORY; 450d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 451d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 452d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza BQ_LOGV("detachNextBuffer detached slot %d", found); 453d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 454d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza *outBuffer = mSlots[found].mGraphicBuffer; 455d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza *outFence = mSlots[found].mFence; 456d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mCore->freeBufferLocked(found); 457d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 458d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return NO_ERROR; 459d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza} 460d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 4619f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatus_t BufferQueueProducer::attachBuffer(int* outSlot, 4629f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza const sp<android::GraphicBuffer>& buffer) { 4639f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_CALL(); 4649f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4659f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (outSlot == NULL) { 4669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("attachBuffer(P): outSlot must not be NULL"); 4679f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 4689f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } else if (buffer == NULL) { 4699f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("attachBuffer(P): cannot attach NULL buffer"); 4709f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 4719f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 4729f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4739f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza Mutex::Autolock lock(mCore->mMutex); 47478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 4759f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4769f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status_t returnFlags = NO_ERROR; 4779f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int found; 4789f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // TODO: Should we provide an async flag to attachBuffer? It seems 4799f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // unlikely that buffers which we are attaching to a BufferQueue will 4809f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // be asynchronous (droppable), but it may not be impossible. 4819f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status_t status = waitForFreeSlotThenRelock("attachBuffer(P)", false, 4829f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza &found, &returnFlags); 4839f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (status != NO_ERROR) { 4849f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return status; 4859f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 4869f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4879f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // This should not happen 4889f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 4899f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("attachBuffer(P): no available buffer slots"); 4909f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return -EBUSY; 4919f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 4929f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4939f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *outSlot = found; 4949f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_BUFFER_INDEX(*outSlot); 4959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGV("attachBuffer(P): returning slot %d flags=%#x", 4969f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *outSlot, returnFlags); 4979f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4989f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mGraphicBuffer = buffer; 4999f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mBufferState = BufferSlot::DEQUEUED; 5009f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR; 5019f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mFence = Fence::NO_FENCE; 5022443c7903c6910b57bcc615a4bf2e60068c15dbdDan Stoza mSlots[*outSlot].mRequestBufferCalled = true; 5039f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 5049f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return returnFlags; 5059f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 5069f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 507289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::queueBuffer(int slot, 508289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const QueueBufferInput &input, QueueBufferOutput *output) { 509289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 510289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_BUFFER_INDEX(slot); 511289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 512289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int64_t timestamp; 513289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza bool isAutoTimestamp; 514289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Rect crop; 515289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int scalingMode; 516289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza uint32_t transform; 5171681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk uint32_t stickyTransform; 518289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza bool async; 519289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<Fence> fence; 520289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza input.deflate(×tamp, &isAutoTimestamp, &crop, &scalingMode, &transform, 5211681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk &async, &fence, &stickyTransform); 522289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 523289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (fence == NULL) { 524289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: fence is NULL"); 525289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 526289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 527289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 528289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (scalingMode) { 529289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_FREEZE: 530289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 531289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 532289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: 533289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 534289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 535289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode); 5369f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 537289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 538289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 539289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<IConsumerListener> listener; 540289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 541289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 542289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 543289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 544289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: BufferQueue has been abandoned"); 545289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 546289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 547289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 548289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const int maxBufferCount = mCore->getMaxBufferCountLocked(async); 549289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (async && mCore->mOverrideMaxBufferCount) { 550289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // FIXME: Some drivers are manually setting the buffer count 551289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // (which they shouldn't), so we do this extra test here to 552289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // handle that case. This is TEMPORARY until we get this fixed. 553289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mOverrideMaxBufferCount < maxBufferCount) { 554289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: async mode is invalid with " 555289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "buffer count override"); 556289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 557289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 558289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 559289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 560289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (slot < 0 || slot >= maxBufferCount) { 561289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)", 562289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza slot, maxBufferCount); 5639f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 564289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 565289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot %d is not owned by the producer " 566289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "(state = %d)", slot, mSlots[slot].mBufferState); 5679f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 568289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (!mSlots[slot].mRequestBufferCalled) { 569289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot %d was queued without requesting " 570289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "a buffer", slot); 5719f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 572289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 573289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 5748f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 5758f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn " crop=[%d,%d,%d,%d] transform=%#x scale=%s", 576289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza slot, mCore->mFrameCounter + 1, timestamp, 577289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza crop.left, crop.top, crop.right, crop.bottom, 578289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza transform, BufferItem::scalingModeName(scalingMode)); 579289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 580289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer); 581289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight()); 582289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Rect croppedRect; 583289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza crop.intersect(bufferRect, &croppedRect); 584289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (croppedRect != crop) { 585289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: crop rect is not contained within the " 586289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "buffer in slot %d", slot); 5879f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 588289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 589289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 590289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFence = fence; 591289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mBufferState = BufferSlot::QUEUED; 592289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ++mCore->mFrameCounter; 593289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFrameNumber = mCore->mFrameCounter; 594289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 595289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BufferItem item; 596289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mAcquireCalled = mSlots[slot].mAcquireCalled; 597289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mGraphicBuffer = mSlots[slot].mGraphicBuffer; 598289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mCrop = crop; 599289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mTransform = transform & ~NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; 600289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mTransformToDisplayInverse = 601289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza bool(transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY); 602289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mScalingMode = scalingMode; 603289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mTimestamp = timestamp; 604289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mIsAutoTimestamp = isAutoTimestamp; 605289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mFrameNumber = mCore->mFrameCounter; 606289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mSlot = slot; 607289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mFence = fence; 608289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mIsDroppable = mCore->mDequeueBufferCannotBlock || async; 609289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 6101681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk mStickyTransform = stickyTransform; 6111681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk 612289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mQueue.empty()) { 613289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // When the queue is empty, we can ignore mDequeueBufferCannotBlock 614289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // and simply queue this buffer 615289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mQueue.push_back(item); 616289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener = mCore->mConsumerListener; 617289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else { 618289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // When the queue is not empty, we need to look at the front buffer 619289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // state to see if we need to replace it 620289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin()); 621289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (front->mIsDroppable) { 622289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If the front queued buffer is still being tracked, we first 623289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // mark it as freed 624289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->stillTracking(front)) { 625289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[front->mSlot].mBufferState = BufferSlot::FREE; 626289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Reset the frame number of the freed buffer so that it is 627289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // the first in line to be dequeued again 628289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[front->mSlot].mFrameNumber = 0; 629289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 630289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Overwrite the droppable buffer with the incoming one 631289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *front = item; 632289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else { 633289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mQueue.push_back(item); 634289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener = mCore->mConsumerListener; 635289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 636289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 637289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 638289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mBufferHasBeenQueued = true; 639289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 640289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 641289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, 642289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mTransformHint, mCore->mQueue.size()); 643289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 644289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); 645289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 646289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 647289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Call back without lock held 648289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (listener != NULL) { 649289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener->onFrameAvailable(); 650289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 651289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 652289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 653289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 654289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 655289ade165e60b5f71734d30e535f16eb1f4313adDan Stozavoid BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) { 656289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 657289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("cancelBuffer: slot %d", slot); 658289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 659289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 660289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 661289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: BufferQueue has been abandoned"); 662289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return; 663289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 664289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 6653e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 666289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", 6673e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 668289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return; 669289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 670289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " 671289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "(state = %d)", slot, mSlots[slot].mBufferState); 672289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return; 673289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (fence == NULL) { 674289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: fence is NULL"); 675289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return; 676289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 677289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 678289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mBufferState = BufferSlot::FREE; 679289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFrameNumber = 0; 680289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFence = fence; 681289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 682289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 683289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 684289ade165e60b5f71734d30e535f16eb1f4313adDan Stozaint BufferQueueProducer::query(int what, int *outValue) { 685289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 686289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 687289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 688289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (outValue == NULL) { 689289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("query: outValue was NULL"); 690289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 691289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 692289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 693289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 694289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("query: BufferQueue has been abandoned"); 695289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 696289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 697289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 698289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int value; 699289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (what) { 700289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_WIDTH: 701289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->mDefaultWidth; 702289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 703289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_HEIGHT: 704289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->mDefaultHeight; 705289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 706289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_FORMAT: 707289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->mDefaultBufferFormat; 708289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 709289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 710289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->getMinUndequeuedBufferCountLocked(false); 711289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 7121681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk case NATIVE_WINDOW_STICKY_TRANSFORM: 7131681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk value = static_cast<int>(mStickyTransform); 7141681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk break; 715289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: 716289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = (mCore->mQueue.size() > 1); 717289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 718289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_CONSUMER_USAGE_BITS: 719289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->mConsumerUsageBits; 720289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 721289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 722289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 723289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 724289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 725289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("query: %d? %d", what, value); 726289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outValue = value; 727289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 728289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 729289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 730f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stozastatus_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, 731289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int api, bool producerControlledByApp, QueueBufferOutput *output) { 732289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 733289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 734289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mConsumerName = mCore->mConsumerName; 735289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("connect(P): api=%d producerControlledByApp=%s", api, 736289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza producerControlledByApp ? "true" : "false"); 737289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 738ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (mCore->mIsAbandoned) { 739ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza BQ_LOGE("connect(P): BufferQueue has been abandoned"); 740ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza return NO_INIT; 741ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza } 742289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 743ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (mCore->mConsumerListener == NULL) { 744ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza BQ_LOGE("connect(P): BufferQueue has no consumer"); 745ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza return NO_INIT; 746ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza } 747289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 748ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (output == NULL) { 749ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza BQ_LOGE("connect(P): output was NULL"); 750ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza return BAD_VALUE; 751ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza } 752289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 753ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 754ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza BQ_LOGE("connect(P): already connected (cur=%d req=%d)", 755ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza mCore->mConnectedApi, api); 756ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza return BAD_VALUE; 757289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 758289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 759289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int status = NO_ERROR; 760289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (api) { 761289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_EGL: 762289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CPU: 763289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_MEDIA: 764289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CAMERA: 765289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConnectedApi = api; 766289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, 767289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mTransformHint, mCore->mQueue.size()); 768289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 769289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Set up a death notification so that we can disconnect 770289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // automatically if the remote producer dies 771f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza if (listener != NULL && 772f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza listener->asBinder()->remoteBinder() != NULL) { 773f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza status = listener->asBinder()->linkToDeath( 774289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza static_cast<IBinder::DeathRecipient*>(this)); 775f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza if (status != NO_ERROR) { 776289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("connect(P): linkToDeath failed: %s (%d)", 777289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza strerror(-status), status); 778289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 779289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 780f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza mCore->mConnectedProducerListener = listener; 781289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 782289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 783289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("connect(P): unknown API %d", api); 784289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status = BAD_VALUE; 785289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 786289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 787289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 788289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mBufferHasBeenQueued = false; 789289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueBufferCannotBlock = 790289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConsumerControlledByApp && producerControlledByApp; 791289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 792289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return status; 793289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 794289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 795289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::disconnect(int api) { 796289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 797289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("disconnect(P): api %d", api); 798289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 799289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int status = NO_ERROR; 800289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<IConsumerListener> listener; 801289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 802289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 80378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 804289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 805289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 806289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // It's not really an error to disconnect after the surface has 807289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // been abandoned; it should just be a no-op. 808289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 809289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 810289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 811289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (api) { 812289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_EGL: 813289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CPU: 814289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_MEDIA: 815289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CAMERA: 816289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mConnectedApi == api) { 817289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->freeAllBuffersLocked(); 818289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 819289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Remove our death notification callback if we have one 820f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza if (mCore->mConnectedProducerListener != NULL) { 821f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza sp<IBinder> token = 822f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza mCore->mConnectedProducerListener->asBinder(); 823289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // This can fail if we're here because of the death 824289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // notification, but we just ignore it 825289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza token->unlinkToDeath( 826289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza static_cast<IBinder::DeathRecipient*>(this)); 827289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 828f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza mCore->mConnectedProducerListener = NULL; 829289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; 830399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall mCore->mSidebandStream.clear(); 831289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 832289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener = mCore->mConsumerListener; 833289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else { 834289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("disconnect(P): connected to another API " 835289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "(cur=%d req=%d)", mCore->mConnectedApi, api); 8369f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status = BAD_VALUE; 837289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 838289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 839289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 840289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("disconnect(P): unknown API %d", api); 8419f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status = BAD_VALUE; 842289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 843289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 844289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 845289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 846289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Call back without lock held 847289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (listener != NULL) { 848289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener->onBuffersReleased(); 849289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 850289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 851289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return status; 852289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 853289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 854399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallstatus_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) { 855afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim sp<IConsumerListener> listener; 856afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim { // Autolock scope 857afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim Mutex::Autolock _l(mCore->mMutex); 858afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim mCore->mSidebandStream = stream; 859afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim listener = mCore->mConsumerListener; 860afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim } // Autolock scope 861afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim 862afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim if (listener != NULL) { 863afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim listener->onSidebandStreamChanged(); 864afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim } 865399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall return NO_ERROR; 866399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall} 867399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall 86829a3e90879fd96404c971e7187cd0e05927bbce0Dan Stozavoid BufferQueueProducer::allocateBuffers(bool async, uint32_t width, 86929a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza uint32_t height, uint32_t format, uint32_t usage) { 87078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour ATRACE_CALL(); 87178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour while (true) { 87278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Vector<int> freeSlots; 87378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour size_t newBufferCount = 0; 87478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t allocWidth = 0; 87578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t allocHeight = 0; 87678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t allocFormat = 0; 87778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t allocUsage = 0; 87878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour { // Autolock scope 87978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Mutex::Autolock lock(mCore->mMutex); 88078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 88129a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 88278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour int currentBufferCount = 0; 88378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) { 88478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (mSlots[slot].mGraphicBuffer != NULL) { 88578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour ++currentBufferCount; 88678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } else { 88778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (mSlots[slot].mBufferState != BufferSlot::FREE) { 88878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGE("allocateBuffers: slot %d without buffer is not FREE", 88978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour slot); 89078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour continue; 89178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 89229a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 89378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour freeSlots.push_front(slot); 89478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 89529a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza } 89629a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 89778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour int maxBufferCount = mCore->getMaxBufferCountLocked(async); 89878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGV("allocateBuffers: allocating from %d buffers up to %d buffers", 89978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour currentBufferCount, maxBufferCount); 90078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (maxBufferCount <= currentBufferCount) 90178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour return; 90278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour newBufferCount = maxBufferCount - currentBufferCount; 90378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (freeSlots.size() < newBufferCount) { 90478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGE("allocateBuffers: ran out of free slots"); 90578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour return; 90678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 90778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocWidth = width > 0 ? width : mCore->mDefaultWidth; 90878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocHeight = height > 0 ? height : mCore->mDefaultHeight; 90978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat; 91078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocUsage = usage | mCore->mConsumerUsageBits; 91129a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 91278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = true; 91378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } // Autolock scope 91478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour 91578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Vector<sp<GraphicBuffer> > buffers; 91678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour for (size_t i = 0; i < newBufferCount; ++i) { 91778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour status_t result = NO_ERROR; 91878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 91978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocWidth, allocHeight, allocFormat, allocUsage, &result)); 92078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (result != NO_ERROR) { 92178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format" 92278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour " %u, usage %u)", width, height, format, usage); 92378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Mutex::Autolock lock(mCore->mMutex); 92478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = false; 92578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocatingCondition.broadcast(); 92678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour return; 92778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 92878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour buffers.push_back(graphicBuffer); 92929a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza } 93029a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 93178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour { // Autolock scope 93278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Mutex::Autolock lock(mCore->mMutex); 93378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth; 93478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight; 93578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t checkFormat = format != 0 ? format : mCore->mDefaultBufferFormat; 93678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t checkUsage = usage | mCore->mConsumerUsageBits; 93778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (checkWidth != allocWidth || checkHeight != allocHeight || 93878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour checkFormat != allocFormat || checkUsage != allocUsage) { 93978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour // Something changed while we released the lock. Retry. 94078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying."); 94178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = false; 94278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocatingCondition.broadcast(); 94378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour continue; 94478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 94529a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 94678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour for (size_t i = 0; i < newBufferCount; ++i) { 94778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour int slot = freeSlots[i]; 94878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (mSlots[slot].mBufferState != BufferSlot::FREE) { 94978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour // A consumer allocated the FREE slot with attachBuffer. Discard the buffer we 95078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour // allocated. 95178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGV("allocateBuffers: slot %d was acquired while allocating. " 95278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour "Dropping allocated buffer.", slot); 95378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour continue; 95478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 95578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->freeBufferLocked(slot); // Clean up the slot first 95678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mSlots[slot].mGraphicBuffer = buffers[i]; 95778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mSlots[slot].mFrameNumber = 0; 95878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mSlots[slot].mFence = Fence::NO_FENCE; 95978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", slot); 96078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 96129a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 96278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = false; 96378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocatingCondition.broadcast(); 96478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } // Autolock scope 96529a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza } 96629a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza} 96729a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 968289ade165e60b5f71734d30e535f16eb1f4313adDan Stozavoid BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) { 969289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If we're here, it means that a producer we were connected to died. 970289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // We're guaranteed that we are still connected to it because we remove 971289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // this callback upon disconnect. It's therefore safe to read mConnectedApi 972289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // without synchronization here. 973289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int api = mCore->mConnectedApi; 974289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza disconnect(api); 975289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 976289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 977289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} // namespace android 978