BufferQueue.cpp revision 851ef8f1bfbb164d61b1528a529a464f0a60dbaf
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" 181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS 19fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis//#define LOG_NDEBUG 0 206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#define GL_GLEXT_PROTOTYPES 226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#define EGL_EGLEXT_PROTOTYPES 236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <EGL/egl.h> 256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <EGL/eglext.h> 266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <gui/BufferQueue.h> 2890ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/ISurfaceComposer.h> 296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <private/gui/ComposerService.h> 306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <utils/Log.h> 32eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#include <gui/SurfaceTexture.h> 331c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// This compile option causes SurfaceTexture to return the buffer that is currently 366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// attached to the GL texture from dequeueBuffer when no other buffers are 376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// available. It requires the drivers (Gralloc, GL, OMX IL, and Camera) to do 386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// implicit cross-process synchronization to prevent the buffer from being 396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// written to before the buffer has (a) been detached from the GL texture and 406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// (b) all GL reads from the buffer have completed. 41eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 42eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam// During refactoring, do not support dequeuing the current buffer 43eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#undef ALLOW_DEQUEUE_CURRENT_BUFFER 44eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER 466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER true 476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled" 486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#else 496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER false 506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#endif 516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// Macros for including the BufferQueue name in log messages 53eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 54eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 55eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 56eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 57eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 59546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian#define ATRACE_BUFFER_INDEX(index) \ 60546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian char ___traceBuf[1024]; \ 61546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian snprintf(___traceBuf, 1024, "%s: %d", mConsumerName.string(), (index)); \ 62546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf); 63546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 646b091c53000c843211c218ce40287a7edca9bc63Daniel Lamnamespace android { 656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// Get an ID that's unique within this process. 676b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatic int32_t createProcessUniqueId() { 686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam static volatile int32_t globalCounter = 0; 696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return android_atomic_inc(&globalCounter); 706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 726b091c53000c843211c218ce40287a7edca9bc63Daniel LamBufferQueue::BufferQueue( bool allowSynchronousMode ) : 736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDefaultWidth(1), 746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDefaultHeight(1), 756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mPixelFormat(PIXEL_FORMAT_RGBA_8888), 766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount(MIN_ASYNC_BUFFER_SLOTS), 776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mClientBufferCount(0), 786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS), 796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSynchronousMode(false), 806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mAllowSynchronousMode(allowSynchronousMode), 816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi(NO_CONNECTED_API), 826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mAbandoned(false), 83eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mFrameCounter(0), 84b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferHasBeenQueued(false), 85b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mDefaultBufferFormat(0), 86b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mConsumerUsageBits(0), 87b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mTransformHint(0) 886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{ 896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Choose a name using the PID and a process-unique ID. 90eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); 916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("BufferQueue"); 936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam sp<ISurfaceComposer> composer(ComposerService::getComposerService()); 946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mGraphicBufferAlloc = composer->createGraphicBufferAlloc(); 956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 976b091c53000c843211c218ce40287a7edca9bc63Daniel LamBufferQueue::~BufferQueue() { 986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("~BufferQueue"); 996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 1006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1016b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setBufferCountServerLocked(int bufferCount) { 1026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (bufferCount > NUM_BUFFER_SLOTS) 1036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 1046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // special-case, nothing to do 1066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (bufferCount == mBufferCount) 1076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 1086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mClientBufferCount && 1106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam bufferCount >= mBufferCount) { 1116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // easy, we just have more buffers 1126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount = bufferCount; 1136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mServerBufferCount = bufferCount; 11474ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 1156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 1166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // we're here because we're either 1176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - reducing the number of available buffers 1186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - or there is a client-buffer-count in effect 1196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // less than 2 buffers is never allowed 1216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (bufferCount < 2) 1226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 1236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // when there is non client-buffer-count in effect, the client is not 1256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // allowed to dequeue more than one buffer at a time, 1266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // so the next time they dequeue a buffer, we know that they don't 1276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // own one. the actual resizing will happen during the next 1286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // dequeueBuffer. 1296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mServerBufferCount = bufferCount; 131b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mDequeueCondition.broadcast(); 1326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 1346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 1356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 136eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lambool BufferQueue::isSynchronousMode() const { 137eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 138eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return mSynchronousMode; 139eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 140eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 141eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamvoid BufferQueue::setConsumerName(const String8& name) { 142eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 143eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mConsumerName = name; 144eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 145eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 146b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setDefaultBufferFormat(uint32_t defaultFormat) { 147b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 148b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mDefaultBufferFormat = defaultFormat; 149b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return OK; 150b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 151b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 152b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setConsumerUsageBits(uint32_t usage) { 153b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 154b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mConsumerUsageBits = usage; 155b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return OK; 156b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 157b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 158b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setTransformHint(uint32_t hint) { 159b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 160b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mTransformHint = hint; 161b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return OK; 162b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 163b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 1646b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setBufferCount(int bufferCount) { 1656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("setBufferCount: count=%d", bufferCount); 1666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 1676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 1696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!"); 1706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 1716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (bufferCount > NUM_BUFFER_SLOTS) { 1736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("setBufferCount: bufferCount larger than slots available"); 1746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 1756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Error out if the user has dequeued buffers 1786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam for (int i=0 ; i<mBufferCount ; i++) { 1796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) { 1806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("setBufferCount: client owns some buffers"); 1816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 1826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int minBufferSlots = mSynchronousMode ? 1866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS; 1876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (bufferCount == 0) { 1886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mClientBufferCount = 0; 1896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam bufferCount = (mServerBufferCount >= minBufferSlots) ? 1906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mServerBufferCount : minBufferSlots; 1916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return setBufferCountServerLocked(bufferCount); 1926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (bufferCount < minBufferSlots) { 1956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("setBufferCount: requested buffer count (%d) is less than " 1966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "minimum (%d)", bufferCount, minBufferSlots); 1976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 1986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // here we're guaranteed that the client doesn't have dequeued buffers 2016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // and will release all of its buffer references. 2026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeAllBuffersLocked(); 2036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount = bufferCount; 2046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mClientBufferCount = bufferCount; 205eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = false; 2066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mQueue.clear(); 20774ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 2086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 2096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 2106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 211b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lamint BufferQueue::query(int what, int* outValue) 212b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam{ 2131c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 214b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam Mutex::Autolock lock(mMutex); 215b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 216b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam if (mAbandoned) { 217b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam ST_LOGE("query: SurfaceTexture has been abandoned!"); 218b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return NO_INIT; 219b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam } 220b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 221b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam int value; 222b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam switch (what) { 223b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_WIDTH: 224b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mDefaultWidth; 225b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 226b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_HEIGHT: 227b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mDefaultHeight; 228b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 229b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_FORMAT: 230b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mPixelFormat; 231b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 232b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 233b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mSynchronousMode ? 234b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS; 235b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 236b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam default: 237b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return BAD_VALUE; 238b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam } 239b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam outValue[0] = value; 240b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return NO_ERROR; 241b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam} 242b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 2436b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 2441c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 2456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("requestBuffer: slot=%d", slot); 2466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 2476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 2486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!"); 2496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 2506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (slot < 0 || mBufferCount <= slot) { 2526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d", 2536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount, slot); 2546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 2556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[slot].mRequestBufferCalled = true; 2576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *buf = mSlots[slot].mGraphicBuffer; 2586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_ERROR; 2596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 2606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2616b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, 2626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam uint32_t format, uint32_t usage) { 2631c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 2646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage); 2656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if ((w && !h) || (!w && h)) { 2676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h); 2686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 2696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t returnFlags(OK); 2726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam EGLDisplay dpy = EGL_NO_DISPLAY; 2736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam EGLSyncKHR fence = EGL_NO_SYNC_KHR; 2746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { // Scope for the lock 2766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 2776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 278b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam if (format == 0) { 279b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam format = mDefaultBufferFormat; 280b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam } 281b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam // turn on usage bits the consumer requested 282b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam usage |= mConsumerUsageBits; 283b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 2846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int found = -1; 2856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int foundSync = -1; 2866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int dequeuedCount = 0; 2876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam bool tryAgain = true; 2886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam while (tryAgain) { 2896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 2906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!"); 2916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 2926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // We need to wait for the FIFO to drain if the number of buffer 2956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // needs to change. 2966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // 2976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // The condition "number of buffers needs to change" is true if 2986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - the client doesn't care about how many buffers there are 2996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - AND the actual number of buffer is different from what was 3006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // set in the last setBufferCountServer() 3016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - OR - 3026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // setBufferCountServer() was set to a value incompatible with 3036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // the synchronization mode (for instance because the sync mode 3046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // changed since) 3056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // 3066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // As long as this condition is true AND the FIFO is not empty, we 3076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // wait on mDequeueCondition. 3086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int minBufferCountNeeded = mSynchronousMode ? 3106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS; 3116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const bool numberOfBuffersNeedsToChange = !mClientBufferCount && 3136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ((mServerBufferCount != mBufferCount) || 3146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (mServerBufferCount < minBufferCountNeeded)); 3156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) { 3176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // wait for the FIFO to drain 3186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.wait(mMutex); 3196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // NOTE: we continue here because we need to reevaluate our 3206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // whole state (eg: we could be abandoned or disconnected) 3216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam continue; 3226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (numberOfBuffersNeedsToChange) { 3256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // here we're guaranteed that mQueue is empty 3266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeAllBuffersLocked(); 3276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount = mServerBufferCount; 3286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mBufferCount < minBufferCountNeeded) 3296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount = minBufferCountNeeded; 330eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = false; 3316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS; 3326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // look for a free buffer to give to the client 3356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam found = INVALID_BUFFER_SLOT; 3366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam foundSync = INVALID_BUFFER_SLOT; 3376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dequeuedCount = 0; 3386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam for (int i = 0; i < mBufferCount; i++) { 3396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int state = mSlots[i].mBufferState; 3406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (state == BufferSlot::DEQUEUED) { 3416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dequeuedCount++; 3426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 344eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // this logic used to be if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER) 345eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // but dequeuing the current buffer is disabled. 346eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (false) { 347eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // This functionality has been temporarily removed so 348eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // BufferQueue and SurfaceTexture can be refactored into 349eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // separate objects 3506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 3516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (state == BufferSlot::FREE) { 3526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam /* We return the oldest of the free buffers to avoid 3536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * stalling the producer if possible. This is because 3546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * the consumer may still have pending reads of the 3556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * buffers in flight. 3566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam */ 3576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam bool isOlder = mSlots[i].mFrameNumber < 3586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[found].mFrameNumber; 3596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (found < 0 || isOlder) { 3606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam foundSync = i; 3616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam found = i; 3626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // clients are not allowed to dequeue more than one buffer 3686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // if they didn't set a buffer count. 3696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mClientBufferCount && dequeuedCount) { 3706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without " 3716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "setting the buffer count"); 3726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 3736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // See whether a buffer has been queued since the last 3766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // setBufferCount so we know whether to perform the 3776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // MIN_UNDEQUEUED_BUFFERS check below. 378eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (mBufferHasBeenQueued) { 3796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // make sure the client is not trying to dequeue more buffers 3806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // than allowed. 3816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int avail = mBufferCount - (dequeuedCount+1); 3826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) { 3836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded " 3846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "(dequeued=%d)", 3856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode), 3866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dequeuedCount); 3876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EBUSY; 3886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 391c2c1f2f24cd70bdcf1958157bab38467bf0fdc71Daniel Lam // if no buffer is found, wait for a buffer to be released 392c2c1f2f24cd70bdcf1958157bab38467bf0fdc71Daniel Lam tryAgain = found == INVALID_BUFFER_SLOT; 3936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (tryAgain) { 3946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.wait(mMutex); 3956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (found == INVALID_BUFFER_SLOT) { 4006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // This should not happen. 4016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: no available buffer slots"); 4026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EBUSY; 4036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int buf = found; 4066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outBuf = found; 4076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 408546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 409546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 4106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const bool useDefaultSize = !w && !h; 4116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (useDefaultSize) { 4126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // use the default size 4136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam w = mDefaultWidth; 4146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam h = mDefaultHeight; 4156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const bool updateFormat = (format != 0); 4186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!updateFormat) { 4196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // keep the current (or default) format 4206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam format = mPixelFormat; 4216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // buffer is now in DEQUEUED (but can also be current at the same time, 4246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // if we're in synchronous mode) 4256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mBufferState = BufferSlot::DEQUEUED; 4266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer); 4286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if ((buffer == NULL) || 4296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->width) != w) || 4306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->height) != h) || 4316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->format) != format) || 4326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ((uint32_t(buffer->usage) & usage) != usage)) 4336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { 4346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam usage |= GraphicBuffer::USAGE_HW_TEXTURE; 4356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t error; 4366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam sp<GraphicBuffer> graphicBuffer( 4376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mGraphicBufferAlloc->createGraphicBuffer( 4386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam w, h, format, usage, &error)); 4396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (graphicBuffer == 0) { 4406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer " 4416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "failed"); 4426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return error; 4436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (updateFormat) { 4456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mPixelFormat = format; 4466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 447eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 448eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mAcquireCalled = false; 4496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mGraphicBuffer = graphicBuffer; 4506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mRequestBufferCalled = false; 4516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mFence = EGL_NO_SYNC_KHR; 452eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; 453eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 4546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION; 4556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dpy = mSlots[buf].mEglDisplay; 4586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam fence = mSlots[buf].mFence; 4596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mFence = EGL_NO_SYNC_KHR; 460eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } // end lock scope 4616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (fence != EGL_NO_SYNC_KHR) { 4636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000); 4646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // If something goes wrong, log the error, but return the buffer without 4656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // synchronizing access to it. It's too late at this point to abort the 4666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // dequeue operation. 4676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (result == EGL_FALSE) { 4686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ALOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError()); 4696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 4706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ALOGE("dequeueBuffer: timeout waiting for fence"); 4716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam eglDestroySyncKHR(dpy, fence); 4736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf, 4766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[*outBuf].mGraphicBuffer->handle, returnFlags); 4776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return returnFlags; 4796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 4806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4816b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setSynchronousMode(bool enabled) { 4821c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 4836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("setSynchronousMode: enabled=%d", enabled); 4846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 4856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 4876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!"); 4886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 4896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t err = OK; 4926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mAllowSynchronousMode && enabled) 4936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 4946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!enabled) { 4966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // going to asynchronous mode, drain the queue 4976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = drainQueueLocked(); 4986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (err != NO_ERROR) 4996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 5006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSynchronousMode != enabled) { 5036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - if we're going to asynchronous mode, the queue is guaranteed to be 5046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // empty here 5056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - if the client set the number of buffers, we're guaranteed that 5066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // we have at least 3 (because we don't allow less) 5076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSynchronousMode = enabled; 50874ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 5096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 5116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 5126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5136b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::queueBuffer(int buf, int64_t timestamp, 514851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian const Rect& crop, int scalingMode, uint32_t transform, 5156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { 5161c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 517546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 518546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 5196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("queueBuffer: slot=%d time=%lld", buf, timestamp); 5206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 521fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<ConsumerListener> listener; 5226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { // scope for the lock 5246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 5256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 5266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!"); 5276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 5286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (buf < 0 || buf >= mBufferCount) { 5306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d", 5316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount, buf); 5326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 5346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot %d is not owned by the client " 5356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "(state=%d)", buf, mSlots[buf].mBufferState); 5366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (!mSlots[buf].mRequestBufferCalled) { 5386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot %d was enqueued without requesting a " 5396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "buffer", buf); 5406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSynchronousMode) { 5446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // In synchronous mode we queue all buffers in a FIFO. 5456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mQueue.push_back(buf); 5466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Synchronous mode always signals that an additional frame should 5486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // be consumed. 549fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener = mConsumerListener; 5506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 5516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // In asynchronous mode we only keep the most recent buffer. 5526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mQueue.empty()) { 5536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mQueue.push_back(buf); 5546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Asynchronous mode only signals that a frame should be 5566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // consumed if no previous frame was pending. If a frame were 5576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // pending then the consumer would have already been notified. 558fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener = mConsumerListener; 5596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 5606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Fifo::iterator front(mQueue.begin()); 5616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // buffer currently queued is freed 5626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[*front].mBufferState = BufferSlot::FREE; 5636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // and we record the new buffer index in the queued list 5646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *front = buf; 5656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 568851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian switch (scalingMode) { 569851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian case NATIVE_WINDOW_SCALING_MODE_FREEZE: 570851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 571851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian break; 572851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian default: 573851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian ST_LOGE("unknown scaling mode: %d (ignoring)", scalingMode); 574851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian scalingMode = mSlots[buf].mScalingMode; 575851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian break; 576851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian } 577851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian 5786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mBufferState = BufferSlot::QUEUED; 579851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian mSlots[buf].mCrop = crop; 580851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian mSlots[buf].mTransform = transform; 581851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian mSlots[buf].mScalingMode = scalingMode; 5826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mTimestamp = timestamp; 5836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mFrameCounter++; 5846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mFrameNumber = mFrameCounter; 5856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 586eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = true; 58774ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 5886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outWidth = mDefaultWidth; 5906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outHeight = mDefaultHeight; 591b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam *outTransform = mTransformHint; 5921c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 5931c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_INT(mConsumerName.string(), mQueue.size()); 5946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } // scope for the lock 5956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // call back without lock held 5976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (listener != 0) { 5986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam listener->onFrameAvailable(); 5996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 6016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 6026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6036b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::cancelBuffer(int buf) { 6041c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 6056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("cancelBuffer: slot=%d", buf); 6066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 6076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 6096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGW("cancelBuffer: BufferQueue has been abandoned!"); 6106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 6116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (buf < 0 || buf >= mBufferCount) { 6146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d", 6156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mBufferCount, buf); 6166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 6176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 6186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)", 6196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam buf, mSlots[buf].mBufferState); 6206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 6216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mBufferState = BufferSlot::FREE; 6236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mFrameNumber = 0; 62474ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 6256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 6266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6276b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::connect(int api, 6286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { 6291c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 6306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("connect: api=%d", api); 6316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 6326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 6346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("connect: BufferQueue has been abandoned!"); 6356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 6366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 638fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mConsumerListener == NULL) { 639fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("connect: BufferQueue has no consumer!"); 640fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_INIT; 641fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 642fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 6436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int err = NO_ERROR; 6446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam switch (api) { 6456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_EGL: 6466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_CPU: 6476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_MEDIA: 6486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_CAMERA: 6496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mConnectedApi != NO_CONNECTED_API) { 6506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("connect: already connected (cur=%d, req=%d)", 6516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi, api); 6526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 6536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 6546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi = api; 6556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outWidth = mDefaultWidth; 6566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outHeight = mDefaultHeight; 6576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outTransform = 0; 6586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam break; 6606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam default: 6616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 6626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam break; 6636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 664eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 665eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = false; 666eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 6676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 6686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 6696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6706b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::disconnect(int api) { 6711c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 6726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("disconnect: api=%d", api); 6736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int err = NO_ERROR; 675fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<ConsumerListener> listener; 676fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 677fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis { // Scope for the lock 678fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis Mutex::Autolock lock(mMutex); 679fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 680fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mAbandoned) { 681fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // it is not really an error to disconnect after the surface 682fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // has been abandoned, it should just be a no-op. 683fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_ERROR; 684fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 685fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 686fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis switch (api) { 687fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_EGL: 688fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_CPU: 689fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_MEDIA: 690fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_CAMERA: 691fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mConnectedApi == api) { 692fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis drainQueueAndFreeBuffersLocked(); 693fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConnectedApi = NO_CONNECTED_API; 694fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mDequeueCondition.broadcast(); 695fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener = mConsumerListener; 696fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } else { 697fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)", 698fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConnectedApi, api); 699fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis err = -EINVAL; 700fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 701fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis break; 702fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis default: 703fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("disconnect: unknown API %d", api); 7046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 705fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis break; 706fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 7076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 708fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 709fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (listener != NULL) { 710fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener->onBuffersReleased(); 711fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 712fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 7136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 7146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 7156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 716eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamvoid BufferQueue::dump(String8& result) const 717eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam{ 718eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam char buffer[1024]; 719eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam BufferQueue::dump(result, "", buffer, 1024); 720eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 721eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 722eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamvoid BufferQueue::dump(String8& result, const char* prefix, 723eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam char* buffer, size_t SIZE) const 724eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam{ 725eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 726eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 727eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam String8 fifo; 728eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam int fifoSize = 0; 729eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Fifo::const_iterator i(mQueue.begin()); 730eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam while (i != mQueue.end()) { 731eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam snprintf(buffer, SIZE, "%02d ", *i++); 732eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam fifoSize++; 733eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam fifo.append(buffer); 734eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 735eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 736eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam snprintf(buffer, SIZE, 737eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam "%s-BufferQueue mBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], " 738eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam "mPixelFormat=%d, FIFO(%d)={%s}\n", 739eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam prefix, mBufferCount, mSynchronousMode, mDefaultWidth, 740eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mDefaultHeight, mPixelFormat, fifoSize, fifo.string()); 741eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam result.append(buffer); 742eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 743eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 744eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam struct { 745eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam const char * operator()(int state) const { 746eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam switch (state) { 747eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::DEQUEUED: return "DEQUEUED"; 748eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::QUEUED: return "QUEUED"; 749eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::FREE: return "FREE"; 750eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::ACQUIRED: return "ACQUIRED"; 751eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam default: return "Unknown"; 752eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 753eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 754eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } stateName; 755eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 756eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam for (int i=0 ; i<mBufferCount ; i++) { 757eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam const BufferSlot& slot(mSlots[i]); 758eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam snprintf(buffer, SIZE, 759eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam "%s%s[%02d] " 760eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam "state=%-8s, crop=[%d,%d,%d,%d], " 761eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam "transform=0x%02x, timestamp=%lld", 762eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i, 763eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam stateName(slot.mBufferState), 764eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam slot.mCrop.left, slot.mCrop.top, slot.mCrop.right, 765eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam slot.mCrop.bottom, slot.mTransform, slot.mTimestamp 766eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ); 767eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam result.append(buffer); 768eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 769eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam const sp<GraphicBuffer>& buf(slot.mGraphicBuffer); 770eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (buf != NULL) { 771eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam snprintf(buffer, SIZE, 772eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ", %p [%4ux%4u:%4u,%3X]", 773eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buf->handle, buf->width, buf->height, buf->stride, 774eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buf->format); 775eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam result.append(buffer); 776eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 777eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam result.append("\n"); 778eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 779eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 780eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 7816b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::freeBufferLocked(int i) { 7826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[i].mGraphicBuffer = 0; 7836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[i].mBufferState = BufferSlot::FREE; 7846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[i].mFrameNumber = 0; 785eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[i].mAcquireCalled = false; 786eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 787eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // destroy fence as BufferQueue now takes ownership 788eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (mSlots[i].mFence != EGL_NO_SYNC_KHR) { 789eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam eglDestroySyncKHR(mSlots[i].mEglDisplay, mSlots[i].mFence); 790eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[i].mFence = EGL_NO_SYNC_KHR; 7916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 7926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 7936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 7946b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::freeAllBuffersLocked() { 7956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ALOGW_IF(!mQueue.isEmpty(), 7966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "freeAllBuffersLocked called but mQueue is not empty"); 797eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mQueue.clear(); 798eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = false; 7996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 8006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeBufferLocked(i); 8016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 8026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 8036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 804fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisstatus_t BufferQueue::acquireBuffer(BufferItem *buffer) { 805546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_CALL(); 806eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 807eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // check if queue is empty 808eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // In asynchronous mode the list is guaranteed to be one buffer 809eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // deep, while in synchronous mode we use the oldest buffer. 810eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (!mQueue.empty()) { 811eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Fifo::iterator front(mQueue.begin()); 812eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam int buf = *front; 813eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 814546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 815546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 816eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (mSlots[buf].mAcquireCalled) { 817eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mGraphicBuffer = NULL; 818fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } else { 819eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mGraphicBuffer = mSlots[buf].mGraphicBuffer; 820eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 821eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mCrop = mSlots[buf].mCrop; 822eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mTransform = mSlots[buf].mTransform; 823eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mScalingMode = mSlots[buf].mScalingMode; 824eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mFrameNumber = mSlots[buf].mFrameNumber; 8253fcee50ffaeb745819356e395408b4d7e3239c13Daniel Lam buffer->mTimestamp = mSlots[buf].mTimestamp; 826eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mBuf = buf; 827eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mAcquireCalled = true; 828eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 829eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mBufferState = BufferSlot::ACQUIRED; 830eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mQueue.erase(front); 83174ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 8321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 8331c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_INT(mConsumerName.string(), mQueue.size()); 834fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } else { 835b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam // should be a better return code? 836b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return -EINVAL; 837eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 838eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 839eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return OK; 840eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 841eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 842eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatus_t BufferQueue::releaseBuffer(int buf, EGLDisplay display, 843eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam EGLSyncKHR fence) { 844546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_CALL(); 845546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 846546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 847eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 848eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 849eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (buf == INVALID_BUFFER_SLOT) { 850eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return -EINVAL; 851eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 852eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 853eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mEglDisplay = display; 854eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mFence = fence; 855eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 856eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // The current buffer becomes FREE if it was still in the queued 857eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // state. If it has already been given to the client 858eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // (synchronous mode), then it stays in DEQUEUED state. 859eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (mSlots[buf].mBufferState == BufferSlot::QUEUED 860eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam || mSlots[buf].mBufferState == BufferSlot::ACQUIRED) { 861eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mBufferState = BufferSlot::FREE; 862eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 86374ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 864eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 865eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return OK; 866eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 867eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 868fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisstatus_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListener) { 869fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("consumerConnect"); 870fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis Mutex::Autolock lock(mMutex); 871fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 872fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mAbandoned) { 873fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("consumerConnect: BufferQueue has been abandoned!"); 874fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_INIT; 875fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 876fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 877fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConsumerListener = consumerListener; 878fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 879fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return OK; 880fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 881fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 882eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatus_t BufferQueue::consumerDisconnect() { 883fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("consumerDisconnect"); 884eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 885b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 886fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mConsumerListener == NULL) { 887fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("consumerDisconnect: No consumer is connected!"); 888fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return -EINVAL; 889fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 890b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 891fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mAbandoned = true; 892fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConsumerListener = NULL; 893b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mQueue.clear(); 894eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam freeAllBuffersLocked(); 89574ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 896eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return OK; 897eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 898eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 899fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisstatus_t BufferQueue::getReleasedBuffers(uint32_t* slotMask) { 900fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("getReleasedBuffers"); 901fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis Mutex::Autolock lock(mMutex); 902fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 903fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mAbandoned) { 904fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("getReleasedBuffers: BufferQueue has been abandoned!"); 905fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_INIT; 906fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 907fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 908fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis uint32_t mask = 0; 909fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 910fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (!mSlots[i].mAcquireCalled) { 911fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mask |= 1 << i; 912fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 913fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 914fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis *slotMask = mask; 915fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 916fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("getReleasedBuffers: returning mask %#x", mask); 917fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_ERROR; 918fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 919fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 920eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatus_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h) 921eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam{ 922eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h); 923eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (!w || !h) { 924eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)", 925eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam w, h); 926eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return BAD_VALUE; 927eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 928eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 929eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 930eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mDefaultWidth = w; 931eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mDefaultHeight = h; 932eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return OK; 933eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 934eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 935eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatus_t BufferQueue::setBufferCountServer(int bufferCount) { 9361c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 937eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 938eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return setBufferCountServerLocked(bufferCount); 939eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 940eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 9416b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::freeAllBuffersExceptHeadLocked() { 9426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ALOGW_IF(!mQueue.isEmpty(), 9436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "freeAllBuffersExceptCurrentLocked called but mQueue is not empty"); 9446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int head = -1; 9456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mQueue.empty()) { 9466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Fifo::iterator front(mQueue.begin()); 9476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam head = *front; 9486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 949eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = false; 9506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 9516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (i != head) { 9526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeBufferLocked(i); 9536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 9546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 9556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 9566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 9576b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::drainQueueLocked() { 9586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam while (mSynchronousMode && !mQueue.isEmpty()) { 9596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.wait(mMutex); 9606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 9616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("drainQueueLocked: BufferQueue has been abandoned!"); 9626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 9636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 9646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mConnectedApi == NO_CONNECTED_API) { 9656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("drainQueueLocked: BufferQueue is not connected!"); 9666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 9676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 9686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 9696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_ERROR; 9706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 9716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 9726b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::drainQueueAndFreeBuffersLocked() { 9736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t err = drainQueueLocked(); 9746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (err == NO_ERROR) { 9756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSynchronousMode) { 9766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeAllBuffersLocked(); 9776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 9786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeAllBuffersExceptHeadLocked(); 9796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 9806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 9816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 9826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 9836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 984fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie GennisBufferQueue::ProxyConsumerListener::ProxyConsumerListener( 985fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis const wp<BufferQueue::ConsumerListener>& consumerListener): 986fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConsumerListener(consumerListener) {} 987fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 988fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie GennisBufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {} 989fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 990fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid BufferQueue::ProxyConsumerListener::onFrameAvailable() { 991fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote()); 992fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (listener != NULL) { 993fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener->onFrameAvailable(); 994fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 995fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 996fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 997fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid BufferQueue::ProxyConsumerListener::onBuffersReleased() { 998fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote()); 999fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (listener != NULL) { 1000fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener->onBuffersReleased(); 1001fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 1002fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 1003fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 10046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}; // namespace android 1005