BufferQueueProducer.cpp revision 399184a4cd728ea1421fb0bc1722274a29e38f4a
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 173e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza#define LOG_TAG "BufferQueueProducer" 183e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza#define ATRACE_TAG ATRACE_TAG_GRAPHICS 193e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza//#define LOG_NDEBUG 0 203e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza 21289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#define EGL_EGLEXT_PROTOTYPES 22289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 23289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/BufferItem.h> 24289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/BufferQueueCore.h> 25289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/BufferQueueProducer.h> 26289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/IConsumerListener.h> 27289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/IGraphicBufferAlloc.h> 28289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 29289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <utils/Log.h> 30289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <utils/Trace.h> 31289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 32289ade165e60b5f71734d30e535f16eb1f4313adDan Stozanamespace android { 33289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 34289ade165e60b5f71734d30e535f16eb1f4313adDan StozaBufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) : 35289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore(core), 36289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots(core->mSlots), 37289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mConsumerName() {} 38289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 39289ade165e60b5f71734d30e535f16eb1f4313adDan StozaBufferQueueProducer::~BufferQueueProducer() {} 40289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 41289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 42289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 43289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("requestBuffer: slot %d", slot); 44289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 45289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 46289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 47289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("requestBuffer: BufferQueue has been abandoned"); 48289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 49289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 50289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 513e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 52289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)", 533e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 54289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 55289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 56289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("requestBuffer: slot %d is not owned by the producer " 57289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "(state = %d)", slot, mSlots[slot].mBufferState); 58289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 59289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 60289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 61289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mRequestBufferCalled = true; 62289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *buf = mSlots[slot].mGraphicBuffer; 63289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 64289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 65289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 66289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::setBufferCount(int bufferCount) { 67289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 68289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("setBufferCount: count = %d", bufferCount); 69289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 70289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<IConsumerListener> listener; 71289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 72289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 73289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 74289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 75289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("setBufferCount: BufferQueue has been abandoned"); 76289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 77289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 78289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 793e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) { 80289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("setBufferCount: bufferCount %d too large (max %d)", 813e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS); 82289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 83289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 84289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 85289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // There must be no dequeued buffers when changing the buffer count. 863e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 87289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mSlots[s].mBufferState == BufferSlot::DEQUEUED) { 88289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("setBufferCount: buffer owned by producer"); 89289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return -EINVAL; 90289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 91289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 92289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 93289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (bufferCount == 0) { 94289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mOverrideMaxBufferCount = 0; 95289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 96289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 97289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 98289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 99289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const int minBufferSlots = mCore->getMinMaxBufferCountLocked(false); 100289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (bufferCount < minBufferSlots) { 101289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("setBufferCount: requested buffer count %d is less than " 102289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "minimum %d", bufferCount, minBufferSlots); 103289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 104289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 105289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 106289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Here we are guaranteed that the producer doesn't have any dequeued 107289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // buffers and will release all of its buffer references. We don't 108289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // clear the queue, however, so that currently queued buffers still 109289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // get displayed. 110289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->freeAllBuffersLocked(); 111289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mOverrideMaxBufferCount = bufferCount; 112289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 113289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener = mCore->mConsumerListener; 114289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 115289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 116289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Call back without lock held 117289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (listener != NULL) { 118289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener->onBuffersReleased(); 119289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 120289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 121289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 122289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 123289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 124289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::dequeueBuffer(int *outSlot, 125289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<android::Fence> *outFence, bool async, 126289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza uint32_t width, uint32_t height, uint32_t format, uint32_t usage) { 127289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 128289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 129289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 130289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mConsumerName = mCore->mConsumerName; 131289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 132289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 133289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("dequeueBuffer: async=%s w=%u h=%u format=%#x, usage=%#x", 134289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza async ? "true" : "false", width, height, format, usage); 135289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 136289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if ((width && !height) || (!width && height)) { 137289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height); 138289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 139289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 140289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 141289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status_t returnFlags = NO_ERROR; 142289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLDisplay eglDisplay = EGL_NO_DISPLAY; 143289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; 144289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 145289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 146289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 147289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 148289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (format == 0) { 149289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza format = mCore->mDefaultBufferFormat; 150289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 151289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 152289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Enable the usage bits the consumer requested 153289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza usage |= mCore->mConsumerUsageBits; 154289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 155289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int found = -1; 156289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza bool tryAgain = true; 157289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza while (tryAgain) { 158289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 159289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned"); 160289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 161289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 162289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 163289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const int maxBufferCount = mCore->getMaxBufferCountLocked(async); 164289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (async && mCore->mOverrideMaxBufferCount) { 165289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // FIXME: Some drivers are manually setting the buffer count 166289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // (which they shouldn't), so we do this extra test here to 167289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // handle that case. This is TEMPORARY until we get this fixed. 168289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mOverrideMaxBufferCount < maxBufferCount) { 169289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: async mode is invalid with " 170289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "buffer count override"); 171289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 172289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 173289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 174289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 175289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Free up any buffers that are in slots beyond the max buffer count 1763e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza for (int s = maxBufferCount; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 177289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza assert(mSlots[s].mBufferState == BufferSlot::FREE); 178289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mSlots[s].mGraphicBuffer != NULL) { 179289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->freeBufferLocked(s); 180289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza returnFlags |= RELEASE_ALL_BUFFERS; 181289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 182289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 183289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 184289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Look for a free buffer to give to the client 185289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza found = BufferQueueCore::INVALID_BUFFER_SLOT; 186289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int dequeuedCount = 0; 187289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int acquiredCount = 0; 188289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza for (int s = 0; s < maxBufferCount; ++s) { 189289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (mSlots[s].mBufferState) { 190289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case BufferSlot::DEQUEUED: 191289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ++dequeuedCount; 192289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 193289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case BufferSlot::ACQUIRED: 194289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ++acquiredCount; 195289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 196289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case BufferSlot::FREE: 197289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // We return the oldest of the free buffers to avoid 198289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // stalling the producer if possible, since the consumer 199289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // may still have pending reads of in-flight buffers 200289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT || 201289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) { 202289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza found = s; 203289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 204289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 205289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 206289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 207289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 208289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 209289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 210289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Producers are not allowed to dequeue more than one buffer if they 211289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // did not set a buffer count 212289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (!mCore->mOverrideMaxBufferCount && dequeuedCount) { 213289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: can't dequeue multiple buffers " 214289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "without setting the buffer count"); 215289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return -EINVAL; 216289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 217289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 218289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // See whether a buffer has been queued since the last 219289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // setBufferCount so we know whether to perform the min undequeued 220289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // buffers check below 221289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mBufferHasBeenQueued) { 222289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Make sure the producer is not trying to dequeue more buffers 223289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // than allowed 224289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const int newUndequeuedCount = 225289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza maxBufferCount - (dequeuedCount + 1); 226289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const int minUndequeuedCount = 227289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->getMinUndequeuedBufferCountLocked(async); 228289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (newUndequeuedCount < minUndequeuedCount) { 229289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: min undequeued buffer count (%d) " 230289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "exceeded (dequeued=%d undequeued=%d)", 231289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza minUndequeuedCount, dequeuedCount, 232289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza newUndequeuedCount); 233289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return -EBUSY; 234289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 235289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 236289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 237289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If no buffer is found, wait for a buffer to be released or for 238289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // the max buffer count to change 239289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza tryAgain = (found == BufferQueueCore::INVALID_BUFFER_SLOT); 240289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (tryAgain) { 241289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Return an error if we're in non-blocking mode (producer and 242289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // consumer are controlled by the application). 243289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // However, the consumer is allowed to briefly acquire an extra 244289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // buffer (which could cause us to have to wait here), which is 245289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // okay, since it is only used to implement an atomic acquire + 246289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // release (e.g., in GLConsumer::updateTexImage()) 247289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mDequeueBufferCannotBlock && 248289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza (acquiredCount <= mCore->mMaxAcquiredBufferCount)) { 249289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return WOULD_BLOCK; 250289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 251289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.wait(mCore->mMutex); 252289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 253289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // while (tryAgain) 254289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 255289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // This should not happen 256289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 257289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: no available buffer slots"); 258289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return -EBUSY; 259289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 260289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 261289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outSlot = found; 262289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_BUFFER_INDEX(found); 263289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 264289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const bool useDefaultSize = !width && !height; 265289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (useDefaultSize) { 266289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza width = mCore->mDefaultWidth; 267289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza height = mCore->mDefaultHeight; 268289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 269289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 270289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mBufferState = BufferSlot::DEQUEUED; 271289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 272289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer); 273289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if ((buffer == NULL) || 274289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza (static_cast<uint32_t>(buffer->width) != width) || 275289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza (static_cast<uint32_t>(buffer->height) != height) || 276289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza (static_cast<uint32_t>(buffer->format) != format) || 277289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ((static_cast<uint32_t>(buffer->usage) & usage) != usage)) 278289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { 279289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mAcquireCalled = false; 280289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mGraphicBuffer = NULL; 281289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mRequestBufferCalled = false; 282289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglDisplay = EGL_NO_DISPLAY; 283289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglFence = EGL_NO_SYNC_KHR; 284289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mFence = Fence::NO_FENCE; 285289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 286289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza returnFlags |= BUFFER_NEEDS_REALLOCATION; 287289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 288289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 289289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (CC_UNLIKELY(mSlots[found].mFence == NULL)) { 290289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: about to return a NULL fence - " 291289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "slot=%d w=%d h=%d format=%u", 292289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza found, buffer->width, buffer->height, buffer->format); 293289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 294289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 295289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglDisplay = mSlots[found].mEglDisplay; 296289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglFence = mSlots[found].mEglFence; 297289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outFence = mSlots[found].mFence; 298289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mEglFence = EGL_NO_SYNC_KHR; 299289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[found].mFence = Fence::NO_FENCE; 300289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 301289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 302289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (returnFlags & BUFFER_NEEDS_REALLOCATION) { 303289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status_t error; 304289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 305289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza width, height, format, usage, &error)); 306289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (graphicBuffer == NULL) { 307289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: createGraphicBuffer failed"); 308289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return error; 309289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 310289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 311289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 312289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 313289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 314289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 315289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned"); 316289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 317289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 318289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 319289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[*outSlot].mFrameNumber = ~0; 320289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[*outSlot].mGraphicBuffer = graphicBuffer; 321289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 322289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 323289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 324289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (eglFence != EGL_NO_SYNC_KHR) { 325289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0, 326289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 1000000000); 327289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If something goes wrong, log the error, but return the buffer without 328289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // synchronizing access to it. It's too late at this point to abort the 329289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // dequeue operation. 330289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (result == EGL_FALSE) { 331289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: error %#x waiting for fence", 332289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglGetError()); 333289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 334289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("dequeueBuffer: timeout waiting for fence"); 335289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 336289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza eglDestroySyncKHR(eglDisplay, eglFence); 337289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 338289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 339289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("dequeueBuffer: returning slot=%d/%llu buf=%p flags=%#x", *outSlot, 340289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[*outSlot].mFrameNumber, 341289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[*outSlot].mGraphicBuffer->handle, returnFlags); 342289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 343289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return returnFlags; 344289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 345289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 346289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::queueBuffer(int slot, 347289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const QueueBufferInput &input, QueueBufferOutput *output) { 348289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 349289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_BUFFER_INDEX(slot); 350289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 351289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int64_t timestamp; 352289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza bool isAutoTimestamp; 353289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Rect crop; 354289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int scalingMode; 355289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza uint32_t transform; 356289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza bool async; 357289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<Fence> fence; 358289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza input.deflate(×tamp, &isAutoTimestamp, &crop, &scalingMode, &transform, 359289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza &async, &fence); 360289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 361289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (fence == NULL) { 362289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: fence is NULL"); 363289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 364289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 365289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 366289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (scalingMode) { 367289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_FREEZE: 368289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 369289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 370289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: 371289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 372289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 373289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode); 374289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return -EINVAL; 375289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 376289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 377289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<IConsumerListener> listener; 378289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 379289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 380289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 381289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 382289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: BufferQueue has been abandoned"); 383289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 384289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 385289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 386289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const int maxBufferCount = mCore->getMaxBufferCountLocked(async); 387289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (async && mCore->mOverrideMaxBufferCount) { 388289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // FIXME: Some drivers are manually setting the buffer count 389289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // (which they shouldn't), so we do this extra test here to 390289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // handle that case. This is TEMPORARY until we get this fixed. 391289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mOverrideMaxBufferCount < maxBufferCount) { 392289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: async mode is invalid with " 393289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "buffer count override"); 394289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 395289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 396289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 397289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 398289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (slot < 0 || slot >= maxBufferCount) { 399289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)", 400289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza slot, maxBufferCount); 401289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return -EINVAL; 402289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 403289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot %d is not owned by the producer " 404289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "(state = %d)", slot, mSlots[slot].mBufferState); 405289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return -EINVAL; 406289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (!mSlots[slot].mRequestBufferCalled) { 407289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: slot %d was queued without requesting " 408289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "a buffer", slot); 409289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return -EINVAL; 410289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 411289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 412289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("queueBuffer: slot=%d/%llu time=%llu crop=[%d,%d,%d,%d] " 413289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "transform=%#x scale=%s", 414289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza slot, mCore->mFrameCounter + 1, timestamp, 415289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza crop.left, crop.top, crop.right, crop.bottom, 416289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza transform, BufferItem::scalingModeName(scalingMode)); 417289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 418289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer); 419289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight()); 420289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Rect croppedRect; 421289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza crop.intersect(bufferRect, &croppedRect); 422289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (croppedRect != crop) { 423289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("queueBuffer: crop rect is not contained within the " 424289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "buffer in slot %d", slot); 425289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return -EINVAL; 426289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 427289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 428289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFence = fence; 429289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mBufferState = BufferSlot::QUEUED; 430289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ++mCore->mFrameCounter; 431289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFrameNumber = mCore->mFrameCounter; 432289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 433289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BufferItem item; 434289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mAcquireCalled = mSlots[slot].mAcquireCalled; 435289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mGraphicBuffer = mSlots[slot].mGraphicBuffer; 436289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mCrop = crop; 437289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mTransform = transform & ~NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; 438289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mTransformToDisplayInverse = 439289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza bool(transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY); 440289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mScalingMode = scalingMode; 441289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mTimestamp = timestamp; 442289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mIsAutoTimestamp = isAutoTimestamp; 443289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mFrameNumber = mCore->mFrameCounter; 444289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mSlot = slot; 445289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mFence = fence; 446289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza item.mIsDroppable = mCore->mDequeueBufferCannotBlock || async; 447289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 448289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mQueue.empty()) { 449289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // When the queue is empty, we can ignore mDequeueBufferCannotBlock 450289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // and simply queue this buffer 451289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mQueue.push_back(item); 452289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener = mCore->mConsumerListener; 453289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else { 454289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // When the queue is not empty, we need to look at the front buffer 455289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // state to see if we need to replace it 456289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin()); 457289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (front->mIsDroppable) { 458289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If the front queued buffer is still being tracked, we first 459289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // mark it as freed 460289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->stillTracking(front)) { 461289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[front->mSlot].mBufferState = BufferSlot::FREE; 462289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Reset the frame number of the freed buffer so that it is 463289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // the first in line to be dequeued again 464289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[front->mSlot].mFrameNumber = 0; 465289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 466289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Overwrite the droppable buffer with the incoming one 467289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *front = item; 468289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else { 469289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mQueue.push_back(item); 470289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener = mCore->mConsumerListener; 471289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 472289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 473289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 474289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mBufferHasBeenQueued = true; 475289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 476289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 477289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, 478289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mTransformHint, mCore->mQueue.size()); 479289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 480289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); 481289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 482289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 483289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Call back without lock held 484289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (listener != NULL) { 485289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener->onFrameAvailable(); 486289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 487289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 488289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 489289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 490289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 491289ade165e60b5f71734d30e535f16eb1f4313adDan Stozavoid BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) { 492289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 493289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("cancelBuffer: slot %d", slot); 494289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 495289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 496289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 497289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: BufferQueue has been abandoned"); 498289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return; 499289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 500289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 5013e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 502289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", 5033e96f1982fda358424b0b75f394cbf7c1794a072Dan Stoza slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 504289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return; 505289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 506289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " 507289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "(state = %d)", slot, mSlots[slot].mBufferState); 508289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return; 509289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else if (fence == NULL) { 510289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("cancelBuffer: fence is NULL"); 511289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return; 512289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 513289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 514289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mBufferState = BufferSlot::FREE; 515289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFrameNumber = 0; 516289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlots[slot].mFence = fence; 517289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 518289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 519289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 520289ade165e60b5f71734d30e535f16eb1f4313adDan Stozaint BufferQueueProducer::query(int what, int *outValue) { 521289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 522289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 523289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 524289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (outValue == NULL) { 525289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("query: outValue was NULL"); 526289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 527289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 528289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 529289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 530289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("query: BufferQueue has been abandoned"); 531289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 532289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 533289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 534289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int value; 535289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (what) { 536289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_WIDTH: 537289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->mDefaultWidth; 538289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 539289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_HEIGHT: 540289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->mDefaultHeight; 541289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 542289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_FORMAT: 543289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->mDefaultBufferFormat; 544289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 545289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 546289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->getMinUndequeuedBufferCountLocked(false); 547289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 548289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: 549289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = (mCore->mQueue.size() > 1); 550289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 551289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_CONSUMER_USAGE_BITS: 552289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza value = mCore->mConsumerUsageBits; 553289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 554289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 555289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 556289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 557289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 558289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("query: %d? %d", what, value); 559289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza *outValue = value; 560289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 561289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 562289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 563289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::connect(const sp<android::IBinder> &token, 564289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int api, bool producerControlledByApp, QueueBufferOutput *output) { 565289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 566289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 567289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mConsumerName = mCore->mConsumerName; 568289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("connect(P): api=%d producerControlledByApp=%s", api, 569289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza producerControlledByApp ? "true" : "false"); 570289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 571289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If we disconnect and reconnect quickly, we can be in a state where our 572289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // slots are empty but we have many buffers in the queue. This can cause us 573289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // to run out of memory if we outrun the consumer. Wait here if it looks 574289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // like we have too many buffers queued up. 575289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza while (true) { 576289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 577289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("connect(P): BufferQueue has been abandoned"); 578289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 579289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 580289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 581289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mConsumerListener == NULL) { 582289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("connect(P): BufferQueue has no consumer"); 583289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_INIT; 584289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 585289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 586289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (output == NULL) { 587289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("connect(P): output was NULL"); 588289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 589289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 590289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 591289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 592289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("connect(P): already connected (cur=%d req=%d)", 593289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConnectedApi, api); 594289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return BAD_VALUE; 595289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 596289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 597289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza size_t maxBufferCount = mCore->getMaxBufferCountLocked(false); 598289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mQueue.size() <= maxBufferCount) { 599289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // The queue size seems small enough to proceed 600289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // TODO: Make this bound tighter? 601289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 602289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 603289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 604289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("connect(P): queue size is %d, waiting", mCore->mQueue.size()); 605289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.wait(mCore->mMutex); 606289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 607289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 608289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int status = NO_ERROR; 609289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (api) { 610289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_EGL: 611289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CPU: 612289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_MEDIA: 613289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CAMERA: 614289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConnectedApi = api; 615289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, 616289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mTransformHint, mCore->mQueue.size()); 617289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 618289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Set up a death notification so that we can disconnect 619289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // automatically if the remote producer dies 620289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (token != NULL && token->remoteBinder() != NULL) { 621289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status = token->linkToDeath( 622289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza static_cast<IBinder::DeathRecipient*>(this)); 623289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (status == NO_ERROR) { 624289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConnectedProducerToken = token; 625289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else { 626289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("connect(P): linkToDeath failed: %s (%d)", 627289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza strerror(-status), status); 628289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 629289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 630289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 631289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 632289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("connect(P): unknown API %d", api); 633289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status = BAD_VALUE; 634289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 635289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 636289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 637289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mBufferHasBeenQueued = false; 638289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueBufferCannotBlock = 639289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConsumerControlledByApp && producerControlledByApp; 640289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 641289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return status; 642289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 643289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 644289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferQueueProducer::disconnect(int api) { 645289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza ATRACE_CALL(); 646289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGV("disconnect(P): api %d", api); 647289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 648289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int status = NO_ERROR; 649289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<IConsumerListener> listener; 650289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza { // Autolock scope 651289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza Mutex::Autolock lock(mCore->mMutex); 652289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 653289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mIsAbandoned) { 654289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // It's not really an error to disconnect after the surface has 655289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // been abandoned; it should just be a no-op. 656289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 657289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 658289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 659289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (api) { 660289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_EGL: 661289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CPU: 662289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_MEDIA: 663289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_API_CAMERA: 664289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mCore->mConnectedApi == api) { 665289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->freeAllBuffersLocked(); 666289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 667289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Remove our death notification callback if we have one 668289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza sp<IBinder> token = mCore->mConnectedProducerToken; 669289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (token != NULL) { 670289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // This can fail if we're here because of the death 671289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // notification, but we just ignore it 672289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza token->unlinkToDeath( 673289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza static_cast<IBinder::DeathRecipient*>(this)); 674289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 675289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConnectedProducerToken = NULL; 676289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; 677399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall mCore->mSidebandStream.clear(); 678289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mCore->mDequeueCondition.broadcast(); 679289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener = mCore->mConsumerListener; 680289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } else { 681289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("disconnect(P): connected to another API " 682289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza "(cur=%d req=%d)", mCore->mConnectedApi, api); 683289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status = -EINVAL; 684289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 685289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 686289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: 687289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza BQ_LOGE("disconnect(P): unknown API %d", api); 688289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status = -EINVAL; 689289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza break; 690289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 691289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } // Autolock scope 692289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 693289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // Call back without lock held 694289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (listener != NULL) { 695289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza listener->onBuffersReleased(); 696289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 697289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 698289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return status; 699289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 700289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 701399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallstatus_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) { 702399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall Mutex::Autolock _l(mCore->mMutex); 703399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall mCore->mSidebandStream = stream; 704399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall return NO_ERROR; 705399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall} 706399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall 707289ade165e60b5f71734d30e535f16eb1f4313adDan Stozavoid BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) { 708289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // If we're here, it means that a producer we were connected to died. 709289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // We're guaranteed that we are still connected to it because we remove 710289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // this callback upon disconnect. It's therefore safe to read mConnectedApi 711289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // without synchronization here. 712289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza int api = mCore->mConnectedApi; 713289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza disconnect(api); 714289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 715289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 716289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} // namespace android 717