BufferQueue.cpp revision 31a353da225af5329735451c761b430d82dfda1b
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) \ 60695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis if (ATRACE_ENABLED()) { \ 61695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis char ___traceBuf[1024]; \ 62695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis snprintf(___traceBuf, 1024, "%s: %d", mConsumerName.string(), \ 63695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis (index)); \ 64695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf); \ 65695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis } 66546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 676b091c53000c843211c218ce40287a7edca9bc63Daniel Lamnamespace android { 686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// Get an ID that's unique within this process. 706b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatic int32_t createProcessUniqueId() { 716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam static volatile int32_t globalCounter = 0; 726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return android_atomic_inc(&globalCounter); 736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 75cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennisstatic const char* scalingModeName(int scalingMode) { 76cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis switch (scalingMode) { 77cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE"; 78cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW"; 79cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP"; 80cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis default: return "Unknown"; 81cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis } 82cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis} 83cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis 843e87601170141229d661df93e2f59e1ced73474bMathias AgopianBufferQueue::BufferQueue(bool allowSynchronousMode, int bufferCount, 853e87601170141229d661df93e2f59e1ced73474bMathias Agopian const sp<IGraphicBufferAlloc>& allocator) : 866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDefaultWidth(1), 876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDefaultHeight(1), 88abe61bfda4938abd932465e27c29ba9e41aea606Daniel Lam mMinUndequeuedBuffers(bufferCount), 8931a353da225af5329735451c761b430d82dfda1bJamie Gennis mMaxBufferCount(bufferCount + 1), 9031a353da225af5329735451c761b430d82dfda1bJamie Gennis mDefaultMaxBufferCount(bufferCount + 1), 9131a353da225af5329735451c761b430d82dfda1bJamie Gennis mOverrideMaxBufferCount(0), 926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSynchronousMode(false), 936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mAllowSynchronousMode(allowSynchronousMode), 946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi(NO_CONNECTED_API), 956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mAbandoned(false), 96eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mFrameCounter(0), 97b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferHasBeenQueued(false), 981a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888), 99b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mConsumerUsageBits(0), 100b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mTransformHint(0) 1016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{ 1026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Choose a name using the PID and a process-unique ID. 103eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); 1046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("BufferQueue"); 1063e87601170141229d661df93e2f59e1ced73474bMathias Agopian if (allocator == NULL) { 1073e87601170141229d661df93e2f59e1ced73474bMathias Agopian sp<ISurfaceComposer> composer(ComposerService::getComposerService()); 1083e87601170141229d661df93e2f59e1ced73474bMathias Agopian mGraphicBufferAlloc = composer->createGraphicBufferAlloc(); 1093e87601170141229d661df93e2f59e1ced73474bMathias Agopian if (mGraphicBufferAlloc == 0) { 1103e87601170141229d661df93e2f59e1ced73474bMathias Agopian ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()"); 1113e87601170141229d661df93e2f59e1ced73474bMathias Agopian } 1123e87601170141229d661df93e2f59e1ced73474bMathias Agopian } else { 1133e87601170141229d661df93e2f59e1ced73474bMathias Agopian mGraphicBufferAlloc = allocator; 114abe61bfda4938abd932465e27c29ba9e41aea606Daniel Lam } 1156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 1166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1176b091c53000c843211c218ce40287a7edca9bc63Daniel LamBufferQueue::~BufferQueue() { 1186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("~BufferQueue"); 1196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 1206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 12131a353da225af5329735451c761b430d82dfda1bJamie Gennisstatus_t BufferQueue::setDefaultMaxBufferCountLocked(int count) { 12231a353da225af5329735451c761b430d82dfda1bJamie Gennis if (count > NUM_BUFFER_SLOTS) 1236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 1246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 12531a353da225af5329735451c761b430d82dfda1bJamie Gennis mDefaultMaxBufferCount = count; 1261a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 12731a353da225af5329735451c761b430d82dfda1bJamie Gennis if (count == mMaxBufferCount) 1286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 1296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 13031a353da225af5329735451c761b430d82dfda1bJamie Gennis if (!mOverrideMaxBufferCount && 13131a353da225af5329735451c761b430d82dfda1bJamie Gennis count >= mMaxBufferCount) { 1326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // easy, we just have more buffers 13331a353da225af5329735451c761b430d82dfda1bJamie Gennis mMaxBufferCount = count; 13474ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 1356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 1366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // we're here because we're either 1376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - reducing the number of available buffers 1386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - or there is a client-buffer-count in effect 1396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // less than 2 buffers is never allowed 14131a353da225af5329735451c761b430d82dfda1bJamie Gennis if (count < 2) 1426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 1436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 14431a353da225af5329735451c761b430d82dfda1bJamie Gennis // When there is no client-buffer-count in effect, the client is not 14531a353da225af5329735451c761b430d82dfda1bJamie Gennis // allowed to dequeue more than one buffer at a time, so the next time 14631a353da225af5329735451c761b430d82dfda1bJamie Gennis // they dequeue a buffer, we know that they don't own one. the actual 14731a353da225af5329735451c761b430d82dfda1bJamie Gennis // resizing will happen during the next dequeueBuffer. 1486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 14931a353da225af5329735451c761b430d82dfda1bJamie Gennis // We signal this condition in case there is already a blocked 15031a353da225af5329735451c761b430d82dfda1bJamie Gennis // dequeueBuffer call. 151b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mDequeueCondition.broadcast(); 1526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 1546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 1556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 156eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lambool BufferQueue::isSynchronousMode() const { 157eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 158eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return mSynchronousMode; 159eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 160eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 161eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamvoid BufferQueue::setConsumerName(const String8& name) { 162eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 163eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mConsumerName = name; 164eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 165eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 166b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setDefaultBufferFormat(uint32_t defaultFormat) { 167b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 168b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mDefaultBufferFormat = defaultFormat; 169b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return OK; 170b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 171b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 172b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setConsumerUsageBits(uint32_t usage) { 173b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 174b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mConsumerUsageBits = usage; 175b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return OK; 176b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 177b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 178b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setTransformHint(uint32_t hint) { 179b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 180b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mTransformHint = hint; 181b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return OK; 182b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 183b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 1846b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setBufferCount(int bufferCount) { 1856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("setBufferCount: count=%d", bufferCount); 1866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1879abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam sp<ConsumerListener> listener; 1889abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam { 1899abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam Mutex::Autolock lock(mMutex); 1906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1919abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (mAbandoned) { 1929abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!"); 1939abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return NO_INIT; 1949abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 1959abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (bufferCount > NUM_BUFFER_SLOTS) { 1969abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGE("setBufferCount: bufferCount larger than slots available"); 1979abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return BAD_VALUE; 1986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2009abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // Error out if the user has dequeued buffers 20131a353da225af5329735451c761b430d82dfda1bJamie Gennis for (int i=0 ; i<mMaxBufferCount ; i++) { 2029abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) { 2039abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGE("setBufferCount: client owns some buffers"); 2049abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return -EINVAL; 2059abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 2069abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 2076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 20831a353da225af5329735451c761b430d82dfda1bJamie Gennis const int minBufferSlots = getMinMaxBufferCountLocked(); 2099abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (bufferCount == 0) { 21031a353da225af5329735451c761b430d82dfda1bJamie Gennis mOverrideMaxBufferCount = 0; 21131a353da225af5329735451c761b430d82dfda1bJamie Gennis bufferCount = (mDefaultMaxBufferCount >= minBufferSlots) ? 21231a353da225af5329735451c761b430d82dfda1bJamie Gennis mDefaultMaxBufferCount : minBufferSlots; 21331a353da225af5329735451c761b430d82dfda1bJamie Gennis return setDefaultMaxBufferCountLocked(bufferCount); 2149abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 2159abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 2169abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (bufferCount < minBufferSlots) { 2179abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGE("setBufferCount: requested buffer count (%d) is less than " 2189abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam "minimum (%d)", bufferCount, minBufferSlots); 2199abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return BAD_VALUE; 2209abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 2219abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 2229abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // here we're guaranteed that the client doesn't have dequeued buffers 2239abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // and will release all of its buffer references. 2249abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam freeAllBuffersLocked(); 22531a353da225af5329735451c761b430d82dfda1bJamie Gennis mMaxBufferCount = bufferCount; 22631a353da225af5329735451c761b430d82dfda1bJamie Gennis mOverrideMaxBufferCount = bufferCount; 2279abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mBufferHasBeenQueued = false; 2289abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mQueue.clear(); 2299abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mDequeueCondition.broadcast(); 2309abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam listener = mConsumerListener; 2319abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } // scope for lock 2329abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 2339abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (listener != NULL) { 2349abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam listener->onBuffersReleased(); 2356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 2386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 2396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 240b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lamint BufferQueue::query(int what, int* outValue) 241b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam{ 2421c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 243b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam Mutex::Autolock lock(mMutex); 244b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 245b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam if (mAbandoned) { 246b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam ST_LOGE("query: SurfaceTexture has been abandoned!"); 247b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return NO_INIT; 248b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam } 249b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 250b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam int value; 251b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam switch (what) { 252b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_WIDTH: 253b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mDefaultWidth; 254b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 255b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_HEIGHT: 256b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mDefaultHeight; 257b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 258b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_FORMAT: 2591a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis value = mDefaultBufferFormat; 260b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 261b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 262b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mSynchronousMode ? 263abe61bfda4938abd932465e27c29ba9e41aea606Daniel Lam (mMinUndequeuedBuffers-1) : mMinUndequeuedBuffers; 264b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 2652488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: 2662488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian value = (mQueue.size() >= 2); 2672488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian break; 268b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam default: 269b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return BAD_VALUE; 270b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam } 271b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam outValue[0] = value; 272b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return NO_ERROR; 273b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam} 274b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 2756b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 2761c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 2776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("requestBuffer: slot=%d", slot); 2786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 2796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 2806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!"); 2816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 2826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 28331a353da225af5329735451c761b430d82dfda1bJamie Gennis if (slot < 0 || mMaxBufferCount <= slot) { 2846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d", 28531a353da225af5329735451c761b430d82dfda1bJamie Gennis mMaxBufferCount, slot); 2866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 2876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[slot].mRequestBufferCalled = true; 2896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *buf = mSlots[slot].mGraphicBuffer; 2906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_ERROR; 2916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 2926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 293f78575400977f644cf0b12beb2fa5fc278b6ed4cJesse Hallstatus_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence, 294f78575400977f644cf0b12beb2fa5fc278b6ed4cJesse Hall uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { 2951c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 2966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage); 2976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if ((w && !h) || (!w && h)) { 2996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h); 3006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 3016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t returnFlags(OK); 3046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam EGLDisplay dpy = EGL_NO_DISPLAY; 305c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; 3066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { // Scope for the lock 3086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 3096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 310b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam if (format == 0) { 311b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam format = mDefaultBufferFormat; 312b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam } 313b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam // turn on usage bits the consumer requested 314b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam usage |= mConsumerUsageBits; 315b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 3166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int found = -1; 3176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int dequeuedCount = 0; 3186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam bool tryAgain = true; 3196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam while (tryAgain) { 3206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 3216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!"); 3226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 3236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // We need to wait for the FIFO to drain if the number of buffer 3266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // needs to change. 3276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // 3286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // The condition "number of buffers needs to change" is true if 3296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - the client doesn't care about how many buffers there are 3306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - AND the actual number of buffer is different from what was 33131a353da225af5329735451c761b430d82dfda1bJamie Gennis // set in the last setDefaultMaxBufferCount() 3326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - OR - 33331a353da225af5329735451c761b430d82dfda1bJamie Gennis // setDefaultMaxBufferCount() was set to a value incompatible with 3346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // the synchronization mode (for instance because the sync mode 3356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // changed since) 3366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // 3376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // As long as this condition is true AND the FIFO is not empty, we 3386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // wait on mDequeueCondition. 3396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 34031a353da225af5329735451c761b430d82dfda1bJamie Gennis const int minBufferCountNeeded = getMinMaxBufferCountLocked(); 3416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 34231a353da225af5329735451c761b430d82dfda1bJamie Gennis const bool numberOfBuffersNeedsToChange = !mOverrideMaxBufferCount && 34331a353da225af5329735451c761b430d82dfda1bJamie Gennis ((mDefaultMaxBufferCount != mMaxBufferCount) || 34431a353da225af5329735451c761b430d82dfda1bJamie Gennis (mDefaultMaxBufferCount < minBufferCountNeeded)); 3456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) { 3476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // wait for the FIFO to drain 3486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.wait(mMutex); 3496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // NOTE: we continue here because we need to reevaluate our 3506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // whole state (eg: we could be abandoned or disconnected) 3516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam continue; 3526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (numberOfBuffersNeedsToChange) { 3556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // here we're guaranteed that mQueue is empty 3566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeAllBuffersLocked(); 35731a353da225af5329735451c761b430d82dfda1bJamie Gennis mMaxBufferCount = mDefaultMaxBufferCount; 35831a353da225af5329735451c761b430d82dfda1bJamie Gennis if (mMaxBufferCount < minBufferCountNeeded) 35931a353da225af5329735451c761b430d82dfda1bJamie Gennis mMaxBufferCount = minBufferCountNeeded; 360eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = false; 3616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS; 3626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // look for a free buffer to give to the client 3656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam found = INVALID_BUFFER_SLOT; 3666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dequeuedCount = 0; 36731a353da225af5329735451c761b430d82dfda1bJamie Gennis for (int i = 0; i < mMaxBufferCount; i++) { 3686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int state = mSlots[i].mBufferState; 3696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (state == BufferSlot::DEQUEUED) { 3706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dequeuedCount++; 3716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 373eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // this logic used to be if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER) 374eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // but dequeuing the current buffer is disabled. 375eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (false) { 376eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // This functionality has been temporarily removed so 377eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // BufferQueue and SurfaceTexture can be refactored into 378eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // separate objects 3796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 3806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (state == BufferSlot::FREE) { 3816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam /* We return the oldest of the free buffers to avoid 3826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * stalling the producer if possible. This is because 3836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * the consumer may still have pending reads of the 3846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * buffers in flight. 3856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam */ 3866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam bool isOlder = mSlots[i].mFrameNumber < 3876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[found].mFrameNumber; 3886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (found < 0 || isOlder) { 3896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam found = i; 3906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // clients are not allowed to dequeue more than one buffer 3966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // if they didn't set a buffer count. 39731a353da225af5329735451c761b430d82dfda1bJamie Gennis if (!mOverrideMaxBufferCount && dequeuedCount) { 3986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without " 3996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "setting the buffer count"); 4006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 4016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // See whether a buffer has been queued since the last 4046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // setBufferCount so we know whether to perform the 405abe61bfda4938abd932465e27c29ba9e41aea606Daniel Lam // mMinUndequeuedBuffers check below. 406eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (mBufferHasBeenQueued) { 4076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // make sure the client is not trying to dequeue more buffers 4086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // than allowed. 40931a353da225af5329735451c761b430d82dfda1bJamie Gennis const int avail = mMaxBufferCount - (dequeuedCount+1); 410abe61bfda4938abd932465e27c29ba9e41aea606Daniel Lam if (avail < (mMinUndequeuedBuffers-int(mSynchronousMode))) { 411abe61bfda4938abd932465e27c29ba9e41aea606Daniel Lam ST_LOGE("dequeueBuffer: mMinUndequeuedBuffers=%d exceeded " 4126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "(dequeued=%d)", 413abe61bfda4938abd932465e27c29ba9e41aea606Daniel Lam mMinUndequeuedBuffers-int(mSynchronousMode), 4146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dequeuedCount); 4156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EBUSY; 4166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 419c2c1f2f24cd70bdcf1958157bab38467bf0fdc71Daniel Lam // if no buffer is found, wait for a buffer to be released 420c2c1f2f24cd70bdcf1958157bab38467bf0fdc71Daniel Lam tryAgain = found == INVALID_BUFFER_SLOT; 4216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (tryAgain) { 4226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.wait(mMutex); 4236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (found == INVALID_BUFFER_SLOT) { 4286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // This should not happen. 4296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: no available buffer slots"); 4306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EBUSY; 4316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int buf = found; 4346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outBuf = found; 4356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 436546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 437546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 4386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const bool useDefaultSize = !w && !h; 4396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (useDefaultSize) { 4406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // use the default size 4416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam w = mDefaultWidth; 4426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam h = mDefaultHeight; 4436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // buffer is now in DEQUEUED (but can also be current at the same time, 4466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // if we're in synchronous mode) 4476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mBufferState = BufferSlot::DEQUEUED; 4486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer); 4506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if ((buffer == NULL) || 4516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->width) != w) || 4526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->height) != h) || 4536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->format) != format) || 4546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ((uint32_t(buffer->usage) & usage) != usage)) 4556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { 4566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t error; 4576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam sp<GraphicBuffer> graphicBuffer( 4586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mGraphicBufferAlloc->createGraphicBuffer( 4596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam w, h, format, usage, &error)); 4606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (graphicBuffer == 0) { 4616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer " 4626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "failed"); 4636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return error; 4646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 465eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 466eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mAcquireCalled = false; 4676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mGraphicBuffer = graphicBuffer; 4686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mRequestBufferCalled = false; 469c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 470c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mFence.clear(); 471eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; 472eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 4736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION; 4746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dpy = mSlots[buf].mEglDisplay; 477c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall eglFence = mSlots[buf].mEglFence; 478c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall outFence = mSlots[buf].mFence; 479c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 480c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mFence.clear(); 481eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } // end lock scope 4826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 483c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall if (eglFence != EGL_NO_SYNC_KHR) { 484c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000); 4856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // If something goes wrong, log the error, but return the buffer without 4866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // synchronizing access to it. It's too late at this point to abort the 4876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // dequeue operation. 4886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (result == EGL_FALSE) { 489b7a6b96301c00c630610df4cb55a45d666200817Jamie Gennis ST_LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError()); 4906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 491b7a6b96301c00c630610df4cb55a45d666200817Jamie Gennis ST_LOGE("dequeueBuffer: timeout waiting for fence"); 4926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 493c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall eglDestroySyncKHR(dpy, eglFence); 4946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf, 4976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[*outBuf].mGraphicBuffer->handle, returnFlags); 4986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return returnFlags; 5006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 5016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5026b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setSynchronousMode(bool enabled) { 5031c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 5046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("setSynchronousMode: enabled=%d", enabled); 5056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 5066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 5086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!"); 5096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 5106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t err = OK; 5136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mAllowSynchronousMode && enabled) 5146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 5156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!enabled) { 5176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // going to asynchronous mode, drain the queue 5186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = drainQueueLocked(); 5196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (err != NO_ERROR) 5206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 5216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSynchronousMode != enabled) { 5246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - if we're going to asynchronous mode, the queue is guaranteed to be 5256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // empty here 5266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - if the client set the number of buffers, we're guaranteed that 5276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // we have at least 3 (because we don't allow less) 5286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSynchronousMode = enabled; 52974ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 5306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 5326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 5336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 534f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopianstatus_t BufferQueue::queueBuffer(int buf, 535f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopian const QueueBufferInput& input, QueueBufferOutput* output) { 5361c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 537546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 538546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 539efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis Rect crop; 540efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis uint32_t transform; 541efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis int scalingMode; 542efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis int64_t timestamp; 543c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall sp<Fence> fence; 544efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis 545c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall input.deflate(×tamp, &crop, &scalingMode, &transform, &fence); 546efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis 547cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis ST_LOGV("queueBuffer: slot=%d time=%#llx crop=[%d,%d,%d,%d] tr=%#x " 548cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis "scale=%s", 549cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis buf, timestamp, crop.left, crop.top, crop.right, crop.bottom, 550cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis transform, scalingModeName(scalingMode)); 5516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 552fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<ConsumerListener> listener; 5536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { // scope for the lock 5556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 5566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 5576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!"); 5586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 5596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 56031a353da225af5329735451c761b430d82dfda1bJamie Gennis if (buf < 0 || buf >= mMaxBufferCount) { 5616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d", 56231a353da225af5329735451c761b430d82dfda1bJamie Gennis mMaxBufferCount, buf); 5636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 5656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot %d is not owned by the client " 5666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "(state=%d)", buf, mSlots[buf].mBufferState); 5676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (!mSlots[buf].mRequestBufferCalled) { 5696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot %d was enqueued without requesting a " 5706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "buffer", buf); 5716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 574d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer); 575d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight()); 576d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis Rect croppedCrop; 577d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis crop.intersect(bufferRect, &croppedCrop); 578d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis if (croppedCrop != crop) { 579d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis ST_LOGE("queueBuffer: crop rect is not contained within the " 580d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis "buffer in slot %d", buf); 581d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis return -EINVAL; 582d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis } 583d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis 5846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSynchronousMode) { 5856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // In synchronous mode we queue all buffers in a FIFO. 5866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mQueue.push_back(buf); 5876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Synchronous mode always signals that an additional frame should 5896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // be consumed. 590fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener = mConsumerListener; 5916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 5926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // In asynchronous mode we only keep the most recent buffer. 5936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mQueue.empty()) { 5946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mQueue.push_back(buf); 5956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Asynchronous mode only signals that a frame should be 5976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // consumed if no previous frame was pending. If a frame were 5986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // pending then the consumer would have already been notified. 599fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener = mConsumerListener; 6006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 6016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Fifo::iterator front(mQueue.begin()); 6026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // buffer currently queued is freed 6036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[*front].mBufferState = BufferSlot::FREE; 6046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // and we record the new buffer index in the queued list 6056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *front = buf; 6066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 609efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mSlots[buf].mTimestamp = timestamp; 610efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mSlots[buf].mCrop = crop; 611efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mSlots[buf].mTransform = transform; 612c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mFence = fence; 613f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopian 614851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian switch (scalingMode) { 615851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian case NATIVE_WINDOW_SCALING_MODE_FREEZE: 616851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 617016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 618851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian break; 619851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian default: 620851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian ST_LOGE("unknown scaling mode: %d (ignoring)", scalingMode); 621851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian scalingMode = mSlots[buf].mScalingMode; 622851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian break; 623851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian } 624851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian 6256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mBufferState = BufferSlot::QUEUED; 626851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian mSlots[buf].mScalingMode = scalingMode; 6276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mFrameCounter++; 6286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mFrameNumber = mFrameCounter; 6296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 630eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = true; 63174ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 6326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6332488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, 6342488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian mQueue.size()); 6351c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 6361c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_INT(mConsumerName.string(), mQueue.size()); 6376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } // scope for the lock 6386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // call back without lock held 6406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (listener != 0) { 6416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam listener->onFrameAvailable(); 6426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 6446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 6456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 646c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hallvoid BufferQueue::cancelBuffer(int buf, sp<Fence> fence) { 6471c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 6486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("cancelBuffer: slot=%d", buf); 6496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 6506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 6526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGW("cancelBuffer: BufferQueue has been abandoned!"); 6536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 6546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 65631a353da225af5329735451c761b430d82dfda1bJamie Gennis if (buf < 0 || buf >= mMaxBufferCount) { 6576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d", 65831a353da225af5329735451c761b430d82dfda1bJamie Gennis mMaxBufferCount, buf); 6596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 6606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 6616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)", 6626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam buf, mSlots[buf].mBufferState); 6636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 6646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mBufferState = BufferSlot::FREE; 6666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mFrameNumber = 0; 667c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mFence = fence; 66874ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 6696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 6706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 67124202f5676c32edeef6544cf36e06b9fc970dbdeMathias Agopianstatus_t BufferQueue::connect(int api, QueueBufferOutput* output) { 6721c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 6736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("connect: api=%d", api); 6746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 6756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 6776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("connect: BufferQueue has been abandoned!"); 6786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 6796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 681fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mConsumerListener == NULL) { 682fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("connect: BufferQueue has no consumer!"); 683fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_INIT; 684fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 685fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 6866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int err = NO_ERROR; 6876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam switch (api) { 6886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_EGL: 6896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_CPU: 6906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_MEDIA: 6916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_CAMERA: 6926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mConnectedApi != NO_CONNECTED_API) { 6936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("connect: already connected (cur=%d, req=%d)", 6946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi, api); 6956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 6966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 6976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi = api; 6982488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, 6992488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian mQueue.size()); 7006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 7016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam break; 7026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam default: 7036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 7046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam break; 7056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 706eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 707eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = false; 708eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 7096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 7106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 7116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 7126b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::disconnect(int api) { 7131c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 7146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("disconnect: api=%d", api); 7156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 7166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int err = NO_ERROR; 717fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<ConsumerListener> listener; 718fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 719fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis { // Scope for the lock 720fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis Mutex::Autolock lock(mMutex); 721fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 722fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mAbandoned) { 723fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // it is not really an error to disconnect after the surface 724fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // has been abandoned, it should just be a no-op. 725fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_ERROR; 726fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 727fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 728fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis switch (api) { 729fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_EGL: 730fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_CPU: 731fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_MEDIA: 732fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_CAMERA: 733fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mConnectedApi == api) { 734fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis drainQueueAndFreeBuffersLocked(); 735fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConnectedApi = NO_CONNECTED_API; 736fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mDequeueCondition.broadcast(); 737fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener = mConsumerListener; 738fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } else { 739fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)", 740fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConnectedApi, api); 741fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis err = -EINVAL; 742fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 743fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis break; 744fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis default: 745fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("disconnect: unknown API %d", api); 7466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 747fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis break; 748fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 7496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 750fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 751fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (listener != NULL) { 752fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener->onBuffersReleased(); 753fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 754fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 7556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 7566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 7576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 758eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamvoid BufferQueue::dump(String8& result) const 759eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam{ 760eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam char buffer[1024]; 761eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam BufferQueue::dump(result, "", buffer, 1024); 762eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 763eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 764eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamvoid BufferQueue::dump(String8& result, const char* prefix, 765eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam char* buffer, size_t SIZE) const 766eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam{ 767eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 768eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 769eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam String8 fifo; 770eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam int fifoSize = 0; 771eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Fifo::const_iterator i(mQueue.begin()); 772eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam while (i != mQueue.end()) { 773eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam snprintf(buffer, SIZE, "%02d ", *i++); 774eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam fifoSize++; 775eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam fifo.append(buffer); 776eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 777eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 778eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam snprintf(buffer, SIZE, 77931a353da225af5329735451c761b430d82dfda1bJamie Gennis "%s-BufferQueue mMaxBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], " 7801a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis "default-format=%d, FIFO(%d)={%s}\n", 78131a353da225af5329735451c761b430d82dfda1bJamie Gennis prefix, mMaxBufferCount, mSynchronousMode, mDefaultWidth, 7821a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mDefaultHeight, mDefaultBufferFormat, fifoSize, fifo.string()); 783eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam result.append(buffer); 784eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 785eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 786eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam struct { 787eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam const char * operator()(int state) const { 788eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam switch (state) { 789eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::DEQUEUED: return "DEQUEUED"; 790eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::QUEUED: return "QUEUED"; 791eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::FREE: return "FREE"; 792eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::ACQUIRED: return "ACQUIRED"; 793eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam default: return "Unknown"; 794eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 795eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 796eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } stateName; 797eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 79831a353da225af5329735451c761b430d82dfda1bJamie Gennis for (int i=0 ; i<mMaxBufferCount ; i++) { 799eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam const BufferSlot& slot(mSlots[i]); 800eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam snprintf(buffer, SIZE, 801eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam "%s%s[%02d] " 802eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam "state=%-8s, crop=[%d,%d,%d,%d], " 803cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis "xform=0x%02x, time=%#llx, scale=%s", 804eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i, 805eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam stateName(slot.mBufferState), 806eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam slot.mCrop.left, slot.mCrop.top, slot.mCrop.right, 807cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis slot.mCrop.bottom, slot.mTransform, slot.mTimestamp, 808cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis scalingModeName(slot.mScalingMode) 809eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ); 810eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam result.append(buffer); 811eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 812eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam const sp<GraphicBuffer>& buf(slot.mGraphicBuffer); 813eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (buf != NULL) { 814eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam snprintf(buffer, SIZE, 815eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ", %p [%4ux%4u:%4u,%3X]", 816eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buf->handle, buf->width, buf->height, buf->stride, 817eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buf->format); 818eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam result.append(buffer); 819eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 820eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam result.append("\n"); 821eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 822eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 823eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 8241a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid BufferQueue::freeBufferLocked(int slot) { 8251a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ST_LOGV("freeBufferLocked: slot=%d", slot); 8261a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mGraphicBuffer = 0; 8271a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) { 8281a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mNeedsCleanupOnRelease = true; 8299abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 8301a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mBufferState = BufferSlot::FREE; 8311a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mFrameNumber = 0; 8321a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mAcquireCalled = false; 833eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 834eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // destroy fence as BufferQueue now takes ownership 8351a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) { 8361a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence); 8371a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mEglFence = EGL_NO_SYNC_KHR; 8386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 8391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mFence.clear(); 8406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 8416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 8426b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::freeAllBuffersLocked() { 8436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ALOGW_IF(!mQueue.isEmpty(), 8446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "freeAllBuffersLocked called but mQueue is not empty"); 845eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mQueue.clear(); 846eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = false; 8476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 8486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeBufferLocked(i); 8496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 8506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 8516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 852fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisstatus_t BufferQueue::acquireBuffer(BufferItem *buffer) { 853546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_CALL(); 854eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 855eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // check if queue is empty 856eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // In asynchronous mode the list is guaranteed to be one buffer 857eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // deep, while in synchronous mode we use the oldest buffer. 858eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (!mQueue.empty()) { 859eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Fifo::iterator front(mQueue.begin()); 860eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam int buf = *front; 861eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 862546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 863546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 864eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (mSlots[buf].mAcquireCalled) { 865eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mGraphicBuffer = NULL; 866fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } else { 867eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mGraphicBuffer = mSlots[buf].mGraphicBuffer; 868eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 869eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mCrop = mSlots[buf].mCrop; 870eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mTransform = mSlots[buf].mTransform; 871eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mScalingMode = mSlots[buf].mScalingMode; 872eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mFrameNumber = mSlots[buf].mFrameNumber; 8733fcee50ffaeb745819356e395408b4d7e3239c13Daniel Lam buffer->mTimestamp = mSlots[buf].mTimestamp; 874eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mBuf = buf; 875b42b1ac1587aebda5e2f334d95b620271fafba4eJesse Hall buffer->mFence = mSlots[buf].mFence; 876eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 8771a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[buf].mAcquireCalled = true; 8781a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[buf].mNeedsCleanupOnRelease = false; 879eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mBufferState = BufferSlot::ACQUIRED; 8801a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[buf].mFence.clear(); 8811a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 882eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mQueue.erase(front); 88374ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 8841c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 8851c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_INT(mConsumerName.string(), mQueue.size()); 886fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } else { 887fbcda930dd8b2823cfeb160fd0131f5897b7522fDaniel Lam return NO_BUFFER_AVAILABLE; 888eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 889eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 890eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return OK; 891eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 892eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 893eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatus_t BufferQueue::releaseBuffer(int buf, EGLDisplay display, 894c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall EGLSyncKHR eglFence, const sp<Fence>& fence) { 895546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_CALL(); 896546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 897546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 898eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 899eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 900eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (buf == INVALID_BUFFER_SLOT) { 901eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return -EINVAL; 902eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 903eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 904eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mEglDisplay = display; 905c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mEglFence = eglFence; 906eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mFence = fence; 907eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 9089abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // The buffer can now only be released if its in the acquired state 9099abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) { 910eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mBufferState = BufferSlot::FREE; 9119abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } else if (mSlots[buf].mNeedsCleanupOnRelease) { 9129abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGV("releasing a stale buf %d its state was %d", buf, mSlots[buf].mBufferState); 9139abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mSlots[buf].mNeedsCleanupOnRelease = false; 9149abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return STALE_BUFFER_SLOT; 9159abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } else { 9169abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGE("attempted to release buf %d but its state was %d", buf, mSlots[buf].mBufferState); 9179abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return -EINVAL; 918eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 919eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 9209abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mDequeueCondition.broadcast(); 921eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return OK; 922eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 923eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 924fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisstatus_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListener) { 925fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("consumerConnect"); 926fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis Mutex::Autolock lock(mMutex); 927fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 928fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mAbandoned) { 929fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("consumerConnect: BufferQueue has been abandoned!"); 930fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_INIT; 931fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 932fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 933fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConsumerListener = consumerListener; 934fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 935fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return OK; 936fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 937fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 938eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatus_t BufferQueue::consumerDisconnect() { 939fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("consumerDisconnect"); 940eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 941b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 942fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mConsumerListener == NULL) { 943fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("consumerDisconnect: No consumer is connected!"); 944fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return -EINVAL; 945fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 946b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 947fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mAbandoned = true; 948fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConsumerListener = NULL; 949b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mQueue.clear(); 950eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam freeAllBuffersLocked(); 95174ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 952eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return OK; 953eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 954eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 955fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisstatus_t BufferQueue::getReleasedBuffers(uint32_t* slotMask) { 956fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("getReleasedBuffers"); 957fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis Mutex::Autolock lock(mMutex); 958fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 959fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mAbandoned) { 960fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("getReleasedBuffers: BufferQueue has been abandoned!"); 961fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_INIT; 962fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 963fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 964fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis uint32_t mask = 0; 965fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 966fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (!mSlots[i].mAcquireCalled) { 967fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mask |= 1 << i; 968fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 969fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 970fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis *slotMask = mask; 971fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 972fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("getReleasedBuffers: returning mask %#x", mask); 973fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_ERROR; 974fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 975fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 976eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatus_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h) 977eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam{ 978eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h); 979eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (!w || !h) { 980eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)", 981eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam w, h); 982eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return BAD_VALUE; 983eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 984eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 985eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 986eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mDefaultWidth = w; 987eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mDefaultHeight = h; 988eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return OK; 989eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 990eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 99131a353da225af5329735451c761b430d82dfda1bJamie Gennisstatus_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) { 9921c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 993eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 99431a353da225af5329735451c761b430d82dfda1bJamie Gennis return setDefaultMaxBufferCountLocked(bufferCount); 995eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 996eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 9976b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::freeAllBuffersExceptHeadLocked() { 9986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int head = -1; 9996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mQueue.empty()) { 10006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Fifo::iterator front(mQueue.begin()); 10016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam head = *front; 10026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1003eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = false; 10046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 10056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (i != head) { 10066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeBufferLocked(i); 10076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 10086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 10096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 10106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 10116b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::drainQueueLocked() { 10126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam while (mSynchronousMode && !mQueue.isEmpty()) { 10136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.wait(mMutex); 10146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 10156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("drainQueueLocked: BufferQueue has been abandoned!"); 10166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 10176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 10186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mConnectedApi == NO_CONNECTED_API) { 10196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("drainQueueLocked: BufferQueue is not connected!"); 10206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 10216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 10226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 10236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_ERROR; 10246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 10256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 10266b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::drainQueueAndFreeBuffersLocked() { 10276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t err = drainQueueLocked(); 10286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (err == NO_ERROR) { 10296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSynchronousMode) { 10306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeAllBuffersLocked(); 10316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 10326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeAllBuffersExceptHeadLocked(); 10336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 10346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 10356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 10366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 10376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 103831a353da225af5329735451c761b430d82dfda1bJamie Gennisint BufferQueue::getMinMaxBufferCountLocked() const { 103931a353da225af5329735451c761b430d82dfda1bJamie Gennis return mSynchronousMode ? mMinUndequeuedBuffers : mMinUndequeuedBuffers + 1; 104031a353da225af5329735451c761b430d82dfda1bJamie Gennis} 104131a353da225af5329735451c761b430d82dfda1bJamie Gennis 1042fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie GennisBufferQueue::ProxyConsumerListener::ProxyConsumerListener( 1043fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis const wp<BufferQueue::ConsumerListener>& consumerListener): 1044fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConsumerListener(consumerListener) {} 1045fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1046fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie GennisBufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {} 1047fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1048fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid BufferQueue::ProxyConsumerListener::onFrameAvailable() { 1049fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote()); 1050fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (listener != NULL) { 1051fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener->onFrameAvailable(); 1052fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 1053fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 1054fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1055fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid BufferQueue::ProxyConsumerListener::onBuffersReleased() { 1056fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote()); 1057fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (listener != NULL) { 1058fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener->onBuffersReleased(); 1059fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 1060fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 1061fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 10626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}; // namespace android 1063