BufferQueueProducer.cpp revision ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584
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 60583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 61583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos BQ_LOGE("requestBuffer: BufferQueue has no connected producer"); 62583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 63583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 64583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 653e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 66289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)", 673e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 68289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 69ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } else if (!mSlots[slot].mBufferState.isDequeued()) { 70289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("requestBuffer: slot %d is not owned by the producer " 71ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos "(state = %s)", slot, mSlots[slot].mBufferState.string()); 72289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 73289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 74289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 75289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mRequestBufferCalled = true; 76289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *buf = mSlots[slot].mGraphicBuffer; 77289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 78289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 79289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 80fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballosstatus_t BufferQueueProducer::setMaxDequeuedBufferCount( 81fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos int maxDequeuedBuffers) { 82fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos ATRACE_CALL(); 83fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos BQ_LOGV("setMaxDequeuedBufferCount: maxDequeuedBuffers = %d", 84fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos maxDequeuedBuffers); 85fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 86fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos sp<IConsumerListener> listener; 87fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos { // Autolock scope 88fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos Mutex::Autolock lock(mCore->mMutex); 89fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos mCore->waitWhileAllocatingLocked(); 90fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 91fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if (mCore->mIsAbandoned) { 92fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue has been " 93fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos "abandoned"); 94fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return NO_INIT; 95fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 96fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 97fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos // There must be no dequeued buffers when changing the buffer count. 98fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 99ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mSlots[s].mBufferState.isDequeued()) { 100fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos BQ_LOGE("setMaxDequeuedBufferCount: buffer owned by producer"); 101fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return BAD_VALUE; 102fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 103fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 104fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 105567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos int bufferCount = mCore->getMinUndequeuedBufferCountLocked(); 106fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos bufferCount += maxDequeuedBuffers; 107fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 108fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) { 109fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos BQ_LOGE("setMaxDequeuedBufferCount: bufferCount %d too large " 110fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos "(max %d)", bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS); 111fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return BAD_VALUE; 112fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 113fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 114567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos const int minBufferSlots = mCore->getMinMaxBufferCountLocked(); 115fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if (bufferCount < minBufferSlots) { 116fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos BQ_LOGE("setMaxDequeuedBufferCount: requested buffer count %d is " 117fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos "less than minimum %d", bufferCount, minBufferSlots); 118fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return BAD_VALUE; 119fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 120fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 12119e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos if (bufferCount > mCore->mMaxBufferCount) { 12219e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos BQ_LOGE("setMaxDequeuedBufferCount: %d dequeued buffers would " 123567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos "exceed the maxBufferCount (%d) (maxAcquired %d async %d " 124567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos "mDequeuedBufferCannotBlock %d)", maxDequeuedBuffers, 125567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos mCore->mMaxBufferCount, mCore->mMaxAcquiredBufferCount, 126567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos mCore->mAsyncMode, mCore->mDequeueBufferCannotBlock); 12719e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos return BAD_VALUE; 12819e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos } 12919e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos 130fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos // Here we are guaranteed that the producer doesn't have any dequeued 131fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos // buffers and will release all of its buffer references. We don't 132fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos // clear the queue, however, so that currently queued buffers still 133fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos // get displayed. 134fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos mCore->freeAllBuffersLocked(); 135fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers; 136fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos mCore->mDequeueCondition.broadcast(); 137fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos listener = mCore->mConsumerListener; 138fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } // Autolock scope 139fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 140fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos // Call back without lock held 141fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if (listener != NULL) { 142fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos listener->onBuffersReleased(); 143fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 144fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 145fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return NO_ERROR; 146fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos} 147fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 148fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballosstatus_t BufferQueueProducer::setAsyncMode(bool async) { 149fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos ATRACE_CALL(); 150fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos BQ_LOGV("setAsyncMode: async = %d", async); 151fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 152fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos sp<IConsumerListener> listener; 153fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos { // Autolock scope 154fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos Mutex::Autolock lock(mCore->mMutex); 155fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos mCore->waitWhileAllocatingLocked(); 156fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 157fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if (mCore->mIsAbandoned) { 158fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos BQ_LOGE("setAsyncMode: BufferQueue has been abandoned"); 159fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return NO_INIT; 160fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 161fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 16219e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos if ((mCore->mMaxAcquiredBufferCount + mCore->mMaxDequeuedBufferCount + 163567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos (async || mCore->mDequeueBufferCannotBlock ? 1 : 0)) > 164567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos mCore->mMaxBufferCount) { 16519e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos BQ_LOGE("setAsyncMode(%d): this call would cause the " 16619e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos "maxBufferCount (%d) to be exceeded (maxAcquired %d " 167567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos "maxDequeued %d mDequeueBufferCannotBlock %d)", async, 168567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos mCore->mMaxBufferCount, mCore->mMaxAcquiredBufferCount, 169567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos mCore->mMaxDequeuedBufferCount, 170567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos mCore->mDequeueBufferCannotBlock); 17119e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos return BAD_VALUE; 17219e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos } 17319e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos 174fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos mCore->mAsyncMode = async; 175fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos mCore->mDequeueCondition.broadcast(); 176fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos listener = mCore->mConsumerListener; 177fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } // Autolock scope 178fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 179fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos // Call back without lock held 180fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if (listener != NULL) { 181fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos listener->onBuffersReleased(); 182fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos } 183fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos return NO_ERROR; 184fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos} 185fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos 1869f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatus_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller, 187567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos int* found, status_t* returnFlags) const { 1889f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza bool tryAgain = true; 1899f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza while (tryAgain) { 1909f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mCore->mIsAbandoned) { 1919f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza BQ_LOGE("%s: BufferQueue has been abandoned", caller); 1929f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_INIT; 1939f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 1949f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 195567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos const int maxBufferCount = mCore->getMaxBufferCountLocked(); 1969f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 1979f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // Free up any buffers that are in slots beyond the max buffer count 1989f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza for (int s = maxBufferCount; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 199ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos assert(mSlots[s].mBufferState.isFree()); 2009f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mSlots[s].mGraphicBuffer != NULL) { 2019f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->freeBufferLocked(s); 2029f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *returnFlags |= RELEASE_ALL_BUFFERS; 2039f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2049f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2059f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 2069f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int dequeuedCount = 0; 2079f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int acquiredCount = 0; 2089f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza for (int s = 0; s < maxBufferCount; ++s) { 209ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mSlots[s].mBufferState.isDequeued()) { 210ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos ++dequeuedCount; 211ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 212ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mSlots[s].mBufferState.isAcquired()) { 213ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos ++acquiredCount; 2149f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2159f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2169f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 217e5b755a045f4203fdd989047441259893c6fbe2dPablo Ceballos // Producers are not allowed to dequeue more than 218e5b755a045f4203fdd989047441259893c6fbe2dPablo Ceballos // mMaxDequeuedBufferCount buffers. 219e5b755a045f4203fdd989047441259893c6fbe2dPablo Ceballos // This check is only done if a buffer has already been queued 220e5b755a045f4203fdd989047441259893c6fbe2dPablo Ceballos if (mCore->mBufferHasBeenQueued && 221e5b755a045f4203fdd989047441259893c6fbe2dPablo Ceballos dequeuedCount >= mCore->mMaxDequeuedBufferCount) { 222e5b755a045f4203fdd989047441259893c6fbe2dPablo Ceballos BQ_LOGE("%s: attempting to exceed the max dequeued buffer count " 223e5b755a045f4203fdd989047441259893c6fbe2dPablo Ceballos "(%d)", caller, mCore->mMaxDequeuedBufferCount); 2249f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return INVALID_OPERATION; 2259f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2269f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 2270de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza *found = BufferQueueCore::INVALID_BUFFER_SLOT; 2280de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 229ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // If we disconnect and reconnect quickly, we can be in a state where 230ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // our slots are empty but we have many buffers in the queue. This can 231ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // cause us to run out of memory if we outrun the consumer. Wait here if 232ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // it looks like we have too many buffers queued up. 2338f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn bool tooManyBuffers = mCore->mQueue.size() 2348f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn > static_cast<size_t>(maxBufferCount); 235ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (tooManyBuffers) { 2368f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn BQ_LOGV("%s: queue size is %zu, waiting", caller, 237ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza mCore->mQueue.size()); 2380de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza } else { 239ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // If in single buffer mode and a shared buffer exists, always 240ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // return it. 241ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mCore->mSingleBufferMode && mCore->mSingleBufferSlot != 242ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BufferQueueCore::INVALID_BUFFER_SLOT) { 243ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos *found = mCore->mSingleBufferSlot; 244ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } else if (!mCore->mFreeBuffers.empty()) { 2450de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza auto slot = mCore->mFreeBuffers.begin(); 2460de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza *found = *slot; 2470de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza mCore->mFreeBuffers.erase(slot); 2489de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza } else if (mCore->mAllowAllocation && !mCore->mFreeSlots.empty()) { 2490de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza auto slot = mCore->mFreeSlots.begin(); 2500de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza // Only return free slots up to the max buffer count 2510de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza if (*slot < maxBufferCount) { 2520de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza *found = *slot; 2530de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza mCore->mFreeSlots.erase(slot); 2540de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza } 2550de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza } 256ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza } 257ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza 258ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // If no buffer is found, or if the queue has too many buffers 259ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // outstanding, wait for a buffer to be acquired or released, or for the 260ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza // max buffer count to change. 261ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) || 262ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza tooManyBuffers; 2639f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (tryAgain) { 2649f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // Return an error if we're in non-blocking mode (producer and 2659f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // consumer are controlled by the application). 2669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // However, the consumer is allowed to briefly acquire an extra 2679f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // buffer (which could cause us to have to wait here), which is 2689f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // okay, since it is only used to implement an atomic acquire + 2699f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // release (e.g., in GLConsumer::updateTexImage()) 270fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos if ((mCore->mDequeueBufferCannotBlock || mCore->mAsyncMode) && 2719f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza (acquiredCount <= mCore->mMaxAcquiredBufferCount)) { 2729f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return WOULD_BLOCK; 2739f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2749f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->mDequeueCondition.wait(mCore->mMutex); 2759f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 2769f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } // while (tryAgain) 2779f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 2789f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_ERROR; 2799f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 2809f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 281289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::dequeueBuffer(int *outSlot, 282567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos sp<android::Fence> *outFence, uint32_t width, uint32_t height, 283567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos PixelFormat format, uint32_t usage) { 284289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 285289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 286289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 287289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mConsumerName = mCore->mConsumerName; 288583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 289583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mIsAbandoned) { 290583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned"); 291583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 292583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 293583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 294583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 295583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos BQ_LOGE("dequeueBuffer: BufferQueue has no connected producer"); 296583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 297583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 298289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 299289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 300567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos BQ_LOGV("dequeueBuffer: w=%u h=%u format=%#x, usage=%#x", width, height, 301567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos format, usage); 302289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 303289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if ((width && !height) || (!width && height)) { 304289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height); 305289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 306289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 307289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 308289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status_t returnFlags = NO_ERROR; 309289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLDisplay eglDisplay = EGL_NO_DISPLAY; 310289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; 3119f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza bool attachedByConsumer = false; 312289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 313289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 314289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 31578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 316289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 317289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (format == 0) { 318289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza format = mCore->mDefaultBufferFormat; 319289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 320289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 321289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Enable the usage bits the consumer requested 322289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza usage |= mCore->mConsumerUsageBits; 323289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 3249de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza const bool useDefaultSize = !width && !height; 3259de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza if (useDefaultSize) { 3269de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza width = mCore->mDefaultWidth; 3279de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza height = mCore->mDefaultHeight; 3289f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 329289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 3309de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza int found = BufferItem::INVALID_BUFFER_SLOT; 3319de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza while (found == BufferItem::INVALID_BUFFER_SLOT) { 332567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos status_t status = waitForFreeSlotThenRelock("dequeueBuffer", &found, 333567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos &returnFlags); 3349de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza if (status != NO_ERROR) { 3359de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza return status; 3369de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza } 3379de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 3389de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza // This should not happen 3399de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 3409de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza BQ_LOGE("dequeueBuffer: no available buffer slots"); 3419de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza return -EBUSY; 3429de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza } 3439de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 3449de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer); 3459de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 3469de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza // If we are not allowed to allocate new buffers, 3479de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza // waitForFreeSlotThenRelock must have returned a slot containing a 3489de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza // buffer. If this buffer would require reallocation to meet the 3499de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza // requested attributes, we free it and attempt to get another one. 3509de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza if (!mCore->mAllowAllocation) { 3519de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza if (buffer->needsReallocation(width, height, format, usage)) { 352ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mCore->mSingleBufferMode && 353ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mSingleBufferSlot == found) { 354ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("dequeueBuffer: cannot re-allocate a shared" 355ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos "buffer"); 356ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos return BAD_VALUE; 357ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 358ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 3599de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza mCore->freeBufferLocked(found); 3609de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza found = BufferItem::INVALID_BUFFER_SLOT; 3619de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza continue; 3629de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza } 3639de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza } 364289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 365289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 366289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outSlot = found; 367289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_BUFFER_INDEX(found); 368289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 3699f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza attachedByConsumer = mSlots[found].mAttachedByConsumer; 3709f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 371ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[found].mBufferState.dequeue(); 372ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 373ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // If single buffer mode has just been enabled, cache the slot of the 374ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // first buffer that is dequeued and mark it as the shared buffer. 375ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mCore->mSingleBufferMode && mCore->mSingleBufferSlot == 376ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BufferQueueCore::INVALID_BUFFER_SLOT) { 377ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mSingleBufferSlot = found; 378ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[found].mBufferState.mShared = true; 379ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 380289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 381289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer); 382289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if ((buffer == NULL) || 3839de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza buffer->needsReallocation(width, height, format, usage)) 384289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { 385289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mAcquireCalled = false; 386289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mGraphicBuffer = NULL; 387289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mRequestBufferCalled = false; 388289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglDisplay = EGL_NO_DISPLAY; 389289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglFence = EGL_NO_SYNC_KHR; 390289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mFence = Fence::NO_FENCE; 3914afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza mCore->mBufferAge = 0; 392ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mIsAllocating = true; 393289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 394289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza returnFlags |= BUFFER_NEEDS_REALLOCATION; 3954afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza } else { 3964afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza // We add 1 because that will be the frame number when this buffer 3974afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza // is queued 3984afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza mCore->mBufferAge = 3994afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber; 400289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 401289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 402800b41ab8486b9d885124071659c774f6c1856e2Dan Stoza BQ_LOGV("dequeueBuffer: setting buffer age to %" PRIu64, 403800b41ab8486b9d885124071659c774f6c1856e2Dan Stoza mCore->mBufferAge); 4044afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza 405289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (CC_UNLIKELY(mSlots[found].mFence == NULL)) { 406289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: about to return a NULL fence - " 407289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "slot=%d w=%d h=%d format=%u", 408289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza found, buffer->width, buffer->height, buffer->format); 409289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 410289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 411289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglDisplay = mSlots[found].mEglDisplay; 412289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglFence = mSlots[found].mEglFence; 413289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outFence = mSlots[found].mFence; 414289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglFence = EGL_NO_SYNC_KHR; 415289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mFence = Fence::NO_FENCE; 4160de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 4170de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza mCore->validateConsistencyLocked(); 418289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 419289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 420289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (returnFlags & BUFFER_NEEDS_REALLOCATION) { 421289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status_t error; 42229a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot); 423289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 4243be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza width, height, format, usage, &error)); 425289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 426289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 427289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 428ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (graphicBuffer != NULL && !mCore->mIsAbandoned) { 429ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos graphicBuffer->setGenerationNumber(mCore->mGenerationNumber); 430ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[*outSlot].mGraphicBuffer = graphicBuffer; 431ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 432ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 433ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mIsAllocating = false; 434ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mIsAllocatingCondition.broadcast(); 435ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 436ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (graphicBuffer == NULL) { 437ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("dequeueBuffer: createGraphicBuffer failed"); 438ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos return error; 439ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 440ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 441289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 442289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned"); 443289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 444289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 445289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 446289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 447289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 4489f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (attachedByConsumer) { 4499f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza returnFlags |= BUFFER_NEEDS_REALLOCATION; 4509f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 4519f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 452289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (eglFence != EGL_NO_SYNC_KHR) { 453289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0, 454289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1000000000); 455289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If something goes wrong, log the error, but return the buffer without 456289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // synchronizing access to it. It's too late at this point to abort the 457289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // dequeue operation. 458289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (result == EGL_FALSE) { 459289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: error %#x waiting for fence", 460289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglGetError()); 461289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 462289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: timeout waiting for fence"); 463289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 464289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglDestroySyncKHR(eglDisplay, eglFence); 465289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 466289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 4678f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x", 4688f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn *outSlot, 469289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[*outSlot].mFrameNumber, 470289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[*outSlot].mGraphicBuffer->handle, returnFlags); 471289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 472289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return returnFlags; 473289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 474289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 4759f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatus_t BufferQueueProducer::detachBuffer(int slot) { 4769f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_CALL(); 4779f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_BUFFER_INDEX(slot); 478ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGV("detachBuffer: slot %d", slot); 4799f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza Mutex::Autolock lock(mCore->mMutex); 4809f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 4819f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (mCore->mIsAbandoned) { 482ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("detachBuffer: BufferQueue has been abandoned"); 4839f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_INIT; 4849f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 4859f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 486583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 487ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("detachBuffer: BufferQueue has no connected producer"); 488583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 489583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 490583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 491ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mCore->mSingleBufferMode) { 492ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("detachBuffer: cannot detach a buffer in single buffer" 493ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos "mode"); 494ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos return BAD_VALUE; 495ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 496ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 4979f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 498ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", 4999f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 5009f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 501ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } else if (!mSlots[slot].mBufferState.isDequeued()) { 502ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("detachBuffer: slot %d is not owned by the producer " 503ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos "(state = %s)", slot, mSlots[slot].mBufferState.string()); 5049f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 5059f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } else if (!mSlots[slot].mRequestBufferCalled) { 506ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("detachBuffer: buffer in slot %d has not been requested", 5079f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza slot); 5089f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 5099f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 5109f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 511ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[slot].mBufferState.detachProducer(); 5129f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->freeBufferLocked(slot); 5139f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mCore->mDequeueCondition.broadcast(); 5140de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza mCore->validateConsistencyLocked(); 5159f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 5169f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return NO_ERROR; 5179f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 5189f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 519d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stozastatus_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, 520d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza sp<Fence>* outFence) { 521d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza ATRACE_CALL(); 522d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 523d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if (outBuffer == NULL) { 524d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza BQ_LOGE("detachNextBuffer: outBuffer must not be NULL"); 525d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return BAD_VALUE; 526d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } else if (outFence == NULL) { 527d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza BQ_LOGE("detachNextBuffer: outFence must not be NULL"); 528d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return BAD_VALUE; 529d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 530d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 531d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza Mutex::Autolock lock(mCore->mMutex); 532d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 533d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza if (mCore->mIsAbandoned) { 534d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned"); 535d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return NO_INIT; 536d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza } 537d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 538583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 539583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos BQ_LOGE("detachNextBuffer: BufferQueue has no connected producer"); 540583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 541583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 542583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 543ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mCore->mSingleBufferMode) { 544ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("detachNextBuffer: cannot detach a buffer in single buffer" 545ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos "mode"); 546ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos return BAD_VALUE; 547ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 548ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 549583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos mCore->waitWhileAllocatingLocked(); 550583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 5510de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza if (mCore->mFreeBuffers.empty()) { 5521fc9cc25a487d4d9dea3cc185331e3481ead36ffDan Stoza return NO_MEMORY; 5531fc9cc25a487d4d9dea3cc185331e3481ead36ffDan Stoza } 5548dddc990103b71137be2a6365a26b1ac36598e68Dan Stoza 5550de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza int found = mCore->mFreeBuffers.front(); 5560de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza mCore->mFreeBuffers.remove(found); 5570de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 558d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza BQ_LOGV("detachNextBuffer detached slot %d", found); 559d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 560d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza *outBuffer = mSlots[found].mGraphicBuffer; 561d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza *outFence = mSlots[found].mFence; 562d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza mCore->freeBufferLocked(found); 5630de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza mCore->validateConsistencyLocked(); 564d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 565d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza return NO_ERROR; 566d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza} 567d9822a3843017444364899afc3c23fb5be6b9cb9Dan Stoza 5689f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozastatus_t BufferQueueProducer::attachBuffer(int* outSlot, 5699f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza const sp<android::GraphicBuffer>& buffer) { 5709f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_CALL(); 5719f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 5729f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (outSlot == NULL) { 573ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: outSlot must not be NULL"); 5749f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 5759f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } else if (buffer == NULL) { 576ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: cannot attach NULL buffer"); 5779f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 5789f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 5799f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 5809f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza Mutex::Autolock lock(mCore->mMutex); 581583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 582583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mIsAbandoned) { 583ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: BufferQueue has been abandoned"); 584583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 585583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 586583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 587583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 588ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: BufferQueue has no connected producer"); 589583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 590583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 5919f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 592ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mCore->mSingleBufferMode) { 593ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: cannot atach a buffer in single buffer mode"); 594ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos return BAD_VALUE; 595ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 596ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 597812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza if (buffer->getGenerationNumber() != mCore->mGenerationNumber) { 598812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] " 599812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza "[queue %u]", buffer->getGenerationNumber(), 600812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza mCore->mGenerationNumber); 601812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza return BAD_VALUE; 602812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza } 603812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza 604583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos mCore->waitWhileAllocatingLocked(); 605583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 6069f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status_t returnFlags = NO_ERROR; 6079f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza int found; 608ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos status_t status = waitForFreeSlotThenRelock("attachBuffer", &found, 609567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos &returnFlags); 6109f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (status != NO_ERROR) { 6119f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return status; 6129f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 6139f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 6149f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza // This should not happen 6159f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 616ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("attachBuffer: no available buffer slots"); 6179f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return -EBUSY; 6189f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza } 6199f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 6209f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *outSlot = found; 6219f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza ATRACE_BUFFER_INDEX(*outSlot); 622ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGV("attachBuffer: returning slot %d flags=%#x", 6239f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza *outSlot, returnFlags); 6249f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 6259f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mGraphicBuffer = buffer; 626ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[*outSlot].mBufferState.attachProducer(); 6279f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR; 6289f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza mSlots[*outSlot].mFence = Fence::NO_FENCE; 6292443c7903c6910b57bcc615a4bf2e60068c15dbdDan Stoza mSlots[*outSlot].mRequestBufferCalled = true; 6309f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 6310de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza mCore->validateConsistencyLocked(); 6320de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 6339f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return returnFlags; 6349f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza} 6359f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza 636289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::queueBuffer(int slot, 637289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const QueueBufferInput &input, QueueBufferOutput *output) { 638289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 639289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_BUFFER_INDEX(slot); 640289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 641289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int64_t timestamp; 642289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza bool isAutoTimestamp; 64382c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala android_dataspace dataSpace; 64460d6922a011fe18c111b8d30fb6ef1f655b6b15ePablo Ceballos Rect crop(Rect::EMPTY_RECT); 645289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int scalingMode; 646289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza uint32_t transform; 6471681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk uint32_t stickyTransform; 648289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<Fence> fence; 64982c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala input.deflate(×tamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode, 650567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos &transform, &fence, &stickyTransform); 6515065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza Region surfaceDamage = input.getSurfaceDamage(); 652289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 653289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (fence == NULL) { 654289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: fence is NULL"); 655de288fe2d43adfa1b2243ae534faaf832bf50491Jesse Hall return BAD_VALUE; 656289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 657289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 658289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (scalingMode) { 659289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_FREEZE: 660289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 661289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 662289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: 663289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 664289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 665289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode); 6669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 667289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 668289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 6698dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza sp<IConsumerListener> frameAvailableListener; 6708dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza sp<IConsumerListener> frameReplacedListener; 6718dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza int callbackTicket = 0; 6728dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza BufferItem item; 673289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 674289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 675289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 676289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 677289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: BufferQueue has been abandoned"); 678289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 679289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 680289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 681583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 682583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos BQ_LOGE("queueBuffer: BufferQueue has no connected producer"); 683583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 684583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 685583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 686567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos const int maxBufferCount = mCore->getMaxBufferCountLocked(); 687289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 688289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (slot < 0 || slot >= maxBufferCount) { 689289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)", 690289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza slot, maxBufferCount); 6919f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 692ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } else if (!mSlots[slot].mBufferState.isDequeued()) { 693289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot %d is not owned by the producer " 694ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos "(state = %s)", slot, mSlots[slot].mBufferState.string()); 6959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 696289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (!mSlots[slot].mRequestBufferCalled) { 697289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot %d was queued without requesting " 698289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "a buffer", slot); 6999f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 700289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 701289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 70282c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d" 7038f515ce1c57379cafac4357bc4fdb61dd346ec5fMark Salyzyn " crop=[%d,%d,%d,%d] transform=%#x scale=%s", 70482c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala slot, mCore->mFrameCounter + 1, timestamp, dataSpace, 7053be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza crop.left, crop.top, crop.right, crop.bottom, transform, 7063be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode))); 707289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 708289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer); 709289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight()); 71060d6922a011fe18c111b8d30fb6ef1f655b6b15ePablo Ceballos Rect croppedRect(Rect::EMPTY_RECT); 711289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza crop.intersect(bufferRect, &croppedRect); 712289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (croppedRect != crop) { 713289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: crop rect is not contained within the " 714289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "buffer in slot %d", slot); 7159f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza return BAD_VALUE; 716289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 717289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 71882c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala // Override UNKNOWN dataspace with consumer default 71982c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala if (dataSpace == HAL_DATASPACE_UNKNOWN) { 72082c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala dataSpace = mCore->mDefaultBufferDataSpace; 72182c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala } 72282c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala 723289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFence = fence; 724ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[slot].mBufferState.queue(); 725ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 726289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ++mCore->mFrameCounter; 727289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFrameNumber = mCore->mFrameCounter; 728289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 729289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mAcquireCalled = mSlots[slot].mAcquireCalled; 730289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mGraphicBuffer = mSlots[slot].mGraphicBuffer; 731289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mCrop = crop; 7323be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza item.mTransform = transform & 7333be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY); 734289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mTransformToDisplayInverse = 7353be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0; 7363be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza item.mScalingMode = static_cast<uint32_t>(scalingMode); 737289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mTimestamp = timestamp; 738289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mIsAutoTimestamp = isAutoTimestamp; 73982c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala item.mDataSpace = dataSpace; 740289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mFrameNumber = mCore->mFrameCounter; 741289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mSlot = slot; 742289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mFence = fence; 743567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos item.mIsDroppable = mCore->mAsyncMode || 744ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mDequeueBufferCannotBlock || 745ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos (mCore->mSingleBufferMode && mCore->mSingleBufferSlot == slot); 7465065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza item.mSurfaceDamage = surfaceDamage; 747289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 7481681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk mStickyTransform = stickyTransform; 7491681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk 750ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // Cache the shared buffer data so that the BufferItem can be recreated. 751ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mCore->mSingleBufferMode) { 752ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mSingleBufferCache.crop = crop; 753ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mSingleBufferCache.transform = transform; 754ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mSingleBufferCache.scalingMode = static_cast<uint32_t>( 755ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos scalingMode); 756ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mSingleBufferCache.dataspace = dataSpace; 757ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 758ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 759289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mQueue.empty()) { 760289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // When the queue is empty, we can ignore mDequeueBufferCannotBlock 761289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // and simply queue this buffer 762289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mQueue.push_back(item); 7638dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameAvailableListener = mCore->mConsumerListener; 764289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else { 765289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // When the queue is not empty, we need to look at the front buffer 766289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // state to see if we need to replace it 767289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin()); 768289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (front->mIsDroppable) { 769289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If the front queued buffer is still being tracked, we first 770289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // mark it as freed 771289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->stillTracking(front)) { 772ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[front->mSlot].mBufferState.freeQueued(); 773ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 774ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // After leaving single buffer mode, the shared buffer will 775ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // still be around. Mark it as no longer shared if this 776ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // operation causes it to be free. 777ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (!mCore->mSingleBufferMode && 778ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[front->mSlot].mBufferState.isFree()) { 779ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[front->mSlot].mBufferState.mShared = false; 780ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 781ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // Don't put the shared buffer on the free list. 782ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (!mSlots[front->mSlot].mBufferState.isShared()) { 783ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mFreeBuffers.push_front(front->mSlot); 784ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 785289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 786289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Overwrite the droppable buffer with the incoming one 787289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *front = item; 7888dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameReplacedListener = mCore->mConsumerListener; 789289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else { 790289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mQueue.push_back(item); 7918dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameAvailableListener = mCore->mConsumerListener; 792289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 793289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 794289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 795289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mBufferHasBeenQueued = true; 796289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 797289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 798289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, 7993be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza mCore->mTransformHint, 8003be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza static_cast<uint32_t>(mCore->mQueue.size())); 801289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 802289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); 8038dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza 8048dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // Take a ticket for the callback functions 8058dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza callbackTicket = mNextCallbackTicket++; 8060de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 8070de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza mCore->validateConsistencyLocked(); 808289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 809289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 81099a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner // Wait without lock held 81199a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) { 81299a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner // Waiting here allows for two full buffers to be queued but not a 81399a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner // third. In the event that frames take varying time, this makes a 81499a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner // small trade-off in favor of latency rather than throughput. 81599a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner mLastQueueBufferFence->waitForever("Throttling EGL Production"); 81699a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner mLastQueueBufferFence = fence; 81799a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner } 81899a0afbaee9eddabc2b544e3a5c432901c1d498cEric Penner 8198dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // Don't send the GraphicBuffer through the callback, and don't send 8208dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // the slot number, since the consumer shouldn't need it 8218dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza item.mGraphicBuffer.clear(); 8228dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza item.mSlot = BufferItem::INVALID_BUFFER_SLOT; 8238dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza 8248dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // Call back without the main BufferQueue lock held, but with the callback 8258dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza // lock held so we can ensure that callbacks occur in order 8268dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza { 8278dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza Mutex::Autolock lock(mCallbackMutex); 8288dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza while (callbackTicket != mCurrentCallbackTicket) { 8298dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mCallbackCondition.wait(mCallbackMutex); 8308dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza } 8318dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza 8328dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza if (frameAvailableListener != NULL) { 8338dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameAvailableListener->onFrameAvailable(item); 8348dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza } else if (frameReplacedListener != NULL) { 8358dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza frameReplacedListener->onFrameReplaced(item); 8368dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza } 8378dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza 8388dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza ++mCurrentCallbackTicket; 8398dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza mCallbackCondition.broadcast(); 840289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 841289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 842289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 843289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 844289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 845583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballosstatus_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) { 846289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 847289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("cancelBuffer: slot %d", slot); 848289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 849289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 850289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 851289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: BufferQueue has been abandoned"); 852583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 853583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos } 854583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 855583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 856583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos BQ_LOGE("cancelBuffer: BufferQueue has no connected producer"); 857583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_INIT; 858289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 859289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 860ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (mCore->mSingleBufferMode) { 861ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("cancelBuffer: cannot cancel a buffer in single buffer mode"); 862ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos return BAD_VALUE; 863ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 864ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 8653e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 866289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", 8673e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 868583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return BAD_VALUE; 869ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } else if (!mSlots[slot].mBufferState.isDequeued()) { 870289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " 871ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos "(state = %s)", slot, mSlots[slot].mBufferState.string()); 872583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return BAD_VALUE; 873289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (fence == NULL) { 874289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: fence is NULL"); 875583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return BAD_VALUE; 876289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 877289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 878ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[slot].mBufferState.cancel(); 879ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 880ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // After leaving single buffer mode, the shared buffer will still be around. 881ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // Mark it as no longer shared if this operation causes it to be free. 882ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (!mCore->mSingleBufferMode && mSlots[slot].mBufferState.isFree()) { 883ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mSlots[slot].mBufferState.mShared = false; 884ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 885ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 886ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // Don't put the shared buffer on the free list. 887ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (!mSlots[slot].mBufferState.isShared()) { 888ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mFreeBuffers.push_front(slot); 889ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 890289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFence = fence; 891289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 8920de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza mCore->validateConsistencyLocked(); 893583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos 894583b1b32191992d6ada58b3c61c71932a71c0c4bPablo Ceballos return NO_ERROR; 895289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 896289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 897289ade165e60b5f71734d30e535f16eb1f4313adDan Stozaint BufferQueueProducer::query(int what, int *outValue) { 898289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 899289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 900289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 901289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (outValue == NULL) { 902289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("query: outValue was NULL"); 903289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 904289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 905289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 906289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 907289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("query: BufferQueue has been abandoned"); 908289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 909289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 910289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 911289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int value; 912289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (what) { 913289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_WIDTH: 9143be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza value = static_cast<int32_t>(mCore->mDefaultWidth); 915289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 916289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_HEIGHT: 9173be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza value = static_cast<int32_t>(mCore->mDefaultHeight); 918289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 919289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_FORMAT: 9203be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza value = static_cast<int32_t>(mCore->mDefaultBufferFormat); 921289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 922289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 923567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos value = mCore->getMinUndequeuedBufferCountLocked(); 924289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 9251681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk case NATIVE_WINDOW_STICKY_TRANSFORM: 9263be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza value = static_cast<int32_t>(mStickyTransform); 9271681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk break; 928289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: 929289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = (mCore->mQueue.size() > 1); 930289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 931289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_CONSUMER_USAGE_BITS: 9323be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza value = static_cast<int32_t>(mCore->mConsumerUsageBits); 933289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 93482c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala case NATIVE_WINDOW_DEFAULT_DATASPACE: 93582c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace); 93682c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala break; 9374afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza case NATIVE_WINDOW_BUFFER_AGE: 9384afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza if (mCore->mBufferAge > INT32_MAX) { 9394afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza value = 0; 9404afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza } else { 9414afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza value = static_cast<int32_t>(mCore->mBufferAge); 9424afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza } 9434afd8b67f9be307e6c6ed89deab2e85516bb3a0eDan Stoza break; 944289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 945289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 946289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 947289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 948289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("query: %d? %d", what, value); 949289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outValue = value; 950289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 951289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 952289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 953f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stozastatus_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, 954289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int api, bool producerControlledByApp, QueueBufferOutput *output) { 955289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 956289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 957289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mConsumerName = mCore->mConsumerName; 958ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGV("connect: api=%d producerControlledByApp=%s", api, 959289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza producerControlledByApp ? "true" : "false"); 960289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 961ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (mCore->mIsAbandoned) { 962ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("connect: BufferQueue has been abandoned"); 963ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza return NO_INIT; 964ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza } 965289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 966ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (mCore->mConsumerListener == NULL) { 967ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("connect: BufferQueue has no consumer"); 968ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza return NO_INIT; 969ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza } 970289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 971ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (output == NULL) { 972ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("connect: output was NULL"); 973ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza return BAD_VALUE; 974ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza } 975289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 976ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 977ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("connect: already connected (cur=%d req=%d)", 978ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza mCore->mConnectedApi, api); 979ae3c3682333f25e860fe54e2bae3599bb466cdb6Dan Stoza return BAD_VALUE; 980289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 981289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 982289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int status = NO_ERROR; 983289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (api) { 984289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_EGL: 985289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CPU: 986289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_MEDIA: 987289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CAMERA: 988289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConnectedApi = api; 989289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, 9903be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza mCore->mTransformHint, 9913be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza static_cast<uint32_t>(mCore->mQueue.size())); 992289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 993289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Set up a death notification so that we can disconnect 994289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // automatically if the remote producer dies 995f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza if (listener != NULL && 996097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen IInterface::asBinder(listener)->remoteBinder() != NULL) { 997097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen status = IInterface::asBinder(listener)->linkToDeath( 998289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza static_cast<IBinder::DeathRecipient*>(this)); 999f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza if (status != NO_ERROR) { 1000ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("connect: linkToDeath failed: %s (%d)", 1001289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza strerror(-status), status); 1002289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1003289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1004f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza mCore->mConnectedProducerListener = listener; 1005289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 1006289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 1007ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("connect: unknown API %d", api); 1008289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status = BAD_VALUE; 1009289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 1010289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1011289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1012289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mBufferHasBeenQueued = false; 1013567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos mCore->mDequeueBufferCannotBlock = mCore->mConsumerControlledByApp && 1014567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos producerControlledByApp; 10152b83cc920ac98498bee161e2b0e7befdfc82ca2bDan Stoza mCore->mAllowAllocation = true; 1016289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1017289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return status; 1018289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 1019289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1020289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::disconnect(int api) { 1021289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 1022ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGV("disconnect: api %d", api); 1023289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1024289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int status = NO_ERROR; 1025289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<IConsumerListener> listener; 1026289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 1027289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 102878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 1029289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1030289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 1031289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // It's not really an error to disconnect after the surface has 1032289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // been abandoned; it should just be a no-op. 1033289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 1034289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1035289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1036289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (api) { 1037289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_EGL: 1038289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CPU: 1039289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_MEDIA: 1040289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CAMERA: 1041289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mConnectedApi == api) { 1042289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->freeAllBuffersLocked(); 1043289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1044289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Remove our death notification callback if we have one 1045f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza if (mCore->mConnectedProducerListener != NULL) { 1046f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza sp<IBinder> token = 1047097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen IInterface::asBinder(mCore->mConnectedProducerListener); 1048289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // This can fail if we're here because of the death 1049289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // notification, but we just ignore it 1050289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza token->unlinkToDeath( 1051289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza static_cast<IBinder::DeathRecipient*>(this)); 1052289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1053f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza mCore->mConnectedProducerListener = NULL; 1054289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; 1055399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall mCore->mSidebandStream.clear(); 1056289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 1057289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener = mCore->mConsumerListener; 10584f21a4cc22a94eeb65742fcbb0a8516624474fe5Amith Dsouza } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 1059ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("disconnect: still connected to another API " 1060289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "(cur=%d req=%d)", mCore->mConnectedApi, api); 10619f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status = BAD_VALUE; 1062289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1063289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 1064289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 1065ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGE("disconnect: unknown API %d", api); 10669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza status = BAD_VALUE; 1067289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 1068289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1069289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 1070289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1071289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Call back without lock held 1072289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (listener != NULL) { 1073289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener->onBuffersReleased(); 1074289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 1075289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1076289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return status; 1077289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 1078289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1079399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallstatus_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) { 1080afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim sp<IConsumerListener> listener; 1081afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim { // Autolock scope 1082afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim Mutex::Autolock _l(mCore->mMutex); 1083afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim mCore->mSidebandStream = stream; 1084afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim listener = mCore->mConsumerListener; 1085afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim } // Autolock scope 1086afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim 1087afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim if (listener != NULL) { 1088afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim listener->onSidebandStreamChanged(); 1089afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim } 1090399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall return NO_ERROR; 1091399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall} 1092399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall 1093567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballosvoid BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height, 1094567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos PixelFormat format, uint32_t usage) { 109578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour ATRACE_CALL(); 109678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour while (true) { 109778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Vector<int> freeSlots; 109878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour size_t newBufferCount = 0; 109978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t allocWidth = 0; 110078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t allocHeight = 0; 11013be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN; 110278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t allocUsage = 0; 110378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour { // Autolock scope 110478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Mutex::Autolock lock(mCore->mMutex); 110578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->waitWhileAllocatingLocked(); 110629a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 11079de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza if (!mCore->mAllowAllocation) { 11089de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza BQ_LOGE("allocateBuffers: allocation is not allowed for this " 11099de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza "BufferQueue"); 11109de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza return; 11119de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza } 11129de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 111378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour int currentBufferCount = 0; 111478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) { 111578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (mSlots[slot].mGraphicBuffer != NULL) { 111678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour ++currentBufferCount; 111778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } else { 1118ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (!mSlots[slot].mBufferState.isFree()) { 111978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGE("allocateBuffers: slot %d without buffer is not FREE", 112078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour slot); 112178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour continue; 112278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 112329a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 112411f14871db607718090ae6aa2e5dee3f490b8830Antoine Labour freeSlots.push_back(slot); 112578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 112629a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza } 112729a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 1128567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos int maxBufferCount = mCore->getMaxBufferCountLocked(); 112978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGV("allocateBuffers: allocating from %d buffers up to %d buffers", 113078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour currentBufferCount, maxBufferCount); 113178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (maxBufferCount <= currentBufferCount) 113278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour return; 11333be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza newBufferCount = 11343be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza static_cast<size_t>(maxBufferCount - currentBufferCount); 113578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (freeSlots.size() < newBufferCount) { 113678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGE("allocateBuffers: ran out of free slots"); 113778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour return; 113878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 113978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocWidth = width > 0 ? width : mCore->mDefaultWidth; 114078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocHeight = height > 0 ? height : mCore->mDefaultHeight; 114178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat; 114278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocUsage = usage | mCore->mConsumerUsageBits; 114329a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 114478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = true; 114578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } // Autolock scope 114678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour 11473be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza Vector<sp<GraphicBuffer>> buffers; 114878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour for (size_t i = 0; i < newBufferCount; ++i) { 114978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour status_t result = NO_ERROR; 115078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 115178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour allocWidth, allocHeight, allocFormat, allocUsage, &result)); 115278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (result != NO_ERROR) { 115378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format" 115478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour " %u, usage %u)", width, height, format, usage); 115578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Mutex::Autolock lock(mCore->mMutex); 115678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = false; 115778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocatingCondition.broadcast(); 115878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour return; 115978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 116078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour buffers.push_back(graphicBuffer); 116129a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza } 116229a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 116378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour { // Autolock scope 116478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour Mutex::Autolock lock(mCore->mMutex); 116578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth; 116678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight; 11673be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza PixelFormat checkFormat = format != 0 ? 11683be1c6b60a188dc10025e2ce156c11fac050625dDan Stoza format : mCore->mDefaultBufferFormat; 116978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour uint32_t checkUsage = usage | mCore->mConsumerUsageBits; 117078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour if (checkWidth != allocWidth || checkHeight != allocHeight || 117178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour checkFormat != allocFormat || checkUsage != allocUsage) { 117278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour // Something changed while we released the lock. Retry. 117378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying."); 117478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = false; 117578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocatingCondition.broadcast(); 117678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour continue; 117778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 117829a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 117978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour for (size_t i = 0; i < newBufferCount; ++i) { 118078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour int slot = freeSlots[i]; 1181ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (!mSlots[slot].mBufferState.isFree()) { 118278014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour // A consumer allocated the FREE slot with attachBuffer. Discard the buffer we 118378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour // allocated. 118478014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGV("allocateBuffers: slot %d was acquired while allocating. " 118578014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour "Dropping allocated buffer.", slot); 118678014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour continue; 118778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 118878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->freeBufferLocked(slot); // Clean up the slot first 118978014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mSlots[slot].mGraphicBuffer = buffers[i]; 119078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mSlots[slot].mFence = Fence::NO_FENCE; 11910de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 11920de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza // freeBufferLocked puts this slot on the free slots list. Since 11930de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza // we then attached a buffer, move the slot to free buffer list. 11940de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza mCore->mFreeSlots.erase(slot); 11950de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza mCore->mFreeBuffers.push_front(slot); 11960de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza 119778014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", slot); 119878014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } 119929a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 120078014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocating = false; 120178014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour mCore->mIsAllocatingCondition.broadcast(); 12020de7ea752900b5da29ad19c2799040235477f3c5Dan Stoza mCore->validateConsistencyLocked(); 120378014f32da6d0ebf52fb34ebb7663863000520a0Antoine Labour } // Autolock scope 120429a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza } 120529a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza} 120629a3e90879fd96404c971e7187cd0e05927bbce0Dan Stoza 12079de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stozastatus_t BufferQueueProducer::allowAllocation(bool allow) { 12089de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza ATRACE_CALL(); 12099de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza BQ_LOGV("allowAllocation: %s", allow ? "true" : "false"); 12109de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 12119de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza Mutex::Autolock lock(mCore->mMutex); 12129de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza mCore->mAllowAllocation = allow; 12139de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza return NO_ERROR; 12149de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza} 12159de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza 1216812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stozastatus_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) { 1217812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza ATRACE_CALL(); 1218812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza BQ_LOGV("setGenerationNumber: %u", generationNumber); 1219812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza 1220812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza Mutex::Autolock lock(mCore->mMutex); 1221812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza mCore->mGenerationNumber = generationNumber; 1222812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza return NO_ERROR; 1223812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza} 1224812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza 1225c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan StozaString8 BufferQueueProducer::getConsumerName() const { 1226c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza ATRACE_CALL(); 1227c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza BQ_LOGV("getConsumerName: %s", mConsumerName.string()); 1228c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza return mConsumerName; 1229c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza} 1230c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza 12317dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stozauint64_t BufferQueueProducer::getNextFrameNumber() const { 12327dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza ATRACE_CALL(); 12337dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza 12347dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza Mutex::Autolock lock(mCore->mMutex); 12357dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza uint64_t nextFrameNumber = mCore->mFrameCounter + 1; 12367dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza return nextFrameNumber; 12377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza} 12387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza 1239ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballosstatus_t BufferQueueProducer::setSingleBufferMode(bool singleBufferMode) { 1240ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos ATRACE_CALL(); 1241ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos BQ_LOGV("setSingleBufferMode: %d", singleBufferMode); 1242ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 1243ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos Mutex::Autolock lock(mCore->mMutex); 1244ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos if (!singleBufferMode) { 1245ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mSingleBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT; 1246ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos } 1247ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCore->mSingleBufferMode = singleBufferMode; 1248ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 1249ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos return NO_ERROR; 1250ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos} 1251ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 1252289ade165e60b5f71734d30e535f16eb1f4313adDan Stozavoid BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) { 1253289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If we're here, it means that a producer we were connected to died. 1254289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // We're guaranteed that we are still connected to it because we remove 1255289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // this callback upon disconnect. It's therefore safe to read mConnectedApi 1256289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // without synchronization here. 1257289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int api = mCore->mConnectedApi; 1258289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza disconnect(api); 1259289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 1260289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1261289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} // namespace android 1262