BufferQueue.cpp revision 90ac799241f077a7b7e6c1875fd933864c8dd2a7
16b091c53000c843211c218ce40287a7edca9bc63Daniel Lam/* 26b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * Copyright (C) 2012 The Android Open Source Project 36b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * 46b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * Licensed under the Apache License, Version 2.0 (the "License"); 56b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * you may not use this file except in compliance with the License. 66b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * You may obtain a copy of the License at 76b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * 86b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * http://www.apache.org/licenses/LICENSE-2.0 96b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * 106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * Unless required by applicable law or agreed to in writing, software 116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * distributed under the License is distributed on an "AS IS" BASIS, 126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * See the License for the specific language governing permissions and 146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * limitations under the License. 156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam */ 166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#define LOG_TAG "BufferQueue" 18333023884112259f145bb23c41a05211198d9792Daniel Lam//#define LOG_NDEBUG 0 196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#define GL_GLEXT_PROTOTYPES 216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#define EGL_EGLEXT_PROTOTYPES 226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <EGL/egl.h> 246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <EGL/eglext.h> 256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <gui/BufferQueue.h> 2790ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/ISurfaceComposer.h> 286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <private/gui/ComposerService.h> 296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <utils/Log.h> 31333023884112259f145bb23c41a05211198d9792Daniel Lam#include <gui/SurfaceTexture.h> 326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// This compile option causes SurfaceTexture to return the buffer that is currently 346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// attached to the GL texture from dequeueBuffer when no other buffers are 356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// available. It requires the drivers (Gralloc, GL, OMX IL, and Camera) to do 366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// implicit cross-process synchronization to prevent the buffer from being 376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// written to before the buffer has (a) been detached from the GL texture and 386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// (b) all GL reads from the buffer have completed. 396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER 406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER true 416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled" 426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#else 436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER false 446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#endif 456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// Macros for including the BufferQueue name in log messages 47333023884112259f145bb23c41a05211198d9792Daniel Lam#define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 48333023884112259f145bb23c41a05211198d9792Daniel Lam#define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 49333023884112259f145bb23c41a05211198d9792Daniel Lam#define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 50333023884112259f145bb23c41a05211198d9792Daniel Lam#define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 51333023884112259f145bb23c41a05211198d9792Daniel Lam#define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 536b091c53000c843211c218ce40287a7edca9bc63Daniel Lamnamespace android { 546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// Get an ID that's unique within this process. 566b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatic int32_t createProcessUniqueId() { 576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam static volatile int32_t globalCounter = 0; 586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return android_atomic_inc(&globalCounter); 596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 616b091c53000c843211c218ce40287a7edca9bc63Daniel LamBufferQueue::BufferQueue( bool allowSynchronousMode ) : 626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDefaultWidth(1), 636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDefaultHeight(1), 646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mPixelFormat(PIXEL_FORMAT_RGBA_8888), 656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount(MIN_ASYNC_BUFFER_SLOTS), 666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mClientBufferCount(0), 676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS), 686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mNextTransform(0), 696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mNextScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSynchronousMode(false), 716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mAllowSynchronousMode(allowSynchronousMode), 726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi(NO_CONNECTED_API), 736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mAbandoned(false), 74333023884112259f145bb23c41a05211198d9792Daniel Lam mFrameCounter(0), 75333023884112259f145bb23c41a05211198d9792Daniel Lam mBufferHasBeenQueued(false) 766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{ 776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Choose a name using the PID and a process-unique ID. 78333023884112259f145bb23c41a05211198d9792Daniel Lam mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); 796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("BufferQueue"); 816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam sp<ISurfaceComposer> composer(ComposerService::getComposerService()); 826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mGraphicBufferAlloc = composer->createGraphicBufferAlloc(); 836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mNextCrop.makeInvalid(); 846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 866b091c53000c843211c218ce40287a7edca9bc63Daniel LamBufferQueue::~BufferQueue() { 876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("~BufferQueue"); 886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 906b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setBufferCountServerLocked(int bufferCount) { 916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (bufferCount > NUM_BUFFER_SLOTS) 926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // special-case, nothing to do 956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (bufferCount == mBufferCount) 966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mClientBufferCount && 996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam bufferCount >= mBufferCount) { 1006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // easy, we just have more buffers 1016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount = bufferCount; 1026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mServerBufferCount = bufferCount; 1036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.signal(); 1046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 1056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // we're here because we're either 1066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - reducing the number of available buffers 1076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - or there is a client-buffer-count in effect 1086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // less than 2 buffers is never allowed 1106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (bufferCount < 2) 1116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 1126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // when there is non client-buffer-count in effect, the client is not 1146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // allowed to dequeue more than one buffer at a time, 1156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // so the next time they dequeue a buffer, we know that they don't 1166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // own one. the actual resizing will happen during the next 1176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // dequeueBuffer. 1186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mServerBufferCount = bufferCount; 1206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 1226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 1236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 124333023884112259f145bb23c41a05211198d9792Daniel Lambool BufferQueue::isSynchronousMode() const { 125333023884112259f145bb23c41a05211198d9792Daniel Lam Mutex::Autolock lock(mMutex); 126333023884112259f145bb23c41a05211198d9792Daniel Lam return mSynchronousMode; 127333023884112259f145bb23c41a05211198d9792Daniel Lam} 128333023884112259f145bb23c41a05211198d9792Daniel Lam 129333023884112259f145bb23c41a05211198d9792Daniel Lamvoid BufferQueue::setConsumerName(const String8& name) { 130333023884112259f145bb23c41a05211198d9792Daniel Lam Mutex::Autolock lock(mMutex); 131333023884112259f145bb23c41a05211198d9792Daniel Lam mConsumerName = name; 132333023884112259f145bb23c41a05211198d9792Daniel Lam} 133333023884112259f145bb23c41a05211198d9792Daniel Lam 134333023884112259f145bb23c41a05211198d9792Daniel Lamvoid BufferQueue::setFrameAvailableListener( 135333023884112259f145bb23c41a05211198d9792Daniel Lam const sp<FrameAvailableListener>& listener) { 136333023884112259f145bb23c41a05211198d9792Daniel Lam ST_LOGV("setFrameAvailableListener"); 137333023884112259f145bb23c41a05211198d9792Daniel Lam Mutex::Autolock lock(mMutex); 138333023884112259f145bb23c41a05211198d9792Daniel Lam mFrameAvailableListener = listener; 139333023884112259f145bb23c41a05211198d9792Daniel Lam} 140333023884112259f145bb23c41a05211198d9792Daniel Lam 1416b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setBufferCount(int bufferCount) { 1426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("setBufferCount: count=%d", bufferCount); 1436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 1446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 1466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!"); 1476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 1486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (bufferCount > NUM_BUFFER_SLOTS) { 1506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("setBufferCount: bufferCount larger than slots available"); 1516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 1526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Error out if the user has dequeued buffers 1556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam for (int i=0 ; i<mBufferCount ; i++) { 1566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) { 1576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("setBufferCount: client owns some buffers"); 1586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 1596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int minBufferSlots = mSynchronousMode ? 1636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS; 1646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (bufferCount == 0) { 1656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mClientBufferCount = 0; 1666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam bufferCount = (mServerBufferCount >= minBufferSlots) ? 1676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mServerBufferCount : minBufferSlots; 1686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return setBufferCountServerLocked(bufferCount); 1696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (bufferCount < minBufferSlots) { 1726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("setBufferCount: requested buffer count (%d) is less than " 1736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "minimum (%d)", bufferCount, minBufferSlots); 1746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 1756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // here we're guaranteed that the client doesn't have dequeued buffers 1786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // and will release all of its buffer references. 1796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeAllBuffersLocked(); 1806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount = bufferCount; 1816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mClientBufferCount = bufferCount; 182333023884112259f145bb23c41a05211198d9792Daniel Lam mBufferHasBeenQueued = false; 1836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mQueue.clear(); 1846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.signal(); 1856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 1866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 1876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 188b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lamint BufferQueue::query(int what, int* outValue) 189b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam{ 190b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam Mutex::Autolock lock(mMutex); 191b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 192b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam if (mAbandoned) { 193b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam ST_LOGE("query: SurfaceTexture has been abandoned!"); 194b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return NO_INIT; 195b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam } 196b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 197b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam int value; 198b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam switch (what) { 199b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_WIDTH: 200b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mDefaultWidth; 201b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 202b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_HEIGHT: 203b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mDefaultHeight; 204b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 205b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_FORMAT: 206b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mPixelFormat; 207b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 208b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 209b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mSynchronousMode ? 210b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS; 211b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 212b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam default: 213b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return BAD_VALUE; 214b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam } 215b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam outValue[0] = value; 216b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return NO_ERROR; 217b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam} 218b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 2196b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 2206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("requestBuffer: slot=%d", slot); 2216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 2226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 2236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!"); 2246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 2256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (slot < 0 || mBufferCount <= slot) { 2276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d", 2286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount, slot); 2296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 2306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[slot].mRequestBufferCalled = true; 2326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *buf = mSlots[slot].mGraphicBuffer; 2336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_ERROR; 2346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 2356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2366b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, 2376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam uint32_t format, uint32_t usage) { 2386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage); 2396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if ((w && !h) || (!w && h)) { 2416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h); 2426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 2436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t returnFlags(OK); 2466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam EGLDisplay dpy = EGL_NO_DISPLAY; 2476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam EGLSyncKHR fence = EGL_NO_SYNC_KHR; 2486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { // Scope for the lock 2506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 2516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int found = -1; 2536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int foundSync = -1; 2546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int dequeuedCount = 0; 2556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam bool tryAgain = true; 2566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam while (tryAgain) { 2576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 2586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!"); 2596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 2606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // We need to wait for the FIFO to drain if the number of buffer 2636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // needs to change. 2646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // 2656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // The condition "number of buffers needs to change" is true if 2666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - the client doesn't care about how many buffers there are 2676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - AND the actual number of buffer is different from what was 2686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // set in the last setBufferCountServer() 2696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - OR - 2706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // setBufferCountServer() was set to a value incompatible with 2716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // the synchronization mode (for instance because the sync mode 2726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // changed since) 2736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // 2746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // As long as this condition is true AND the FIFO is not empty, we 2756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // wait on mDequeueCondition. 2766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int minBufferCountNeeded = mSynchronousMode ? 2786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS; 2796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const bool numberOfBuffersNeedsToChange = !mClientBufferCount && 2816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ((mServerBufferCount != mBufferCount) || 2826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (mServerBufferCount < minBufferCountNeeded)); 2836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) { 2856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // wait for the FIFO to drain 2866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.wait(mMutex); 2876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // NOTE: we continue here because we need to reevaluate our 2886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // whole state (eg: we could be abandoned or disconnected) 2896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam continue; 2906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (numberOfBuffersNeedsToChange) { 2936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // here we're guaranteed that mQueue is empty 2946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeAllBuffersLocked(); 2956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount = mServerBufferCount; 2966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mBufferCount < minBufferCountNeeded) 2976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount = minBufferCountNeeded; 298333023884112259f145bb23c41a05211198d9792Daniel Lam mBufferHasBeenQueued = false; 2996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS; 3006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // look for a free buffer to give to the client 3036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam found = INVALID_BUFFER_SLOT; 3046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam foundSync = INVALID_BUFFER_SLOT; 3056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dequeuedCount = 0; 3066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam for (int i = 0; i < mBufferCount; i++) { 3076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int state = mSlots[i].mBufferState; 3086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (state == BufferSlot::DEQUEUED) { 3096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dequeuedCount++; 3106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER) { 313333023884112259f145bb23c41a05211198d9792Daniel Lam // This functionality has been temporarily removed so 314333023884112259f145bb23c41a05211198d9792Daniel Lam // BufferQueue and SurfaceTexture can be refactored into 315333023884112259f145bb23c41a05211198d9792Daniel Lam // separate objects 3166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 3176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (state == BufferSlot::FREE) { 3186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam /* We return the oldest of the free buffers to avoid 3196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * stalling the producer if possible. This is because 3206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * the consumer may still have pending reads of the 3216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * buffers in flight. 3226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam */ 3236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam bool isOlder = mSlots[i].mFrameNumber < 3246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[found].mFrameNumber; 3256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (found < 0 || isOlder) { 3266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam foundSync = i; 3276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam found = i; 3286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // clients are not allowed to dequeue more than one buffer 3346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // if they didn't set a buffer count. 3356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mClientBufferCount && dequeuedCount) { 3366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without " 3376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "setting the buffer count"); 3386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 3396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // See whether a buffer has been queued since the last 3426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // setBufferCount so we know whether to perform the 3436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // MIN_UNDEQUEUED_BUFFERS check below. 344333023884112259f145bb23c41a05211198d9792Daniel Lam if (mBufferHasBeenQueued) { 3456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // make sure the client is not trying to dequeue more buffers 3466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // than allowed. 3476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int avail = mBufferCount - (dequeuedCount+1); 3486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) { 3496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded " 3506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "(dequeued=%d)", 3516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode), 3526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dequeuedCount); 3536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EBUSY; 3546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // we're in synchronous mode and didn't find a buffer, we need to 3586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // wait for some buffers to be consumed 3596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT); 3606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (tryAgain) { 3616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.wait(mMutex); 3626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSynchronousMode && found == INVALID_BUFFER_SLOT) { 3666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // foundSync guaranteed to be != INVALID_BUFFER_SLOT 3676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam found = foundSync; 3686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (found == INVALID_BUFFER_SLOT) { 3716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // This should not happen. 3726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: no available buffer slots"); 3736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EBUSY; 3746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int buf = found; 3776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outBuf = found; 3786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const bool useDefaultSize = !w && !h; 3806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (useDefaultSize) { 3816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // use the default size 3826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam w = mDefaultWidth; 3836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam h = mDefaultHeight; 3846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const bool updateFormat = (format != 0); 3876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!updateFormat) { 3886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // keep the current (or default) format 3896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam format = mPixelFormat; 3906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // buffer is now in DEQUEUED (but can also be current at the same time, 3936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // if we're in synchronous mode) 3946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mBufferState = BufferSlot::DEQUEUED; 3956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer); 3976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if ((buffer == NULL) || 3986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->width) != w) || 3996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->height) != h) || 4006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->format) != format) || 4016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ((uint32_t(buffer->usage) & usage) != usage)) 4026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { 4036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam usage |= GraphicBuffer::USAGE_HW_TEXTURE; 4046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t error; 4056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam sp<GraphicBuffer> graphicBuffer( 4066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mGraphicBufferAlloc->createGraphicBuffer( 4076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam w, h, format, usage, &error)); 4086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (graphicBuffer == 0) { 4096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer " 4106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "failed"); 4116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return error; 4126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (updateFormat) { 4146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mPixelFormat = format; 4156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 416333023884112259f145bb23c41a05211198d9792Daniel Lam 417333023884112259f145bb23c41a05211198d9792Daniel Lam mSlots[buf].mAcquireCalled = false; 4186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mGraphicBuffer = graphicBuffer; 4196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mRequestBufferCalled = false; 4206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mFence = EGL_NO_SYNC_KHR; 421333023884112259f145bb23c41a05211198d9792Daniel Lam mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; 422333023884112259f145bb23c41a05211198d9792Daniel Lam 423333023884112259f145bb23c41a05211198d9792Daniel Lam 424333023884112259f145bb23c41a05211198d9792Daniel Lam 425333023884112259f145bb23c41a05211198d9792Daniel Lam 4266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION; 4276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dpy = mSlots[buf].mEglDisplay; 4306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam fence = mSlots[buf].mFence; 4316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mFence = EGL_NO_SYNC_KHR; 432333023884112259f145bb23c41a05211198d9792Daniel Lam } // end lock scope 4336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (fence != EGL_NO_SYNC_KHR) { 4356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000); 4366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // If something goes wrong, log the error, but return the buffer without 4376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // synchronizing access to it. It's too late at this point to abort the 4386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // dequeue operation. 4396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (result == EGL_FALSE) { 4406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ALOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError()); 4416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 4426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ALOGE("dequeueBuffer: timeout waiting for fence"); 4436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam eglDestroySyncKHR(dpy, fence); 445333023884112259f145bb23c41a05211198d9792Daniel Lam 4466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf, 4496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[*outBuf].mGraphicBuffer->handle, returnFlags); 4506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return returnFlags; 4526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 4536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4546b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setSynchronousMode(bool enabled) { 4556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("setSynchronousMode: enabled=%d", enabled); 4566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 4576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 4596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!"); 4606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 4616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t err = OK; 4646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mAllowSynchronousMode && enabled) 4656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 4666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!enabled) { 4686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // going to asynchronous mode, drain the queue 4696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = drainQueueLocked(); 4706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (err != NO_ERROR) 4716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 4726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSynchronousMode != enabled) { 4756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - if we're going to asynchronous mode, the queue is guaranteed to be 4766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // empty here 4776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - if the client set the number of buffers, we're guaranteed that 4786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // we have at least 3 (because we don't allow less) 4796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSynchronousMode = enabled; 4806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.signal(); 4816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 4836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 4846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4856b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::queueBuffer(int buf, int64_t timestamp, 4866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { 4876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("queueBuffer: slot=%d time=%lld", buf, timestamp); 4886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam sp<FrameAvailableListener> listener; 4906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { // scope for the lock 4926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 4936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 4946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!"); 4956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 4966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (buf < 0 || buf >= mBufferCount) { 4986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d", 4996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount, buf); 5006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 5026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot %d is not owned by the client " 5036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "(state=%d)", buf, mSlots[buf].mBufferState); 5046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (!mSlots[buf].mRequestBufferCalled) { 5066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot %d was enqueued without requesting a " 5076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "buffer", buf); 5086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSynchronousMode) { 5126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // In synchronous mode we queue all buffers in a FIFO. 5136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mQueue.push_back(buf); 5146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Synchronous mode always signals that an additional frame should 5166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // be consumed. 5176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam listener = mFrameAvailableListener; 5186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 5196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // In asynchronous mode we only keep the most recent buffer. 5206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mQueue.empty()) { 5216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mQueue.push_back(buf); 5226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Asynchronous mode only signals that a frame should be 5246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // consumed if no previous frame was pending. If a frame were 5256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // pending then the consumer would have already been notified. 5266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam listener = mFrameAvailableListener; 5276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 5286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Fifo::iterator front(mQueue.begin()); 5296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // buffer currently queued is freed 5306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[*front].mBufferState = BufferSlot::FREE; 5316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // and we record the new buffer index in the queued list 5326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *front = buf; 5336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mBufferState = BufferSlot::QUEUED; 5376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mCrop = mNextCrop; 5386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mTransform = mNextTransform; 5396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mScalingMode = mNextScalingMode; 5406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mTimestamp = timestamp; 5416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mFrameCounter++; 5426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mFrameNumber = mFrameCounter; 5436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 544333023884112259f145bb23c41a05211198d9792Daniel Lam mBufferHasBeenQueued = true; 5456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.signal(); 5466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outWidth = mDefaultWidth; 5486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outHeight = mDefaultHeight; 5496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outTransform = 0; 5506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } // scope for the lock 5516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // call back without lock held 5536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (listener != 0) { 5546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam listener->onFrameAvailable(); 5556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 5576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 5586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5596b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::cancelBuffer(int buf) { 5606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("cancelBuffer: slot=%d", buf); 5616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 5626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 5646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGW("cancelBuffer: BufferQueue has been abandoned!"); 5656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 5666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (buf < 0 || buf >= mBufferCount) { 5696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d", 5706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount, buf); 5716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 5726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 5736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)", 5746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam buf, mSlots[buf].mBufferState); 5756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 5766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mBufferState = BufferSlot::FREE; 5786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mFrameNumber = 0; 5796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.signal(); 5806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 5816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5826b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setCrop(const Rect& crop) { 5836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("setCrop: crop=[%d,%d,%d,%d]", crop.left, crop.top, crop.right, 5846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam crop.bottom); 5856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 5876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 5886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("setCrop: BufferQueue has been abandoned!"); 5896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 5906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mNextCrop = crop; 5926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 5936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 5946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5956b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setTransform(uint32_t transform) { 5966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("setTransform: xform=%#x", transform); 5976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 5986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 5996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("setTransform: BufferQueue has been abandoned!"); 6006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 6016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mNextTransform = transform; 6036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 6046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 6056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6066b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setScalingMode(int mode) { 6076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("setScalingMode: mode=%d", mode); 6086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam switch (mode) { 6106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_SCALING_MODE_FREEZE: 6116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 6126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam break; 6136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam default: 6146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("unknown scaling mode: %d", mode); 6156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 6166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 6196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mNextScalingMode = mode; 6206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 6216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 6226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6236b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::connect(int api, 6246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { 6256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("connect: api=%d", api); 6266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 6276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 6296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("connect: BufferQueue has been abandoned!"); 6306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 6316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int err = NO_ERROR; 6346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam switch (api) { 6356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_EGL: 6366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_CPU: 6376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_MEDIA: 6386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_CAMERA: 6396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mConnectedApi != NO_CONNECTED_API) { 6406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("connect: already connected (cur=%d, req=%d)", 6416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi, api); 6426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 6436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 6446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi = api; 6456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outWidth = mDefaultWidth; 6466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outHeight = mDefaultHeight; 6476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outTransform = 0; 6486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam break; 6506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam default: 6516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 6526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam break; 6536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 654333023884112259f145bb23c41a05211198d9792Daniel Lam 655333023884112259f145bb23c41a05211198d9792Daniel Lam mBufferHasBeenQueued = false; 656333023884112259f145bb23c41a05211198d9792Daniel Lam 6576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 6586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 6596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6606b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::disconnect(int api) { 6616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("disconnect: api=%d", api); 6626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 6636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 6656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // it is not really an error to disconnect after the surface 6666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // has been abandoned, it should just be a no-op. 6676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_ERROR; 6686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int err = NO_ERROR; 6716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam switch (api) { 6726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_EGL: 6736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_CPU: 6746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_MEDIA: 6756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_CAMERA: 6766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mConnectedApi == api) { 6776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam drainQueueAndFreeBuffersLocked(); 6786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi = NO_CONNECTED_API; 6796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mNextCrop.makeInvalid(); 6806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mNextScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; 6816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mNextTransform = 0; 6826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.signal(); 6836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 6846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)", 6856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi, api); 6866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 6876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam break; 6896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam default: 6906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("disconnect: unknown API %d", api); 6916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 6926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam break; 6936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 6956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 6966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 697333023884112259f145bb23c41a05211198d9792Daniel Lamvoid BufferQueue::dump(String8& result) const 698333023884112259f145bb23c41a05211198d9792Daniel Lam{ 699333023884112259f145bb23c41a05211198d9792Daniel Lam char buffer[1024]; 700333023884112259f145bb23c41a05211198d9792Daniel Lam BufferQueue::dump(result, "", buffer, 1024); 701333023884112259f145bb23c41a05211198d9792Daniel Lam} 702333023884112259f145bb23c41a05211198d9792Daniel Lam 703333023884112259f145bb23c41a05211198d9792Daniel Lamvoid BufferQueue::dump(String8& result, const char* prefix, 704333023884112259f145bb23c41a05211198d9792Daniel Lam char* buffer, size_t SIZE) const 705333023884112259f145bb23c41a05211198d9792Daniel Lam{ 706333023884112259f145bb23c41a05211198d9792Daniel Lam Mutex::Autolock _l(mMutex); 707333023884112259f145bb23c41a05211198d9792Daniel Lam snprintf(buffer, SIZE, 708333023884112259f145bb23c41a05211198d9792Daniel Lam "%snext : {crop=[%d,%d,%d,%d], transform=0x%02x}\n" 709333023884112259f145bb23c41a05211198d9792Daniel Lam ,prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right, 710333023884112259f145bb23c41a05211198d9792Daniel Lam mNextCrop.bottom, mNextTransform 711333023884112259f145bb23c41a05211198d9792Daniel Lam ); 712333023884112259f145bb23c41a05211198d9792Daniel Lam result.append(buffer); 713333023884112259f145bb23c41a05211198d9792Daniel Lam 714333023884112259f145bb23c41a05211198d9792Daniel Lam String8 fifo; 715333023884112259f145bb23c41a05211198d9792Daniel Lam int fifoSize = 0; 716333023884112259f145bb23c41a05211198d9792Daniel Lam Fifo::const_iterator i(mQueue.begin()); 717333023884112259f145bb23c41a05211198d9792Daniel Lam while (i != mQueue.end()) { 718333023884112259f145bb23c41a05211198d9792Daniel Lam snprintf(buffer, SIZE, "%02d ", *i++); 719333023884112259f145bb23c41a05211198d9792Daniel Lam fifoSize++; 720333023884112259f145bb23c41a05211198d9792Daniel Lam fifo.append(buffer); 721333023884112259f145bb23c41a05211198d9792Daniel Lam } 722333023884112259f145bb23c41a05211198d9792Daniel Lam 723333023884112259f145bb23c41a05211198d9792Daniel Lam snprintf(buffer, SIZE, 724333023884112259f145bb23c41a05211198d9792Daniel Lam "%s-BufferQueue mBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], " 725333023884112259f145bb23c41a05211198d9792Daniel Lam "mPixelFormat=%d, FIFO(%d)={%s}\n", 726333023884112259f145bb23c41a05211198d9792Daniel Lam prefix, mBufferCount, mSynchronousMode, mDefaultWidth, 727333023884112259f145bb23c41a05211198d9792Daniel Lam mDefaultHeight, mPixelFormat, fifoSize, fifo.string()); 728333023884112259f145bb23c41a05211198d9792Daniel Lam result.append(buffer); 729333023884112259f145bb23c41a05211198d9792Daniel Lam 730333023884112259f145bb23c41a05211198d9792Daniel Lam 731333023884112259f145bb23c41a05211198d9792Daniel Lam struct { 732333023884112259f145bb23c41a05211198d9792Daniel Lam const char * operator()(int state) const { 733333023884112259f145bb23c41a05211198d9792Daniel Lam switch (state) { 734333023884112259f145bb23c41a05211198d9792Daniel Lam case BufferSlot::DEQUEUED: return "DEQUEUED"; 735333023884112259f145bb23c41a05211198d9792Daniel Lam case BufferSlot::QUEUED: return "QUEUED"; 736333023884112259f145bb23c41a05211198d9792Daniel Lam case BufferSlot::FREE: return "FREE"; 737333023884112259f145bb23c41a05211198d9792Daniel Lam case BufferSlot::ACQUIRED: return "ACQUIRED"; 738333023884112259f145bb23c41a05211198d9792Daniel Lam default: return "Unknown"; 739333023884112259f145bb23c41a05211198d9792Daniel Lam } 740333023884112259f145bb23c41a05211198d9792Daniel Lam } 741333023884112259f145bb23c41a05211198d9792Daniel Lam } stateName; 742333023884112259f145bb23c41a05211198d9792Daniel Lam 743333023884112259f145bb23c41a05211198d9792Daniel Lam for (int i=0 ; i<mBufferCount ; i++) { 744333023884112259f145bb23c41a05211198d9792Daniel Lam const BufferSlot& slot(mSlots[i]); 745333023884112259f145bb23c41a05211198d9792Daniel Lam snprintf(buffer, SIZE, 746333023884112259f145bb23c41a05211198d9792Daniel Lam "%s%s[%02d] " 747333023884112259f145bb23c41a05211198d9792Daniel Lam "state=%-8s, crop=[%d,%d,%d,%d], " 748333023884112259f145bb23c41a05211198d9792Daniel Lam "transform=0x%02x, timestamp=%lld", 749333023884112259f145bb23c41a05211198d9792Daniel Lam prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i, 750333023884112259f145bb23c41a05211198d9792Daniel Lam stateName(slot.mBufferState), 751333023884112259f145bb23c41a05211198d9792Daniel Lam slot.mCrop.left, slot.mCrop.top, slot.mCrop.right, 752333023884112259f145bb23c41a05211198d9792Daniel Lam slot.mCrop.bottom, slot.mTransform, slot.mTimestamp 753333023884112259f145bb23c41a05211198d9792Daniel Lam ); 754333023884112259f145bb23c41a05211198d9792Daniel Lam result.append(buffer); 755333023884112259f145bb23c41a05211198d9792Daniel Lam 756333023884112259f145bb23c41a05211198d9792Daniel Lam const sp<GraphicBuffer>& buf(slot.mGraphicBuffer); 757333023884112259f145bb23c41a05211198d9792Daniel Lam if (buf != NULL) { 758333023884112259f145bb23c41a05211198d9792Daniel Lam snprintf(buffer, SIZE, 759333023884112259f145bb23c41a05211198d9792Daniel Lam ", %p [%4ux%4u:%4u,%3X]", 760333023884112259f145bb23c41a05211198d9792Daniel Lam buf->handle, buf->width, buf->height, buf->stride, 761333023884112259f145bb23c41a05211198d9792Daniel Lam buf->format); 762333023884112259f145bb23c41a05211198d9792Daniel Lam result.append(buffer); 763333023884112259f145bb23c41a05211198d9792Daniel Lam } 764333023884112259f145bb23c41a05211198d9792Daniel Lam result.append("\n"); 765333023884112259f145bb23c41a05211198d9792Daniel Lam } 766333023884112259f145bb23c41a05211198d9792Daniel Lam} 767333023884112259f145bb23c41a05211198d9792Daniel Lam 7686b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::freeBufferLocked(int i) { 7696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[i].mGraphicBuffer = 0; 7706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[i].mBufferState = BufferSlot::FREE; 7716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[i].mFrameNumber = 0; 772333023884112259f145bb23c41a05211198d9792Daniel Lam mSlots[i].mAcquireCalled = false; 773333023884112259f145bb23c41a05211198d9792Daniel Lam 774333023884112259f145bb23c41a05211198d9792Daniel Lam // destroy fence as BufferQueue now takes ownership 775333023884112259f145bb23c41a05211198d9792Daniel Lam if (mSlots[i].mFence != EGL_NO_SYNC_KHR) { 776333023884112259f145bb23c41a05211198d9792Daniel Lam eglDestroySyncKHR(mSlots[i].mEglDisplay, mSlots[i].mFence); 777333023884112259f145bb23c41a05211198d9792Daniel Lam mSlots[i].mFence = EGL_NO_SYNC_KHR; 7786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 7796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 7806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 7816b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::freeAllBuffersLocked() { 7826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ALOGW_IF(!mQueue.isEmpty(), 7836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "freeAllBuffersLocked called but mQueue is not empty"); 784333023884112259f145bb23c41a05211198d9792Daniel Lam mQueue.clear(); 785333023884112259f145bb23c41a05211198d9792Daniel Lam mBufferHasBeenQueued = false; 7866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 7876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeBufferLocked(i); 7886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 7896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 7906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 791333023884112259f145bb23c41a05211198d9792Daniel Lamstatus_t BufferQueue::acquire(BufferItem *buffer) { 792333023884112259f145bb23c41a05211198d9792Daniel Lam Mutex::Autolock _l(mMutex); 793333023884112259f145bb23c41a05211198d9792Daniel Lam // check if queue is empty 794333023884112259f145bb23c41a05211198d9792Daniel Lam // In asynchronous mode the list is guaranteed to be one buffer 795333023884112259f145bb23c41a05211198d9792Daniel Lam // deep, while in synchronous mode we use the oldest buffer. 796333023884112259f145bb23c41a05211198d9792Daniel Lam if (!mQueue.empty()) { 797333023884112259f145bb23c41a05211198d9792Daniel Lam Fifo::iterator front(mQueue.begin()); 798333023884112259f145bb23c41a05211198d9792Daniel Lam int buf = *front; 799333023884112259f145bb23c41a05211198d9792Daniel Lam 800333023884112259f145bb23c41a05211198d9792Daniel Lam if (mSlots[buf].mAcquireCalled) { 801333023884112259f145bb23c41a05211198d9792Daniel Lam buffer->mGraphicBuffer = NULL; 802333023884112259f145bb23c41a05211198d9792Daniel Lam } 803333023884112259f145bb23c41a05211198d9792Daniel Lam else { 804333023884112259f145bb23c41a05211198d9792Daniel Lam buffer->mGraphicBuffer = mSlots[buf].mGraphicBuffer; 805333023884112259f145bb23c41a05211198d9792Daniel Lam } 806333023884112259f145bb23c41a05211198d9792Daniel Lam buffer->mCrop = mSlots[buf].mCrop; 807333023884112259f145bb23c41a05211198d9792Daniel Lam buffer->mTransform = mSlots[buf].mTransform; 808333023884112259f145bb23c41a05211198d9792Daniel Lam buffer->mScalingMode = mSlots[buf].mScalingMode; 809333023884112259f145bb23c41a05211198d9792Daniel Lam buffer->mFrameNumber = mSlots[buf].mFrameNumber; 810333023884112259f145bb23c41a05211198d9792Daniel Lam buffer->mBuf = buf; 811333023884112259f145bb23c41a05211198d9792Daniel Lam mSlots[buf].mAcquireCalled = true; 812333023884112259f145bb23c41a05211198d9792Daniel Lam 813333023884112259f145bb23c41a05211198d9792Daniel Lam mSlots[buf].mBufferState = BufferSlot::ACQUIRED; 814333023884112259f145bb23c41a05211198d9792Daniel Lam mQueue.erase(front); 815333023884112259f145bb23c41a05211198d9792Daniel Lam } 816333023884112259f145bb23c41a05211198d9792Daniel Lam else { 817333023884112259f145bb23c41a05211198d9792Daniel Lam return -EINVAL; //should be a better return code 818333023884112259f145bb23c41a05211198d9792Daniel Lam } 819333023884112259f145bb23c41a05211198d9792Daniel Lam 820333023884112259f145bb23c41a05211198d9792Daniel Lam return OK; 821333023884112259f145bb23c41a05211198d9792Daniel Lam} 822333023884112259f145bb23c41a05211198d9792Daniel Lam 823333023884112259f145bb23c41a05211198d9792Daniel Lamstatus_t BufferQueue::releaseBuffer(int buf, EGLDisplay display, 824333023884112259f145bb23c41a05211198d9792Daniel Lam EGLSyncKHR fence) { 825333023884112259f145bb23c41a05211198d9792Daniel Lam Mutex::Autolock _l(mMutex); 826333023884112259f145bb23c41a05211198d9792Daniel Lam 827333023884112259f145bb23c41a05211198d9792Daniel Lam if (buf == INVALID_BUFFER_SLOT) { 828333023884112259f145bb23c41a05211198d9792Daniel Lam return -EINVAL; 829333023884112259f145bb23c41a05211198d9792Daniel Lam } 830333023884112259f145bb23c41a05211198d9792Daniel Lam 831333023884112259f145bb23c41a05211198d9792Daniel Lam mSlots[buf].mEglDisplay = display; 832333023884112259f145bb23c41a05211198d9792Daniel Lam mSlots[buf].mFence = fence; 833333023884112259f145bb23c41a05211198d9792Daniel Lam 834333023884112259f145bb23c41a05211198d9792Daniel Lam // The current buffer becomes FREE if it was still in the queued 835333023884112259f145bb23c41a05211198d9792Daniel Lam // state. If it has already been given to the client 836333023884112259f145bb23c41a05211198d9792Daniel Lam // (synchronous mode), then it stays in DEQUEUED state. 837333023884112259f145bb23c41a05211198d9792Daniel Lam if (mSlots[buf].mBufferState == BufferSlot::QUEUED 838333023884112259f145bb23c41a05211198d9792Daniel Lam || mSlots[buf].mBufferState == BufferSlot::ACQUIRED) { 839333023884112259f145bb23c41a05211198d9792Daniel Lam mSlots[buf].mBufferState = BufferSlot::FREE; 840333023884112259f145bb23c41a05211198d9792Daniel Lam } 841333023884112259f145bb23c41a05211198d9792Daniel Lam mDequeueCondition.signal(); 842333023884112259f145bb23c41a05211198d9792Daniel Lam 843333023884112259f145bb23c41a05211198d9792Daniel Lam return OK; 844333023884112259f145bb23c41a05211198d9792Daniel Lam} 845333023884112259f145bb23c41a05211198d9792Daniel Lam 846333023884112259f145bb23c41a05211198d9792Daniel Lamstatus_t BufferQueue::consumerDisconnect() { 847333023884112259f145bb23c41a05211198d9792Daniel Lam Mutex::Autolock lock(mMutex); 848333023884112259f145bb23c41a05211198d9792Daniel Lam // Once the SurfaceTexture disconnects, the BufferQueue 849333023884112259f145bb23c41a05211198d9792Daniel Lam // is considered abandoned 850333023884112259f145bb23c41a05211198d9792Daniel Lam mAbandoned = true; 851333023884112259f145bb23c41a05211198d9792Daniel Lam freeAllBuffersLocked(); 852333023884112259f145bb23c41a05211198d9792Daniel Lam mDequeueCondition.signal(); 853333023884112259f145bb23c41a05211198d9792Daniel Lam return OK; 854333023884112259f145bb23c41a05211198d9792Daniel Lam} 855333023884112259f145bb23c41a05211198d9792Daniel Lam 856333023884112259f145bb23c41a05211198d9792Daniel Lamstatus_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h) 857333023884112259f145bb23c41a05211198d9792Daniel Lam{ 858333023884112259f145bb23c41a05211198d9792Daniel Lam ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h); 859333023884112259f145bb23c41a05211198d9792Daniel Lam if (!w || !h) { 860333023884112259f145bb23c41a05211198d9792Daniel Lam ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)", 861333023884112259f145bb23c41a05211198d9792Daniel Lam w, h); 862333023884112259f145bb23c41a05211198d9792Daniel Lam return BAD_VALUE; 863333023884112259f145bb23c41a05211198d9792Daniel Lam } 864333023884112259f145bb23c41a05211198d9792Daniel Lam 865333023884112259f145bb23c41a05211198d9792Daniel Lam Mutex::Autolock lock(mMutex); 866333023884112259f145bb23c41a05211198d9792Daniel Lam mDefaultWidth = w; 867333023884112259f145bb23c41a05211198d9792Daniel Lam mDefaultHeight = h; 868333023884112259f145bb23c41a05211198d9792Daniel Lam return OK; 869333023884112259f145bb23c41a05211198d9792Daniel Lam} 870333023884112259f145bb23c41a05211198d9792Daniel Lam 871333023884112259f145bb23c41a05211198d9792Daniel Lamstatus_t BufferQueue::setBufferCountServer(int bufferCount) { 872333023884112259f145bb23c41a05211198d9792Daniel Lam Mutex::Autolock lock(mMutex); 873333023884112259f145bb23c41a05211198d9792Daniel Lam return setBufferCountServerLocked(bufferCount); 874333023884112259f145bb23c41a05211198d9792Daniel Lam} 875333023884112259f145bb23c41a05211198d9792Daniel Lam 8766b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::freeAllBuffersExceptHeadLocked() { 8776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ALOGW_IF(!mQueue.isEmpty(), 8786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "freeAllBuffersExceptCurrentLocked called but mQueue is not empty"); 8796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int head = -1; 8806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mQueue.empty()) { 8816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Fifo::iterator front(mQueue.begin()); 8826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam head = *front; 8836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 884333023884112259f145bb23c41a05211198d9792Daniel Lam mBufferHasBeenQueued = false; 8856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 8866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (i != head) { 8876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeBufferLocked(i); 8886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 8896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 8906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 8916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 8926b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::drainQueueLocked() { 8936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam while (mSynchronousMode && !mQueue.isEmpty()) { 8946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.wait(mMutex); 8956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 8966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("drainQueueLocked: BufferQueue has been abandoned!"); 8976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 8986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 8996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mConnectedApi == NO_CONNECTED_API) { 9006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("drainQueueLocked: BufferQueue is not connected!"); 9016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 9026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 9036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 9046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_ERROR; 9056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 9066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 9076b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::drainQueueAndFreeBuffersLocked() { 9086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t err = drainQueueLocked(); 9096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (err == NO_ERROR) { 9106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSynchronousMode) { 9116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeAllBuffersLocked(); 9126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 9136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeAllBuffersExceptHeadLocked(); 9146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 9156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 9166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 9176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 9186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 9196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}; // namespace android 920