BufferQueue.cpp revision bf974abe92f7495529916fe0f483f3b56e7c30e3
1589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian/* 2589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * Copyright (C) 2012 The Android Open Source Project 3589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * 4589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * you may not use this file except in compliance with the License. 6589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * You may obtain a copy of the License at 7589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * 8589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * 10589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * Unless required by applicable law or agreed to in writing, software 11589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * See the License for the specific language governing permissions and 14589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * limitations under the License. 15589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian */ 16589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 17589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#define LOG_TAG "BufferQueue" 18589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#define ATRACE_TAG ATRACE_TAG_GRAPHICS 19589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian//#define LOG_NDEBUG 0 20589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 21589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#define GL_GLEXT_PROTOTYPES 22589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#define EGL_EGLEXT_PROTOTYPES 23589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 24589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#include <EGL/egl.h> 25589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#include <EGL/eglext.h> 26589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 27589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#include <gui/BufferQueue.h> 28589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#include <gui/ISurfaceComposer.h> 29589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#include <private/gui/ComposerService.h> 30589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 31589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#include <utils/Log.h> 32589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#include <utils/Trace.h> 33589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 34589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian// Macros for including the BufferQueue name in log messages 35a48bcf62b6a26f24a0bdd2b44bb39fadce499e92Mathias Agopian#define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 36589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 37589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 38589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 39a7352c9f4a6e642c29782b19db5bc0bd98feddc8Mathias Agopian#define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 40a7352c9f4a6e642c29782b19db5bc0bd98feddc8Mathias Agopian 41a7352c9f4a6e642c29782b19db5bc0bd98feddc8Mathias Agopian#define ATRACE_BUFFER_INDEX(index) \ 42a7352c9f4a6e642c29782b19db5bc0bd98feddc8Mathias Agopian if (ATRACE_ENABLED()) { \ 43a7352c9f4a6e642c29782b19db5bc0bd98feddc8Mathias Agopian char ___traceBuf[1024]; \ 44a7352c9f4a6e642c29782b19db5bc0bd98feddc8Mathias Agopian snprintf(___traceBuf, 1024, "%s: %d", mConsumerName.string(), \ 45a7352c9f4a6e642c29782b19db5bc0bd98feddc8Mathias Agopian (index)); \ 46a7352c9f4a6e642c29782b19db5bc0bd98feddc8Mathias Agopian android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf); \ 47a7352c9f4a6e642c29782b19db5bc0bd98feddc8Mathias Agopian } 48a7352c9f4a6e642c29782b19db5bc0bd98feddc8Mathias Agopian 49a48bcf62b6a26f24a0bdd2b44bb39fadce499e92Mathias Agopiannamespace android { 50a7352c9f4a6e642c29782b19db5bc0bd98feddc8Mathias Agopian 51a7352c9f4a6e642c29782b19db5bc0bd98feddc8Mathias Agopian// Get an ID that's unique within this process. 52589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopianstatic int32_t createProcessUniqueId() { 53589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian static volatile int32_t globalCounter = 0; 54589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return android_atomic_inc(&globalCounter); 55589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 56589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 57589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopianstatic const char* scalingModeName(int scalingMode) { 58589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian switch (scalingMode) { 59589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE"; 60589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW"; 61589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP"; 62589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian default: return "Unknown"; 63589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian } 64589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 65589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 66589ce85ee4174829cfedce91b6b2509d2a4002ebMathias AgopianBufferQueue::BufferQueue(bool allowSynchronousMode, 67589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian const sp<IGraphicBufferAlloc>& allocator) : 68589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mDefaultWidth(1), 69589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mDefaultHeight(1), 70589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mMaxAcquiredBufferCount(1), 71589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mDefaultMaxBufferCount(2), 72589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mOverrideMaxBufferCount(0), 73589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mSynchronousMode(false), 74589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mAllowSynchronousMode(allowSynchronousMode), 75589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mConnectedApi(NO_CONNECTED_API), 76589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mAbandoned(false), 77589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mFrameCounter(0), 78589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mBufferHasBeenQueued(false), 79589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888), 80589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mConsumerUsageBits(0), 81589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mTransformHint(0) 82589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian{ 83589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian // Choose a name using the PID and a process-unique ID. 84589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); 85589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 86589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian ST_LOGV("BufferQueue"); 87589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian if (allocator == NULL) { 88a48bcf62b6a26f24a0bdd2b44bb39fadce499e92Mathias Agopian sp<ISurfaceComposer> composer(ComposerService::getComposerService()); 89a48bcf62b6a26f24a0bdd2b44bb39fadce499e92Mathias Agopian mGraphicBufferAlloc = composer->createGraphicBufferAlloc(); 90a48bcf62b6a26f24a0bdd2b44bb39fadce499e92Mathias Agopian if (mGraphicBufferAlloc == 0) { 91a48bcf62b6a26f24a0bdd2b44bb39fadce499e92Mathias Agopian ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()"); 92589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian } 93589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian } else { 94589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mGraphicBufferAlloc = allocator; 95589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian } 96589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 97a48bcf62b6a26f24a0bdd2b44bb39fadce499e92Mathias Agopian 98a48bcf62b6a26f24a0bdd2b44bb39fadce499e92Mathias AgopianBufferQueue::~BufferQueue() { 99589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian ST_LOGV("~BufferQueue"); 100589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 101589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 102589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopianstatus_t BufferQueue::setDefaultMaxBufferCountLocked(int count) { 103589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian if (count < 2 || count > NUM_BUFFER_SLOTS) 104589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return BAD_VALUE; 105589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 106589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mDefaultMaxBufferCount = count; 107589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mDequeueCondition.broadcast(); 108589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 109589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return OK; 110589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 111589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 112589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopianbool BufferQueue::isSynchronousMode() const { 113589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian Mutex::Autolock lock(mMutex); 114589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return mSynchronousMode; 115589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 116589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 117589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopianvoid BufferQueue::setConsumerName(const String8& name) { 118589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian Mutex::Autolock lock(mMutex); 119589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mConsumerName = name; 120589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 121589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 122589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopianstatus_t BufferQueue::setDefaultBufferFormat(uint32_t defaultFormat) { 123589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian Mutex::Autolock lock(mMutex); 124589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mDefaultBufferFormat = defaultFormat; 125589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return OK; 126589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 127589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 128589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopianstatus_t BufferQueue::setConsumerUsageBits(uint32_t usage) { 129589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian Mutex::Autolock lock(mMutex); 130589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mConsumerUsageBits = usage; 131589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return OK; 132589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 133589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 134589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopianstatus_t BufferQueue::setTransformHint(uint32_t hint) { 135589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian ST_LOGV("setTransformHint: %02x", hint); 136589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian Mutex::Autolock lock(mMutex); 137589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mTransformHint = hint; 138589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return OK; 139589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 140589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 141a48bcf62b6a26f24a0bdd2b44bb39fadce499e92Mathias Agopianstatus_t BufferQueue::setBufferCount(int bufferCount) { 142589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian ST_LOGV("setBufferCount: count=%d", bufferCount); 143589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 144589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian sp<ConsumerListener> listener; 145589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian { 146589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian Mutex::Autolock lock(mMutex); 147589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 148589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian if (mAbandoned) { 149589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!"); 150589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return NO_INIT; 151589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian } 152589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian if (bufferCount > NUM_BUFFER_SLOTS) { 153589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian ST_LOGE("setBufferCount: bufferCount larger than slots available"); 154589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return BAD_VALUE; 155589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian } 156589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 157589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian // Error out if the user has dequeued buffers 158589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian int maxBufferCount = getMaxBufferCountLocked(); 159589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian for (int i=0 ; i<maxBufferCount; i++) { 160589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) { 161589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian ST_LOGE("setBufferCount: client owns some buffers"); 162589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return -EINVAL; 163589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian } 164589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian } 165589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 166589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian const int minBufferSlots = getMinMaxBufferCountLocked(); 167589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian if (bufferCount == 0) { 168589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mOverrideMaxBufferCount = 0; 169589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mDequeueCondition.broadcast(); 170589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return OK; 171589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian } 172589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 173589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian if (bufferCount < minBufferSlots) { 174589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian ST_LOGE("setBufferCount: requested buffer count (%d) is less than " 175589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian "minimum (%d)", bufferCount, minBufferSlots); 176589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return BAD_VALUE; 177589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian } 178589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 179a48bcf62b6a26f24a0bdd2b44bb39fadce499e92Mathias Agopian // here we're guaranteed that the client doesn't have dequeued buffers 180589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian // and will release all of its buffer references. 181589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian // 182589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian // XXX: Should this use drainQueueAndFreeBuffersLocked instead? 183589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian freeAllBuffersLocked(); 184589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mOverrideMaxBufferCount = bufferCount; 185589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mBufferHasBeenQueued = false; 186 mDequeueCondition.broadcast(); 187 listener = mConsumerListener; 188 } // scope for lock 189 190 if (listener != NULL) { 191 listener->onBuffersReleased(); 192 } 193 194 return OK; 195} 196 197int BufferQueue::query(int what, int* outValue) 198{ 199 ATRACE_CALL(); 200 Mutex::Autolock lock(mMutex); 201 202 if (mAbandoned) { 203 ST_LOGE("query: SurfaceTexture has been abandoned!"); 204 return NO_INIT; 205 } 206 207 int value; 208 switch (what) { 209 case NATIVE_WINDOW_WIDTH: 210 value = mDefaultWidth; 211 break; 212 case NATIVE_WINDOW_HEIGHT: 213 value = mDefaultHeight; 214 break; 215 case NATIVE_WINDOW_FORMAT: 216 value = mDefaultBufferFormat; 217 break; 218 case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 219 value = getMinUndequeuedBufferCountLocked(); 220 break; 221 case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: 222 value = (mQueue.size() >= 2); 223 break; 224 default: 225 return BAD_VALUE; 226 } 227 outValue[0] = value; 228 return NO_ERROR; 229} 230 231status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 232 ATRACE_CALL(); 233 ST_LOGV("requestBuffer: slot=%d", slot); 234 Mutex::Autolock lock(mMutex); 235 if (mAbandoned) { 236 ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!"); 237 return NO_INIT; 238 } 239 int maxBufferCount = getMaxBufferCountLocked(); 240 if (slot < 0 || maxBufferCount <= slot) { 241 ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d", 242 maxBufferCount, slot); 243 return BAD_VALUE; 244 } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 245 // XXX: I vaguely recall there was some reason this can be valid, but 246 // for the life of me I can't recall under what circumstances that's 247 // the case. 248 ST_LOGE("requestBuffer: slot %d is not owned by the client (state=%d)", 249 slot, mSlots[slot].mBufferState); 250 return BAD_VALUE; 251 } 252 mSlots[slot].mRequestBufferCalled = true; 253 *buf = mSlots[slot].mGraphicBuffer; 254 return NO_ERROR; 255} 256 257status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence, 258 uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { 259 ATRACE_CALL(); 260 ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage); 261 262 if ((w && !h) || (!w && h)) { 263 ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h); 264 return BAD_VALUE; 265 } 266 267 status_t returnFlags(OK); 268 EGLDisplay dpy = EGL_NO_DISPLAY; 269 EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; 270 271 { // Scope for the lock 272 Mutex::Autolock lock(mMutex); 273 274 if (format == 0) { 275 format = mDefaultBufferFormat; 276 } 277 // turn on usage bits the consumer requested 278 usage |= mConsumerUsageBits; 279 280 int found = -1; 281 int dequeuedCount = 0; 282 bool tryAgain = true; 283 while (tryAgain) { 284 if (mAbandoned) { 285 ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!"); 286 return NO_INIT; 287 } 288 289 const int maxBufferCount = getMaxBufferCountLocked(); 290 291 // Free up any buffers that are in slots beyond the max buffer 292 // count. 293 for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) { 294 assert(mSlots[i].mBufferState == BufferSlot::FREE); 295 if (mSlots[i].mGraphicBuffer != NULL) { 296 freeBufferLocked(i); 297 returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS; 298 } 299 } 300 301 // look for a free buffer to give to the client 302 found = INVALID_BUFFER_SLOT; 303 dequeuedCount = 0; 304 for (int i = 0; i < maxBufferCount; i++) { 305 const int state = mSlots[i].mBufferState; 306 if (state == BufferSlot::DEQUEUED) { 307 dequeuedCount++; 308 } 309 310 if (state == BufferSlot::FREE) { 311 /* We return the oldest of the free buffers to avoid 312 * stalling the producer if possible. This is because 313 * the consumer may still have pending reads of the 314 * buffers in flight. 315 */ 316 if ((found < 0) || 317 mSlots[i].mFrameNumber < mSlots[found].mFrameNumber) { 318 found = i; 319 } 320 } 321 } 322 323 // clients are not allowed to dequeue more than one buffer 324 // if they didn't set a buffer count. 325 if (!mOverrideMaxBufferCount && dequeuedCount) { 326 ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without " 327 "setting the buffer count"); 328 return -EINVAL; 329 } 330 331 // See whether a buffer has been queued since the last 332 // setBufferCount so we know whether to perform the min undequeued 333 // buffers check below. 334 if (mBufferHasBeenQueued) { 335 // make sure the client is not trying to dequeue more buffers 336 // than allowed. 337 const int newUndequeuedCount = maxBufferCount - (dequeuedCount+1); 338 const int minUndequeuedCount = getMinUndequeuedBufferCountLocked(); 339 if (newUndequeuedCount < minUndequeuedCount) { 340 ST_LOGE("dequeueBuffer: min undequeued buffer count (%d) " 341 "exceeded (dequeued=%d undequeudCount=%d)", 342 minUndequeuedCount, dequeuedCount, 343 newUndequeuedCount); 344 return -EBUSY; 345 } 346 } 347 348 // If no buffer is found, wait for a buffer to be released or for 349 // the max buffer count to change. 350 tryAgain = found == INVALID_BUFFER_SLOT; 351 if (tryAgain) { 352 mDequeueCondition.wait(mMutex); 353 } 354 } 355 356 357 if (found == INVALID_BUFFER_SLOT) { 358 // This should not happen. 359 ST_LOGE("dequeueBuffer: no available buffer slots"); 360 return -EBUSY; 361 } 362 363 const int buf = found; 364 *outBuf = found; 365 366 ATRACE_BUFFER_INDEX(buf); 367 368 const bool useDefaultSize = !w && !h; 369 if (useDefaultSize) { 370 // use the default size 371 w = mDefaultWidth; 372 h = mDefaultHeight; 373 } 374 375 // buffer is now in DEQUEUED (but can also be current at the same time, 376 // if we're in synchronous mode) 377 mSlots[buf].mBufferState = BufferSlot::DEQUEUED; 378 379 const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer); 380 if ((buffer == NULL) || 381 (uint32_t(buffer->width) != w) || 382 (uint32_t(buffer->height) != h) || 383 (uint32_t(buffer->format) != format) || 384 ((uint32_t(buffer->usage) & usage) != usage)) 385 { 386 mSlots[buf].mAcquireCalled = false; 387 mSlots[buf].mGraphicBuffer = NULL; 388 mSlots[buf].mRequestBufferCalled = false; 389 mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 390 mSlots[buf].mFence.clear(); 391 mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; 392 393 returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION; 394 } 395 396 dpy = mSlots[buf].mEglDisplay; 397 eglFence = mSlots[buf].mEglFence; 398 outFence = mSlots[buf].mFence; 399 mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 400 mSlots[buf].mFence.clear(); 401 } // end lock scope 402 403 if (returnFlags & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) { 404 status_t error; 405 sp<GraphicBuffer> graphicBuffer( 406 mGraphicBufferAlloc->createGraphicBuffer( 407 w, h, format, usage, &error)); 408 if (graphicBuffer == 0) { 409 ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer " 410 "failed"); 411 return error; 412 } 413 414 { // Scope for the lock 415 Mutex::Autolock lock(mMutex); 416 417 if (mAbandoned) { 418 ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!"); 419 return NO_INIT; 420 } 421 422 mSlots[*outBuf].mGraphicBuffer = graphicBuffer; 423 } 424 } 425 426 427 if (eglFence != EGL_NO_SYNC_KHR) { 428 EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000); 429 // If something goes wrong, log the error, but return the buffer without 430 // synchronizing access to it. It's too late at this point to abort the 431 // dequeue operation. 432 if (result == EGL_FALSE) { 433 ST_LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError()); 434 } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 435 ST_LOGE("dequeueBuffer: timeout waiting for fence"); 436 } 437 eglDestroySyncKHR(dpy, eglFence); 438 } 439 440 ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf, 441 mSlots[*outBuf].mGraphicBuffer->handle, returnFlags); 442 443 return returnFlags; 444} 445 446status_t BufferQueue::setSynchronousMode(bool enabled) { 447 ATRACE_CALL(); 448 ST_LOGV("setSynchronousMode: enabled=%d", enabled); 449 Mutex::Autolock lock(mMutex); 450 451 if (mAbandoned) { 452 ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!"); 453 return NO_INIT; 454 } 455 456 status_t err = OK; 457 if (!mAllowSynchronousMode && enabled) 458 return err; 459 460 if (!enabled) { 461 // going to asynchronous mode, drain the queue 462 err = drainQueueLocked(); 463 if (err != NO_ERROR) 464 return err; 465 } 466 467 if (mSynchronousMode != enabled) { 468 // - if we're going to asynchronous mode, the queue is guaranteed to be 469 // empty here 470 // - if the client set the number of buffers, we're guaranteed that 471 // we have at least 3 (because we don't allow less) 472 mSynchronousMode = enabled; 473 mDequeueCondition.broadcast(); 474 } 475 return err; 476} 477 478status_t BufferQueue::queueBuffer(int buf, 479 const QueueBufferInput& input, QueueBufferOutput* output) { 480 ATRACE_CALL(); 481 ATRACE_BUFFER_INDEX(buf); 482 483 Rect crop; 484 uint32_t transform; 485 int scalingMode; 486 int64_t timestamp; 487 sp<Fence> fence; 488 489 input.deflate(×tamp, &crop, &scalingMode, &transform, &fence); 490 491 ST_LOGV("queueBuffer: slot=%d time=%#llx crop=[%d,%d,%d,%d] tr=%#x " 492 "scale=%s", 493 buf, timestamp, crop.left, crop.top, crop.right, crop.bottom, 494 transform, scalingModeName(scalingMode)); 495 496 sp<ConsumerListener> listener; 497 498 { // scope for the lock 499 Mutex::Autolock lock(mMutex); 500 if (mAbandoned) { 501 ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!"); 502 return NO_INIT; 503 } 504 int maxBufferCount = getMaxBufferCountLocked(); 505 if (buf < 0 || buf >= maxBufferCount) { 506 ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d", 507 maxBufferCount, buf); 508 return -EINVAL; 509 } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 510 ST_LOGE("queueBuffer: slot %d is not owned by the client " 511 "(state=%d)", buf, mSlots[buf].mBufferState); 512 return -EINVAL; 513 } else if (!mSlots[buf].mRequestBufferCalled) { 514 ST_LOGE("queueBuffer: slot %d was enqueued without requesting a " 515 "buffer", buf); 516 return -EINVAL; 517 } 518 519 const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer); 520 Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight()); 521 Rect croppedCrop; 522 crop.intersect(bufferRect, &croppedCrop); 523 if (croppedCrop != crop) { 524 ST_LOGE("queueBuffer: crop rect is not contained within the " 525 "buffer in slot %d", buf); 526 return -EINVAL; 527 } 528 529 if (mSynchronousMode) { 530 // In synchronous mode we queue all buffers in a FIFO. 531 mQueue.push_back(buf); 532 533 // Synchronous mode always signals that an additional frame should 534 // be consumed. 535 listener = mConsumerListener; 536 } else { 537 // In asynchronous mode we only keep the most recent buffer. 538 if (mQueue.empty()) { 539 mQueue.push_back(buf); 540 541 // Asynchronous mode only signals that a frame should be 542 // consumed if no previous frame was pending. If a frame were 543 // pending then the consumer would have already been notified. 544 listener = mConsumerListener; 545 } else { 546 Fifo::iterator front(mQueue.begin()); 547 // buffer currently queued is freed 548 mSlots[*front].mBufferState = BufferSlot::FREE; 549 // and we record the new buffer index in the queued list 550 *front = buf; 551 } 552 } 553 554 mSlots[buf].mTimestamp = timestamp; 555 mSlots[buf].mCrop = crop; 556 mSlots[buf].mTransform = transform; 557 mSlots[buf].mFence = fence; 558 559 switch (scalingMode) { 560 case NATIVE_WINDOW_SCALING_MODE_FREEZE: 561 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 562 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 563 break; 564 default: 565 ST_LOGE("unknown scaling mode: %d (ignoring)", scalingMode); 566 scalingMode = mSlots[buf].mScalingMode; 567 break; 568 } 569 570 mSlots[buf].mBufferState = BufferSlot::QUEUED; 571 mSlots[buf].mScalingMode = scalingMode; 572 mFrameCounter++; 573 mSlots[buf].mFrameNumber = mFrameCounter; 574 575 mBufferHasBeenQueued = true; 576 mDequeueCondition.broadcast(); 577 578 output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, 579 mQueue.size()); 580 581 ATRACE_INT(mConsumerName.string(), mQueue.size()); 582 } // scope for the lock 583 584 // call back without lock held 585 if (listener != 0) { 586 listener->onFrameAvailable(); 587 } 588 return OK; 589} 590 591void BufferQueue::cancelBuffer(int buf, sp<Fence> fence) { 592 ATRACE_CALL(); 593 ST_LOGV("cancelBuffer: slot=%d", buf); 594 Mutex::Autolock lock(mMutex); 595 596 if (mAbandoned) { 597 ST_LOGW("cancelBuffer: BufferQueue has been abandoned!"); 598 return; 599 } 600 601 int maxBufferCount = getMaxBufferCountLocked(); 602 if (buf < 0 || buf >= maxBufferCount) { 603 ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d", 604 maxBufferCount, buf); 605 return; 606 } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 607 ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)", 608 buf, mSlots[buf].mBufferState); 609 return; 610 } 611 mSlots[buf].mBufferState = BufferSlot::FREE; 612 mSlots[buf].mFrameNumber = 0; 613 mSlots[buf].mFence = fence; 614 mDequeueCondition.broadcast(); 615} 616 617status_t BufferQueue::connect(int api, QueueBufferOutput* output) { 618 ATRACE_CALL(); 619 ST_LOGV("connect: api=%d", api); 620 Mutex::Autolock lock(mMutex); 621 622 if (mAbandoned) { 623 ST_LOGE("connect: BufferQueue has been abandoned!"); 624 return NO_INIT; 625 } 626 627 if (mConsumerListener == NULL) { 628 ST_LOGE("connect: BufferQueue has no consumer!"); 629 return NO_INIT; 630 } 631 632 int err = NO_ERROR; 633 switch (api) { 634 case NATIVE_WINDOW_API_EGL: 635 case NATIVE_WINDOW_API_CPU: 636 case NATIVE_WINDOW_API_MEDIA: 637 case NATIVE_WINDOW_API_CAMERA: 638 if (mConnectedApi != NO_CONNECTED_API) { 639 ST_LOGE("connect: already connected (cur=%d, req=%d)", 640 mConnectedApi, api); 641 err = -EINVAL; 642 } else { 643 mConnectedApi = api; 644 output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, 645 mQueue.size()); 646 } 647 break; 648 default: 649 err = -EINVAL; 650 break; 651 } 652 653 mBufferHasBeenQueued = false; 654 655 return err; 656} 657 658status_t BufferQueue::disconnect(int api) { 659 ATRACE_CALL(); 660 ST_LOGV("disconnect: api=%d", api); 661 662 int err = NO_ERROR; 663 sp<ConsumerListener> listener; 664 665 { // Scope for the lock 666 Mutex::Autolock lock(mMutex); 667 668 if (mAbandoned) { 669 // it is not really an error to disconnect after the surface 670 // has been abandoned, it should just be a no-op. 671 return NO_ERROR; 672 } 673 674 switch (api) { 675 case NATIVE_WINDOW_API_EGL: 676 case NATIVE_WINDOW_API_CPU: 677 case NATIVE_WINDOW_API_MEDIA: 678 case NATIVE_WINDOW_API_CAMERA: 679 if (mConnectedApi == api) { 680 drainQueueAndFreeBuffersLocked(); 681 mConnectedApi = NO_CONNECTED_API; 682 mDequeueCondition.broadcast(); 683 listener = mConsumerListener; 684 } else { 685 ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)", 686 mConnectedApi, api); 687 err = -EINVAL; 688 } 689 break; 690 default: 691 ST_LOGE("disconnect: unknown API %d", api); 692 err = -EINVAL; 693 break; 694 } 695 } 696 697 if (listener != NULL) { 698 listener->onBuffersReleased(); 699 } 700 701 return err; 702} 703 704void BufferQueue::dump(String8& result) const 705{ 706 char buffer[1024]; 707 BufferQueue::dump(result, "", buffer, 1024); 708} 709 710void BufferQueue::dump(String8& result, const char* prefix, 711 char* buffer, size_t SIZE) const 712{ 713 Mutex::Autolock _l(mMutex); 714 715 String8 fifo; 716 int fifoSize = 0; 717 Fifo::const_iterator i(mQueue.begin()); 718 while (i != mQueue.end()) { 719 snprintf(buffer, SIZE, "%02d ", *i++); 720 fifoSize++; 721 fifo.append(buffer); 722 } 723 724 int maxBufferCount = getMaxBufferCountLocked(); 725 726 snprintf(buffer, SIZE, 727 "%s-BufferQueue maxBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], " 728 "default-format=%d, transform-hint=%02x, FIFO(%d)={%s}\n", 729 prefix, maxBufferCount, mSynchronousMode, mDefaultWidth, 730 mDefaultHeight, mDefaultBufferFormat, mTransformHint, 731 fifoSize, fifo.string()); 732 result.append(buffer); 733 734 735 struct { 736 const char * operator()(int state) const { 737 switch (state) { 738 case BufferSlot::DEQUEUED: return "DEQUEUED"; 739 case BufferSlot::QUEUED: return "QUEUED"; 740 case BufferSlot::FREE: return "FREE"; 741 case BufferSlot::ACQUIRED: return "ACQUIRED"; 742 default: return "Unknown"; 743 } 744 } 745 } stateName; 746 747 for (int i=0 ; i<maxBufferCount ; i++) { 748 const BufferSlot& slot(mSlots[i]); 749 snprintf(buffer, SIZE, 750 "%s%s[%02d] " 751 "state=%-8s, crop=[%d,%d,%d,%d], " 752 "xform=0x%02x, time=%#llx, scale=%s", 753 prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i, 754 stateName(slot.mBufferState), 755 slot.mCrop.left, slot.mCrop.top, slot.mCrop.right, 756 slot.mCrop.bottom, slot.mTransform, slot.mTimestamp, 757 scalingModeName(slot.mScalingMode) 758 ); 759 result.append(buffer); 760 761 const sp<GraphicBuffer>& buf(slot.mGraphicBuffer); 762 if (buf != NULL) { 763 snprintf(buffer, SIZE, 764 ", %p [%4ux%4u:%4u,%3X]", 765 buf->handle, buf->width, buf->height, buf->stride, 766 buf->format); 767 result.append(buffer); 768 } 769 result.append("\n"); 770 } 771} 772 773void BufferQueue::freeBufferLocked(int slot) { 774 ST_LOGV("freeBufferLocked: slot=%d", slot); 775 mSlots[slot].mGraphicBuffer = 0; 776 if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) { 777 mSlots[slot].mNeedsCleanupOnRelease = true; 778 } 779 mSlots[slot].mBufferState = BufferSlot::FREE; 780 mSlots[slot].mFrameNumber = 0; 781 mSlots[slot].mAcquireCalled = false; 782 783 // destroy fence as BufferQueue now takes ownership 784 if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) { 785 eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence); 786 mSlots[slot].mEglFence = EGL_NO_SYNC_KHR; 787 } 788 mSlots[slot].mFence.clear(); 789} 790 791void BufferQueue::freeAllBuffersLocked() { 792 ALOGW_IF(!mQueue.isEmpty(), 793 "freeAllBuffersLocked called but mQueue is not empty"); 794 mQueue.clear(); 795 mBufferHasBeenQueued = false; 796 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 797 freeBufferLocked(i); 798 } 799} 800 801status_t BufferQueue::acquireBuffer(BufferItem *buffer) { 802 ATRACE_CALL(); 803 Mutex::Autolock _l(mMutex); 804 805 // Check that the consumer doesn't currently have the maximum number of 806 // buffers acquired. We allow the max buffer count to be exceeded by one 807 // buffer, so that the consumer can successfully set up the newly acquired 808 // buffer before releasing the old one. 809 int numAcquiredBuffers = 0; 810 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 811 if (mSlots[i].mBufferState == BufferSlot::ACQUIRED) { 812 numAcquiredBuffers++; 813 } 814 } 815 if (numAcquiredBuffers >= mMaxAcquiredBufferCount+1) { 816 ST_LOGE("acquireBuffer: max acquired buffer count reached: %d (max=%d)", 817 numAcquiredBuffers, mMaxAcquiredBufferCount); 818 return INVALID_OPERATION; 819 } 820 821 // check if queue is empty 822 // In asynchronous mode the list is guaranteed to be one buffer 823 // deep, while in synchronous mode we use the oldest buffer. 824 if (!mQueue.empty()) { 825 Fifo::iterator front(mQueue.begin()); 826 int buf = *front; 827 828 ATRACE_BUFFER_INDEX(buf); 829 830 if (mSlots[buf].mAcquireCalled) { 831 buffer->mGraphicBuffer = NULL; 832 } else { 833 buffer->mGraphicBuffer = mSlots[buf].mGraphicBuffer; 834 } 835 buffer->mCrop = mSlots[buf].mCrop; 836 buffer->mTransform = mSlots[buf].mTransform; 837 buffer->mScalingMode = mSlots[buf].mScalingMode; 838 buffer->mFrameNumber = mSlots[buf].mFrameNumber; 839 buffer->mTimestamp = mSlots[buf].mTimestamp; 840 buffer->mBuf = buf; 841 buffer->mFence = mSlots[buf].mFence; 842 843 mSlots[buf].mAcquireCalled = true; 844 mSlots[buf].mNeedsCleanupOnRelease = false; 845 mSlots[buf].mBufferState = BufferSlot::ACQUIRED; 846 mSlots[buf].mFence.clear(); 847 848 mQueue.erase(front); 849 mDequeueCondition.broadcast(); 850 851 ATRACE_INT(mConsumerName.string(), mQueue.size()); 852 } else { 853 return NO_BUFFER_AVAILABLE; 854 } 855 856 return OK; 857} 858 859status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display, 860 EGLSyncKHR eglFence, const sp<Fence>& fence) { 861 ATRACE_CALL(); 862 ATRACE_BUFFER_INDEX(buf); 863 864 Mutex::Autolock _l(mMutex); 865 866 if (buf == INVALID_BUFFER_SLOT) { 867 return -EINVAL; 868 } 869 870 mSlots[buf].mEglDisplay = display; 871 mSlots[buf].mEglFence = eglFence; 872 mSlots[buf].mFence = fence; 873 874 // The buffer can now only be released if its in the acquired state 875 if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) { 876 mSlots[buf].mBufferState = BufferSlot::FREE; 877 } else if (mSlots[buf].mNeedsCleanupOnRelease) { 878 ST_LOGV("releasing a stale buf %d its state was %d", buf, mSlots[buf].mBufferState); 879 mSlots[buf].mNeedsCleanupOnRelease = false; 880 return STALE_BUFFER_SLOT; 881 } else { 882 ST_LOGE("attempted to release buf %d but its state was %d", buf, mSlots[buf].mBufferState); 883 return -EINVAL; 884 } 885 886 mDequeueCondition.broadcast(); 887 return OK; 888} 889 890status_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListener) { 891 ST_LOGV("consumerConnect"); 892 Mutex::Autolock lock(mMutex); 893 894 if (mAbandoned) { 895 ST_LOGE("consumerConnect: BufferQueue has been abandoned!"); 896 return NO_INIT; 897 } 898 899 mConsumerListener = consumerListener; 900 901 return OK; 902} 903 904status_t BufferQueue::consumerDisconnect() { 905 ST_LOGV("consumerDisconnect"); 906 Mutex::Autolock lock(mMutex); 907 908 if (mConsumerListener == NULL) { 909 ST_LOGE("consumerDisconnect: No consumer is connected!"); 910 return -EINVAL; 911 } 912 913 mAbandoned = true; 914 mConsumerListener = NULL; 915 mQueue.clear(); 916 freeAllBuffersLocked(); 917 mDequeueCondition.broadcast(); 918 return OK; 919} 920 921status_t BufferQueue::getReleasedBuffers(uint32_t* slotMask) { 922 ST_LOGV("getReleasedBuffers"); 923 Mutex::Autolock lock(mMutex); 924 925 if (mAbandoned) { 926 ST_LOGE("getReleasedBuffers: BufferQueue has been abandoned!"); 927 return NO_INIT; 928 } 929 930 uint32_t mask = 0; 931 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 932 if (!mSlots[i].mAcquireCalled) { 933 mask |= 1 << i; 934 } 935 } 936 *slotMask = mask; 937 938 ST_LOGV("getReleasedBuffers: returning mask %#x", mask); 939 return NO_ERROR; 940} 941 942status_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h) 943{ 944 ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h); 945 if (!w || !h) { 946 ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)", 947 w, h); 948 return BAD_VALUE; 949 } 950 951 Mutex::Autolock lock(mMutex); 952 mDefaultWidth = w; 953 mDefaultHeight = h; 954 return OK; 955} 956 957status_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) { 958 ATRACE_CALL(); 959 Mutex::Autolock lock(mMutex); 960 return setDefaultMaxBufferCountLocked(bufferCount); 961} 962 963status_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { 964 ATRACE_CALL(); 965 Mutex::Autolock lock(mMutex); 966 if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > MAX_MAX_ACQUIRED_BUFFERS) { 967 ST_LOGE("setMaxAcquiredBufferCount: invalid count specified: %d", 968 maxAcquiredBuffers); 969 return BAD_VALUE; 970 } 971 if (mConnectedApi != NO_CONNECTED_API) { 972 return INVALID_OPERATION; 973 } 974 mMaxAcquiredBufferCount = maxAcquiredBuffers; 975 return OK; 976} 977 978void BufferQueue::freeAllBuffersExceptHeadLocked() { 979 int head = -1; 980 if (!mQueue.empty()) { 981 Fifo::iterator front(mQueue.begin()); 982 head = *front; 983 } 984 mBufferHasBeenQueued = false; 985 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 986 if (i != head) { 987 freeBufferLocked(i); 988 } 989 } 990} 991 992status_t BufferQueue::drainQueueLocked() { 993 while (mSynchronousMode && !mQueue.isEmpty()) { 994 mDequeueCondition.wait(mMutex); 995 if (mAbandoned) { 996 ST_LOGE("drainQueueLocked: BufferQueue has been abandoned!"); 997 return NO_INIT; 998 } 999 if (mConnectedApi == NO_CONNECTED_API) { 1000 ST_LOGE("drainQueueLocked: BufferQueue is not connected!"); 1001 return NO_INIT; 1002 } 1003 } 1004 return NO_ERROR; 1005} 1006 1007status_t BufferQueue::drainQueueAndFreeBuffersLocked() { 1008 status_t err = drainQueueLocked(); 1009 if (err == NO_ERROR) { 1010 if (mSynchronousMode) { 1011 freeAllBuffersLocked(); 1012 } else { 1013 freeAllBuffersExceptHeadLocked(); 1014 } 1015 } 1016 return err; 1017} 1018 1019int BufferQueue::getMinMaxBufferCountLocked() const { 1020 return getMinUndequeuedBufferCountLocked() + 1; 1021} 1022 1023int BufferQueue::getMinUndequeuedBufferCountLocked() const { 1024 return mSynchronousMode ? mMaxAcquiredBufferCount : 1025 mMaxAcquiredBufferCount + 1; 1026} 1027 1028int BufferQueue::getMaxBufferCountLocked() const { 1029 int minMaxBufferCount = getMinMaxBufferCountLocked(); 1030 1031 int maxBufferCount = mDefaultMaxBufferCount; 1032 if (maxBufferCount < minMaxBufferCount) { 1033 maxBufferCount = minMaxBufferCount; 1034 } 1035 if (mOverrideMaxBufferCount != 0) { 1036 assert(mOverrideMaxBufferCount >= minMaxBufferCount); 1037 maxBufferCount = mOverrideMaxBufferCount; 1038 } 1039 1040 // Any buffers that are dequeued by the producer or sitting in the queue 1041 // waiting to be consumed need to have their slots preserved. Such 1042 // buffers will temporarily keep the max buffer count up until the slots 1043 // no longer need to be preserved. 1044 for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) { 1045 BufferSlot::BufferState state = mSlots[i].mBufferState; 1046 if (state == BufferSlot::QUEUED || state == BufferSlot::DEQUEUED) { 1047 maxBufferCount = i + 1; 1048 } 1049 } 1050 1051 return maxBufferCount; 1052} 1053 1054BufferQueue::ProxyConsumerListener::ProxyConsumerListener( 1055 const wp<BufferQueue::ConsumerListener>& consumerListener): 1056 mConsumerListener(consumerListener) {} 1057 1058BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {} 1059 1060void BufferQueue::ProxyConsumerListener::onFrameAvailable() { 1061 sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote()); 1062 if (listener != NULL) { 1063 listener->onFrameAvailable(); 1064 } 1065} 1066 1067void BufferQueue::ProxyConsumerListener::onBuffersReleased() { 1068 sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote()); 1069 if (listener != NULL) { 1070 listener->onBuffersReleased(); 1071 } 1072} 1073 1074}; // namespace android 1075