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// Macros for including the BufferQueue name in log messages 36eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 37eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 38eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 39eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 40eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 42546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian#define ATRACE_BUFFER_INDEX(index) \ 43695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis if (ATRACE_ENABLED()) { \ 44695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis char ___traceBuf[1024]; \ 45695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis snprintf(___traceBuf, 1024, "%s: %d", mConsumerName.string(), \ 46695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis (index)); \ 47695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf); \ 48695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis } 49546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 506b091c53000c843211c218ce40287a7edca9bc63Daniel Lamnamespace android { 516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// Get an ID that's unique within this process. 536b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatic int32_t createProcessUniqueId() { 546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam static volatile int32_t globalCounter = 0; 556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return android_atomic_inc(&globalCounter); 566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 58cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennisstatic const char* scalingModeName(int scalingMode) { 59cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis switch (scalingMode) { 60cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE"; 61cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW"; 62cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP"; 63cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis default: return "Unknown"; 64cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis } 65cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis} 66cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis 6772f096fb1ad0a0deadbfac5f88627461905d38e8Jamie GennisBufferQueue::BufferQueue(bool allowSynchronousMode, 683e87601170141229d661df93e2f59e1ced73474bMathias Agopian const sp<IGraphicBufferAlloc>& allocator) : 696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDefaultWidth(1), 706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDefaultHeight(1), 7172f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis mMaxAcquiredBufferCount(1), 7272f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis mDefaultMaxBufferCount(2), 7331a353da225af5329735451c761b430d82dfda1bJamie Gennis mOverrideMaxBufferCount(0), 746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSynchronousMode(false), 756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mAllowSynchronousMode(allowSynchronousMode), 766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi(NO_CONNECTED_API), 776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mAbandoned(false), 78eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mFrameCounter(0), 79b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferHasBeenQueued(false), 801a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888), 81b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mConsumerUsageBits(0), 82b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mTransformHint(0) 836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{ 846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Choose a name using the PID and a process-unique ID. 85eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); 866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("BufferQueue"); 883e87601170141229d661df93e2f59e1ced73474bMathias Agopian if (allocator == NULL) { 893e87601170141229d661df93e2f59e1ced73474bMathias Agopian sp<ISurfaceComposer> composer(ComposerService::getComposerService()); 903e87601170141229d661df93e2f59e1ced73474bMathias Agopian mGraphicBufferAlloc = composer->createGraphicBufferAlloc(); 913e87601170141229d661df93e2f59e1ced73474bMathias Agopian if (mGraphicBufferAlloc == 0) { 923e87601170141229d661df93e2f59e1ced73474bMathias Agopian ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()"); 933e87601170141229d661df93e2f59e1ced73474bMathias Agopian } 943e87601170141229d661df93e2f59e1ced73474bMathias Agopian } else { 953e87601170141229d661df93e2f59e1ced73474bMathias Agopian mGraphicBufferAlloc = allocator; 96abe61bfda4938abd932465e27c29ba9e41aea606Daniel Lam } 976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 996b091c53000c843211c218ce40287a7edca9bc63Daniel LamBufferQueue::~BufferQueue() { 1006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("~BufferQueue"); 1016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 1026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 10331a353da225af5329735451c761b430d82dfda1bJamie Gennisstatus_t BufferQueue::setDefaultMaxBufferCountLocked(int count) { 104e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis if (count < 2 || count > NUM_BUFFER_SLOTS) 1056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 1066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 10731a353da225af5329735451c761b430d82dfda1bJamie Gennis mDefaultMaxBufferCount = count; 108e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis mDequeueCondition.broadcast(); 1091a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 1106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 1116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 1126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 113eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lambool BufferQueue::isSynchronousMode() const { 114eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 115eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return mSynchronousMode; 116eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 117eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 118eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamvoid BufferQueue::setConsumerName(const String8& name) { 119eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 120eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mConsumerName = name; 121eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 122eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 123b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setDefaultBufferFormat(uint32_t defaultFormat) { 124b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 125b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mDefaultBufferFormat = defaultFormat; 126b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return OK; 127b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 128b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 129b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setConsumerUsageBits(uint32_t usage) { 130b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 131b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mConsumerUsageBits = usage; 132b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return OK; 133b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 134b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 135b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setTransformHint(uint32_t hint) { 1366905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden ST_LOGV("setTransformHint: %02x", hint); 137b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 138b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mTransformHint = hint; 139b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return OK; 140b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 141b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 1426b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setBufferCount(int bufferCount) { 1436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("setBufferCount: count=%d", bufferCount); 1446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1459abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam sp<ConsumerListener> listener; 1469abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam { 1479abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam Mutex::Autolock lock(mMutex); 1486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1499abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (mAbandoned) { 1509abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!"); 1519abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return NO_INIT; 1529abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 1539abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (bufferCount > NUM_BUFFER_SLOTS) { 1549abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGE("setBufferCount: bufferCount larger than slots available"); 1559abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return BAD_VALUE; 1566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1589abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // Error out if the user has dequeued buffers 159e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis int maxBufferCount = getMaxBufferCountLocked(); 160e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis for (int i=0 ; i<maxBufferCount; i++) { 1619abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) { 1629abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGE("setBufferCount: client owns some buffers"); 1639abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return -EINVAL; 1649abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 1659abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 1666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 16731a353da225af5329735451c761b430d82dfda1bJamie Gennis const int minBufferSlots = getMinMaxBufferCountLocked(); 1689abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (bufferCount == 0) { 16931a353da225af5329735451c761b430d82dfda1bJamie Gennis mOverrideMaxBufferCount = 0; 170e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis mDequeueCondition.broadcast(); 171e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis return OK; 1729abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 1739abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 1749abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (bufferCount < minBufferSlots) { 1759abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGE("setBufferCount: requested buffer count (%d) is less than " 1769abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam "minimum (%d)", bufferCount, minBufferSlots); 1779abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return BAD_VALUE; 1789abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 1799abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 1809abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // here we're guaranteed that the client doesn't have dequeued buffers 1819abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // and will release all of its buffer references. 182e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // 183e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // XXX: Should this use drainQueueAndFreeBuffersLocked instead? 1849abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam freeAllBuffersLocked(); 18531a353da225af5329735451c761b430d82dfda1bJamie Gennis mOverrideMaxBufferCount = bufferCount; 1869abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mBufferHasBeenQueued = false; 1879abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mDequeueCondition.broadcast(); 1889abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam listener = mConsumerListener; 1899abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } // scope for lock 1909abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 1919abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (listener != NULL) { 1929abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam listener->onBuffersReleased(); 1936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 1966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 1976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 198b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lamint BufferQueue::query(int what, int* outValue) 199b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam{ 2001c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 201b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam Mutex::Autolock lock(mMutex); 202b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 203b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam if (mAbandoned) { 204b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam ST_LOGE("query: SurfaceTexture has been abandoned!"); 205b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return NO_INIT; 206b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam } 207b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 208b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam int value; 209b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam switch (what) { 210b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_WIDTH: 211b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mDefaultWidth; 212b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 213b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_HEIGHT: 214b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mDefaultHeight; 215b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 216b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_FORMAT: 2171a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis value = mDefaultBufferFormat; 218b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 219b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 22072f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis value = getMinUndequeuedBufferCountLocked(); 221b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 2222488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: 2232488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian value = (mQueue.size() >= 2); 2242488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian break; 225b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam default: 226b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return BAD_VALUE; 227b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam } 228b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam outValue[0] = value; 229b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return NO_ERROR; 230b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam} 231b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 2326b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 2331c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 2346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("requestBuffer: slot=%d", slot); 2356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 2366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 2376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!"); 2386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 2396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 240e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis int maxBufferCount = getMaxBufferCountLocked(); 241e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis if (slot < 0 || maxBufferCount <= slot) { 2426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d", 243e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis maxBufferCount, slot); 244e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis return BAD_VALUE; 245e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 246e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // XXX: I vaguely recall there was some reason this can be valid, but 247e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // for the life of me I can't recall under what circumstances that's 248e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // the case. 249e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis ST_LOGE("requestBuffer: slot %d is not owned by the client (state=%d)", 250e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis slot, mSlots[slot].mBufferState); 2516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 2526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[slot].mRequestBufferCalled = true; 2546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *buf = mSlots[slot].mGraphicBuffer; 2556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_ERROR; 2566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 2576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 258f78575400977f644cf0b12beb2fa5fc278b6ed4cJesse Hallstatus_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence, 259f78575400977f644cf0b12beb2fa5fc278b6ed4cJesse Hall uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { 2601c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 2616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage); 2626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if ((w && !h) || (!w && h)) { 2646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h); 2656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 2666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t returnFlags(OK); 2696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam EGLDisplay dpy = EGL_NO_DISPLAY; 270c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; 2716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { // Scope for the lock 2736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 2746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 275b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam if (format == 0) { 276b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam format = mDefaultBufferFormat; 277b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam } 278b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam // turn on usage bits the consumer requested 279b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam usage |= mConsumerUsageBits; 280b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 2816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int found = -1; 2826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int dequeuedCount = 0; 2836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam bool tryAgain = true; 2846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam while (tryAgain) { 2856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 2866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!"); 2876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 2886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 290e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis const int maxBufferCount = getMaxBufferCountLocked(); 2916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 292e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // Free up any buffers that are in slots beyond the max buffer 293e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // count. 294e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) { 295e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis assert(mSlots[i].mBufferState == BufferSlot::FREE); 296e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis if (mSlots[i].mGraphicBuffer != NULL) { 297e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis freeBufferLocked(i); 298e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS; 299e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis } 3006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // look for a free buffer to give to the client 3036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam found = INVALID_BUFFER_SLOT; 3046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dequeuedCount = 0; 305e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis for (int i = 0; i < maxBufferCount; i++) { 3066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int state = mSlots[i].mBufferState; 3076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (state == BufferSlot::DEQUEUED) { 3086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dequeuedCount++; 3096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3113fd12e41afcf323fdb99a4cf6bef0f904d72cc8bJamie Gennis if (state == BufferSlot::FREE) { 3123fd12e41afcf323fdb99a4cf6bef0f904d72cc8bJamie Gennis /* We return the oldest of the free buffers to avoid 3133fd12e41afcf323fdb99a4cf6bef0f904d72cc8bJamie Gennis * stalling the producer if possible. This is because 3143fd12e41afcf323fdb99a4cf6bef0f904d72cc8bJamie Gennis * the consumer may still have pending reads of the 3153fd12e41afcf323fdb99a4cf6bef0f904d72cc8bJamie Gennis * buffers in flight. 3163fd12e41afcf323fdb99a4cf6bef0f904d72cc8bJamie Gennis */ 3173fd12e41afcf323fdb99a4cf6bef0f904d72cc8bJamie Gennis bool isOlder = mSlots[i].mFrameNumber < 3183fd12e41afcf323fdb99a4cf6bef0f904d72cc8bJamie Gennis mSlots[found].mFrameNumber; 3193fd12e41afcf323fdb99a4cf6bef0f904d72cc8bJamie Gennis if (found < 0 || isOlder) { 3203fd12e41afcf323fdb99a4cf6bef0f904d72cc8bJamie Gennis found = i; 3216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // clients are not allowed to dequeue more than one buffer 3266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // if they didn't set a buffer count. 32731a353da225af5329735451c761b430d82dfda1bJamie Gennis if (!mOverrideMaxBufferCount && dequeuedCount) { 3286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without " 3296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "setting the buffer count"); 3306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 3316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // See whether a buffer has been queued since the last 33472f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis // setBufferCount so we know whether to perform the min undequeued 33572f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis // buffers check below. 336eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (mBufferHasBeenQueued) { 3376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // make sure the client is not trying to dequeue more buffers 3386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // than allowed. 33972f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis const int newUndequeuedCount = maxBufferCount - (dequeuedCount+1); 34072f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis const int minUndequeuedCount = getMinUndequeuedBufferCountLocked(); 34172f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis if (newUndequeuedCount < minUndequeuedCount) { 34272f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis ST_LOGE("dequeueBuffer: min undequeued buffer count (%d) " 34372f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis "exceeded (dequeued=%d undequeudCount=%d)", 34472f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis minUndequeuedCount, dequeuedCount, 34572f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis newUndequeuedCount); 3466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EBUSY; 3476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 350e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // If no buffer is found, wait for a buffer to be released or for 351e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // the max buffer count to change. 352c2c1f2f24cd70bdcf1958157bab38467bf0fdc71Daniel Lam tryAgain = found == INVALID_BUFFER_SLOT; 3536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (tryAgain) { 3546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.wait(mMutex); 3556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (found == INVALID_BUFFER_SLOT) { 3606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // This should not happen. 3616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: no available buffer slots"); 3626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EBUSY; 3636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int buf = found; 3666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outBuf = found; 3676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 368546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 369546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 3706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const bool useDefaultSize = !w && !h; 3716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (useDefaultSize) { 3726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // use the default size 3736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam w = mDefaultWidth; 3746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam h = mDefaultHeight; 3756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // buffer is now in DEQUEUED (but can also be current at the same time, 3786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // if we're in synchronous mode) 3796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mBufferState = BufferSlot::DEQUEUED; 3806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer); 3826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if ((buffer == NULL) || 3836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->width) != w) || 3846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->height) != h) || 3856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->format) != format) || 3866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ((uint32_t(buffer->usage) & usage) != usage)) 3876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { 388eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mAcquireCalled = false; 3891efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis mSlots[buf].mGraphicBuffer = NULL; 3906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mRequestBufferCalled = false; 391c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 392c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mFence.clear(); 393eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; 394eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 3956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION; 3966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dpy = mSlots[buf].mEglDisplay; 399c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall eglFence = mSlots[buf].mEglFence; 400c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall outFence = mSlots[buf].mFence; 401c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 402c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mFence.clear(); 403eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } // end lock scope 4046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4051efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis if (returnFlags & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) { 4061efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis status_t error; 4071efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis sp<GraphicBuffer> graphicBuffer( 4081efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis mGraphicBufferAlloc->createGraphicBuffer( 4091efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis w, h, format, usage, &error)); 4101efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis if (graphicBuffer == 0) { 4111efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer " 4121efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis "failed"); 4131efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis return error; 4141efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis } 4151efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis 4161efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis { // Scope for the lock 4171efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis Mutex::Autolock lock(mMutex); 4181efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis 4191efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis if (mAbandoned) { 4201efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!"); 4211efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis return NO_INIT; 4221efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis } 4231efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis 4241efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis mSlots[*outBuf].mGraphicBuffer = graphicBuffer; 4251efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis } 4261efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis } 4271efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis 4281efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis 429c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall if (eglFence != EGL_NO_SYNC_KHR) { 430c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000); 4316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // If something goes wrong, log the error, but return the buffer without 4326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // synchronizing access to it. It's too late at this point to abort the 4336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // dequeue operation. 4346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (result == EGL_FALSE) { 435b7a6b96301c00c630610df4cb55a45d666200817Jamie Gennis ST_LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError()); 4366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 437b7a6b96301c00c630610df4cb55a45d666200817Jamie Gennis ST_LOGE("dequeueBuffer: timeout waiting for fence"); 4386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 439c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall eglDestroySyncKHR(dpy, eglFence); 4406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf, 4436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[*outBuf].mGraphicBuffer->handle, returnFlags); 4446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return returnFlags; 4466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 4476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4486b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setSynchronousMode(bool enabled) { 4491c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 4506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("setSynchronousMode: enabled=%d", enabled); 4516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 4526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 4546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!"); 4556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 4566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t err = OK; 4596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mAllowSynchronousMode && enabled) 4606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 4616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!enabled) { 4636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // going to asynchronous mode, drain the queue 4646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = drainQueueLocked(); 4656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (err != NO_ERROR) 4666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 4676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSynchronousMode != enabled) { 4706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - if we're going to asynchronous mode, the queue is guaranteed to be 4716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // empty here 4726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // - if the client set the number of buffers, we're guaranteed that 4736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // we have at least 3 (because we don't allow less) 4746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSynchronousMode = enabled; 47574ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 4766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 4786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 4796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 480f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopianstatus_t BufferQueue::queueBuffer(int buf, 481f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopian const QueueBufferInput& input, QueueBufferOutput* output) { 4821c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 483546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 484546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 485efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis Rect crop; 486efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis uint32_t transform; 487efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis int scalingMode; 488efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis int64_t timestamp; 489c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall sp<Fence> fence; 490efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis 491c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall input.deflate(×tamp, &crop, &scalingMode, &transform, &fence); 492efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis 493cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis ST_LOGV("queueBuffer: slot=%d time=%#llx crop=[%d,%d,%d,%d] tr=%#x " 494cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis "scale=%s", 495cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis buf, timestamp, crop.left, crop.top, crop.right, crop.bottom, 496cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis transform, scalingModeName(scalingMode)); 4976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 498fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<ConsumerListener> listener; 4996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { // scope for the lock 5016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 5026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 5036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!"); 5046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 5056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 506e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis int maxBufferCount = getMaxBufferCountLocked(); 507e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis if (buf < 0 || buf >= maxBufferCount) { 5086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d", 509e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis maxBufferCount, buf); 5106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 5126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot %d is not owned by the client " 5136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "(state=%d)", buf, mSlots[buf].mBufferState); 5146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (!mSlots[buf].mRequestBufferCalled) { 5166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot %d was enqueued without requesting a " 5176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "buffer", buf); 5186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 521d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer); 522d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight()); 523d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis Rect croppedCrop; 524d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis crop.intersect(bufferRect, &croppedCrop); 525d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis if (croppedCrop != crop) { 526d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis ST_LOGE("queueBuffer: crop rect is not contained within the " 527d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis "buffer in slot %d", buf); 528d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis return -EINVAL; 529d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis } 530d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis 5316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSynchronousMode) { 5326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // In synchronous mode we queue all buffers in a FIFO. 5336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mQueue.push_back(buf); 5346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Synchronous mode always signals that an additional frame should 5366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // be consumed. 537fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener = mConsumerListener; 5386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 5396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // In asynchronous mode we only keep the most recent buffer. 5406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mQueue.empty()) { 5416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mQueue.push_back(buf); 5426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Asynchronous mode only signals that a frame should be 5446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // consumed if no previous frame was pending. If a frame were 5456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // pending then the consumer would have already been notified. 546fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener = mConsumerListener; 5476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 5486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Fifo::iterator front(mQueue.begin()); 5496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // buffer currently queued is freed 5506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[*front].mBufferState = BufferSlot::FREE; 5516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // and we record the new buffer index in the queued list 5526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *front = buf; 5536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 556efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mSlots[buf].mTimestamp = timestamp; 557efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mSlots[buf].mCrop = crop; 558efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mSlots[buf].mTransform = transform; 559c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mFence = fence; 560f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopian 561851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian switch (scalingMode) { 562851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian case NATIVE_WINDOW_SCALING_MODE_FREEZE: 563851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 564016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 565851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian break; 566851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian default: 567851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian ST_LOGE("unknown scaling mode: %d (ignoring)", scalingMode); 568851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian scalingMode = mSlots[buf].mScalingMode; 569851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian break; 570851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian } 571851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian 5726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mBufferState = BufferSlot::QUEUED; 573851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian mSlots[buf].mScalingMode = scalingMode; 5746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mFrameCounter++; 5756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mFrameNumber = mFrameCounter; 5766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 577eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = true; 57874ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 5796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5802488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, 5812488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian mQueue.size()); 5821c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 5831c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_INT(mConsumerName.string(), mQueue.size()); 5846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } // scope for the lock 5856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // call back without lock held 5876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (listener != 0) { 5886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam listener->onFrameAvailable(); 5896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return OK; 5916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 5926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 593c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hallvoid BufferQueue::cancelBuffer(int buf, sp<Fence> fence) { 5941c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 5956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("cancelBuffer: slot=%d", buf); 5966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 5976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 5996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGW("cancelBuffer: BufferQueue has been abandoned!"); 6006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 6016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 603e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis int maxBufferCount = getMaxBufferCountLocked(); 604e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis if (buf < 0 || buf >= maxBufferCount) { 6056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d", 606e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis maxBufferCount, buf); 6076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 6086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 6096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)", 6106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam buf, mSlots[buf].mBufferState); 6116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 6126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mBufferState = BufferSlot::FREE; 6146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mFrameNumber = 0; 615c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mFence = fence; 61674ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 6176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 6186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 61924202f5676c32edeef6544cf36e06b9fc970dbdeMathias Agopianstatus_t BufferQueue::connect(int api, QueueBufferOutput* output) { 6201c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 6216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("connect: api=%d", api); 6226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 6236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 6256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("connect: BufferQueue has been abandoned!"); 6266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 6276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 629fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mConsumerListener == NULL) { 630fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("connect: BufferQueue has no consumer!"); 631fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_INIT; 632fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 633fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 6346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int err = NO_ERROR; 6356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam switch (api) { 6366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_EGL: 6376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_CPU: 6386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_MEDIA: 6396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_CAMERA: 6406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mConnectedApi != NO_CONNECTED_API) { 6416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("connect: already connected (cur=%d, req=%d)", 6426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi, api); 6436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 6446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 6456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi = api; 6462488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, 6472488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian mQueue.size()); 6486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam break; 6506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam default: 6516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 6526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam break; 6536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 654eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 655eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = false; 656eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 6576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 6586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 6596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6606b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::disconnect(int api) { 6611c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 6626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("disconnect: api=%d", api); 6636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int err = NO_ERROR; 665fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<ConsumerListener> listener; 666fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 667fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis { // Scope for the lock 668fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis Mutex::Autolock lock(mMutex); 669fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 670fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mAbandoned) { 671fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // it is not really an error to disconnect after the surface 672fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // has been abandoned, it should just be a no-op. 673fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_ERROR; 674fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 675fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 676fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis switch (api) { 677fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_EGL: 678fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_CPU: 679fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_MEDIA: 680fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_CAMERA: 681fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mConnectedApi == api) { 682fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis drainQueueAndFreeBuffersLocked(); 683fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConnectedApi = NO_CONNECTED_API; 684fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mDequeueCondition.broadcast(); 685fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener = mConsumerListener; 686fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } else { 687fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)", 688fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConnectedApi, api); 689fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis err = -EINVAL; 690fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 691fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis break; 692fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis default: 693fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("disconnect: unknown API %d", api); 6946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 695fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis break; 696fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 6976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 698fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 699fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (listener != NULL) { 700fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener->onBuffersReleased(); 701fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 702fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 7036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 7046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 7056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 706eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamvoid BufferQueue::dump(String8& result) const 707eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam{ 708eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam char buffer[1024]; 709eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam BufferQueue::dump(result, "", buffer, 1024); 710eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 711eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 712eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamvoid BufferQueue::dump(String8& result, const char* prefix, 713eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam char* buffer, size_t SIZE) const 714eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam{ 715eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 716eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 717eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam String8 fifo; 718eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam int fifoSize = 0; 719eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Fifo::const_iterator i(mQueue.begin()); 720eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam while (i != mQueue.end()) { 721eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam snprintf(buffer, SIZE, "%02d ", *i++); 722eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam fifoSize++; 723eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam fifo.append(buffer); 724eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 725eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 726e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis int maxBufferCount = getMaxBufferCountLocked(); 727e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis 728eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam snprintf(buffer, SIZE, 729e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis "%s-BufferQueue maxBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], " 7306905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden "default-format=%d, transform-hint=%02x, FIFO(%d)={%s}\n", 731e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis prefix, maxBufferCount, mSynchronousMode, mDefaultWidth, 7326905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden mDefaultHeight, mDefaultBufferFormat, mTransformHint, 7336905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden fifoSize, fifo.string()); 734eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam result.append(buffer); 735eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 736eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 737eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam struct { 738eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam const char * operator()(int state) const { 739eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam switch (state) { 740eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::DEQUEUED: return "DEQUEUED"; 741eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::QUEUED: return "QUEUED"; 742eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::FREE: return "FREE"; 743eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::ACQUIRED: return "ACQUIRED"; 744eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam default: return "Unknown"; 745eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 746eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 747eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } stateName; 748eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 749e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis for (int i=0 ; i<maxBufferCount ; i++) { 750eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam const BufferSlot& slot(mSlots[i]); 751eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam snprintf(buffer, SIZE, 752eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam "%s%s[%02d] " 753eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam "state=%-8s, crop=[%d,%d,%d,%d], " 754cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis "xform=0x%02x, time=%#llx, scale=%s", 755eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i, 756eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam stateName(slot.mBufferState), 757eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam slot.mCrop.left, slot.mCrop.top, slot.mCrop.right, 758cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis slot.mCrop.bottom, slot.mTransform, slot.mTimestamp, 759cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis scalingModeName(slot.mScalingMode) 760eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ); 761eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam result.append(buffer); 762eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 763eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam const sp<GraphicBuffer>& buf(slot.mGraphicBuffer); 764eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (buf != NULL) { 765eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam snprintf(buffer, SIZE, 766eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ", %p [%4ux%4u:%4u,%3X]", 767eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buf->handle, buf->width, buf->height, buf->stride, 768eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buf->format); 769eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam result.append(buffer); 770eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 771eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam result.append("\n"); 772eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 773eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 774eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 7751a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid BufferQueue::freeBufferLocked(int slot) { 7761a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ST_LOGV("freeBufferLocked: slot=%d", slot); 7771a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mGraphicBuffer = 0; 7781a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) { 7791a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mNeedsCleanupOnRelease = true; 7809abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 7811a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mBufferState = BufferSlot::FREE; 7821a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mFrameNumber = 0; 7831a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mAcquireCalled = false; 784eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 785eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // destroy fence as BufferQueue now takes ownership 7861a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) { 7871a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence); 7881a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mEglFence = EGL_NO_SYNC_KHR; 7896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 7901a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mFence.clear(); 7916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 7926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 7936b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::freeAllBuffersLocked() { 7946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ALOGW_IF(!mQueue.isEmpty(), 7956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "freeAllBuffersLocked called but mQueue is not empty"); 796eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mQueue.clear(); 797eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = false; 7986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 7996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeBufferLocked(i); 8006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 8016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 8026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 803fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisstatus_t BufferQueue::acquireBuffer(BufferItem *buffer) { 804546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_CALL(); 805eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 8065e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis 8075e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis // Check that the consumer doesn't currently have the maximum number of 8085e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis // buffers acquired. We allow the max buffer count to be exceeded by one 8095e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis // buffer, so that the consumer can successfully set up the newly acquired 8105e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis // buffer before releasing the old one. 8115e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis int numAcquiredBuffers = 0; 8125e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 8135e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis if (mSlots[i].mBufferState == BufferSlot::ACQUIRED) { 8145e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis numAcquiredBuffers++; 8155e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis } 8165e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis } 8175e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis if (numAcquiredBuffers >= mMaxAcquiredBufferCount+1) { 8185e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis ST_LOGE("acquireBuffer: max acquired buffer count reached: %d (max=%d)", 8195e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis numAcquiredBuffers, mMaxAcquiredBufferCount); 8205e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis return INVALID_OPERATION; 8215e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis } 8225e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis 823eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // check if queue is empty 824eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // In asynchronous mode the list is guaranteed to be one buffer 825eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // deep, while in synchronous mode we use the oldest buffer. 826eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (!mQueue.empty()) { 827eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Fifo::iterator front(mQueue.begin()); 828eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam int buf = *front; 829eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 830546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 831546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 832eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (mSlots[buf].mAcquireCalled) { 833eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mGraphicBuffer = NULL; 834fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } else { 835eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mGraphicBuffer = mSlots[buf].mGraphicBuffer; 836eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 837eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mCrop = mSlots[buf].mCrop; 838eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mTransform = mSlots[buf].mTransform; 839eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mScalingMode = mSlots[buf].mScalingMode; 840eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mFrameNumber = mSlots[buf].mFrameNumber; 8413fcee50ffaeb745819356e395408b4d7e3239c13Daniel Lam buffer->mTimestamp = mSlots[buf].mTimestamp; 842eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buffer->mBuf = buf; 843b42b1ac1587aebda5e2f334d95b620271fafba4eJesse Hall buffer->mFence = mSlots[buf].mFence; 844eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 8451a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[buf].mAcquireCalled = true; 8461a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[buf].mNeedsCleanupOnRelease = false; 847eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mBufferState = BufferSlot::ACQUIRED; 8481a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[buf].mFence.clear(); 8491a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 850eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mQueue.erase(front); 85174ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 8521c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 8531c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_INT(mConsumerName.string(), mQueue.size()); 854fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } else { 855fbcda930dd8b2823cfeb160fd0131f5897b7522fDaniel Lam return NO_BUFFER_AVAILABLE; 856eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 857eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 858eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return OK; 859eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 860eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 861eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatus_t BufferQueue::releaseBuffer(int buf, EGLDisplay display, 862c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall EGLSyncKHR eglFence, const sp<Fence>& fence) { 863546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_CALL(); 864546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 865546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 866eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 867eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 868eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (buf == INVALID_BUFFER_SLOT) { 869eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return -EINVAL; 870eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 871eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 872eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mEglDisplay = display; 873c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mEglFence = eglFence; 874eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mFence = fence; 875eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 8769abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // The buffer can now only be released if its in the acquired state 8779abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) { 878eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mBufferState = BufferSlot::FREE; 8799abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } else if (mSlots[buf].mNeedsCleanupOnRelease) { 8809abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGV("releasing a stale buf %d its state was %d", buf, mSlots[buf].mBufferState); 8819abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mSlots[buf].mNeedsCleanupOnRelease = false; 8829abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return STALE_BUFFER_SLOT; 8839abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } else { 8849abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGE("attempted to release buf %d but its state was %d", buf, mSlots[buf].mBufferState); 8859abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return -EINVAL; 886eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 887eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 8889abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mDequeueCondition.broadcast(); 889eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return OK; 890eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 891eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 892fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisstatus_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListener) { 893fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("consumerConnect"); 894fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis Mutex::Autolock lock(mMutex); 895fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 896fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mAbandoned) { 897fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("consumerConnect: BufferQueue has been abandoned!"); 898fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_INIT; 899fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 900fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 901fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConsumerListener = consumerListener; 902fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 903fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return OK; 904fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 905fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 906eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatus_t BufferQueue::consumerDisconnect() { 907fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("consumerDisconnect"); 908eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 909b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 910fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mConsumerListener == NULL) { 911fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("consumerDisconnect: No consumer is connected!"); 912fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return -EINVAL; 913fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 914b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 915fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mAbandoned = true; 916fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConsumerListener = NULL; 917b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mQueue.clear(); 918eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam freeAllBuffersLocked(); 91974ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 920eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return OK; 921eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 922eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 923fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisstatus_t BufferQueue::getReleasedBuffers(uint32_t* slotMask) { 924fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("getReleasedBuffers"); 925fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis Mutex::Autolock lock(mMutex); 926fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 927fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mAbandoned) { 928fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("getReleasedBuffers: BufferQueue has been abandoned!"); 929fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_INIT; 930fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 931fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 932fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis uint32_t mask = 0; 933fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 934fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (!mSlots[i].mAcquireCalled) { 935fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mask |= 1 << i; 936fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 937fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 938fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis *slotMask = mask; 939fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 940fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("getReleasedBuffers: returning mask %#x", mask); 941fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_ERROR; 942fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 943fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 944eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatus_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h) 945eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam{ 946eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h); 947eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (!w || !h) { 948eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)", 949eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam w, h); 950eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return BAD_VALUE; 951eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 952eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 953eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 954eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mDefaultWidth = w; 955eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mDefaultHeight = h; 956eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return OK; 957eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 958eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 95931a353da225af5329735451c761b430d82dfda1bJamie Gennisstatus_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) { 9601c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 961eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 96231a353da225af5329735451c761b430d82dfda1bJamie Gennis return setDefaultMaxBufferCountLocked(bufferCount); 963eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 964eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 96572f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennisstatus_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { 96672f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis ATRACE_CALL(); 96772f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis Mutex::Autolock lock(mMutex); 968c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > MAX_MAX_ACQUIRED_BUFFERS) { 969c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis ST_LOGE("setMaxAcquiredBufferCount: invalid count specified: %d", 970c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis maxAcquiredBuffers); 971c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis return BAD_VALUE; 972c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis } 97372f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis if (mConnectedApi != NO_CONNECTED_API) { 97472f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis return INVALID_OPERATION; 97572f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis } 97672f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis mMaxAcquiredBufferCount = maxAcquiredBuffers; 97772f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis return OK; 97872f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis} 97972f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis 9806b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::freeAllBuffersExceptHeadLocked() { 9816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int head = -1; 9826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (!mQueue.empty()) { 9836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Fifo::iterator front(mQueue.begin()); 9846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam head = *front; 9856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 986eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = false; 9876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 9886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (i != head) { 9896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeBufferLocked(i); 9906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 9916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 9926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 9936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 9946b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::drainQueueLocked() { 9956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam while (mSynchronousMode && !mQueue.isEmpty()) { 9966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.wait(mMutex); 9976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 9986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("drainQueueLocked: BufferQueue has been abandoned!"); 9996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 10006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 10016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mConnectedApi == NO_CONNECTED_API) { 10026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("drainQueueLocked: BufferQueue is not connected!"); 10036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 10046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 10056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 10066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_ERROR; 10076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 10086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 10096b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::drainQueueAndFreeBuffersLocked() { 10106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t err = drainQueueLocked(); 10116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (err == NO_ERROR) { 10126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mSynchronousMode) { 10136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeAllBuffersLocked(); 10146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 10156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeAllBuffersExceptHeadLocked(); 10166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 10176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 10186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 10196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 10206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 102131a353da225af5329735451c761b430d82dfda1bJamie Gennisint BufferQueue::getMinMaxBufferCountLocked() const { 102272f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis return getMinUndequeuedBufferCountLocked() + 1; 102372f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis} 102472f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis 102572f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennisint BufferQueue::getMinUndequeuedBufferCountLocked() const { 102672f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis return mSynchronousMode ? mMaxAcquiredBufferCount : 102772f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis mMaxAcquiredBufferCount + 1; 102831a353da225af5329735451c761b430d82dfda1bJamie Gennis} 102931a353da225af5329735451c761b430d82dfda1bJamie Gennis 1030e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennisint BufferQueue::getMaxBufferCountLocked() const { 1031e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis int minMaxBufferCount = getMinMaxBufferCountLocked(); 1032e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis 1033e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis int maxBufferCount = mDefaultMaxBufferCount; 1034e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis if (maxBufferCount < minMaxBufferCount) { 1035e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis maxBufferCount = minMaxBufferCount; 1036e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis } 1037e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis if (mOverrideMaxBufferCount != 0) { 1038e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis assert(mOverrideMaxBufferCount >= minMaxBufferCount); 1039e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis maxBufferCount = mOverrideMaxBufferCount; 1040e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis } 1041e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis 1042e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // Any buffers that are dequeued by the producer or sitting in the queue 1043e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // waiting to be consumed need to have their slots preserved. Such 1044e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // buffers will temporarily keep the max buffer count up until the slots 1045e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // no longer need to be preserved. 1046e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) { 1047e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis BufferSlot::BufferState state = mSlots[i].mBufferState; 1048e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis if (state == BufferSlot::QUEUED || state == BufferSlot::DEQUEUED) { 1049e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis maxBufferCount = i + 1; 1050e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis } 1051e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis } 1052e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis 1053e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis return maxBufferCount; 1054e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis} 1055e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis 1056fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie GennisBufferQueue::ProxyConsumerListener::ProxyConsumerListener( 1057fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis const wp<BufferQueue::ConsumerListener>& consumerListener): 1058fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConsumerListener(consumerListener) {} 1059fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1060fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie GennisBufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {} 1061fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1062fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid BufferQueue::ProxyConsumerListener::onFrameAvailable() { 1063fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote()); 1064fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (listener != NULL) { 1065fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener->onFrameAvailable(); 1066fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 1067fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 1068fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1069fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid BufferQueue::ProxyConsumerListener::onBuffersReleased() { 1070fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote()); 1071fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (listener != NULL) { 1072fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener->onBuffersReleased(); 1073fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 1074fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 1075fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 10766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}; // namespace android 1077