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> 28a4e19521ac4563f2ff6517bcfd63d9b8d33a6d0bMathias Agopian#include <gui/IConsumerListener.h> 2990ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/ISurfaceComposer.h> 306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <private/gui/ComposerService.h> 316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <utils/Log.h> 331c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 347cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian#include <utils/CallStack.h> 356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// Macros for including the BufferQueue name in log messages 37eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 38eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 39eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 40eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 41eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 43546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian#define ATRACE_BUFFER_INDEX(index) \ 44695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis if (ATRACE_ENABLED()) { \ 45695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis char ___traceBuf[1024]; \ 46695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis snprintf(___traceBuf, 1024, "%s: %d", mConsumerName.string(), \ 47695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis (index)); \ 48695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf); \ 49695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis } 50546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 516b091c53000c843211c218ce40287a7edca9bc63Daniel Lamnamespace android { 526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// Get an ID that's unique within this process. 546b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatic int32_t createProcessUniqueId() { 556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam static volatile int32_t globalCounter = 0; 566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return android_atomic_inc(&globalCounter); 576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 59cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennisstatic const char* scalingModeName(int scalingMode) { 60cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis switch (scalingMode) { 61cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE"; 62cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW"; 63cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP"; 64cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis default: return "Unknown"; 65cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis } 66cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis} 67cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis 68595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias AgopianBufferQueue::BufferQueue(const sp<IGraphicBufferAlloc>& allocator) : 696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDefaultWidth(1), 706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDefaultHeight(1), 7172f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis mMaxAcquiredBufferCount(1), 7272f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis mDefaultMaxBufferCount(2), 7331a353da225af5329735451c761b430d82dfda1bJamie Gennis mOverrideMaxBufferCount(0), 74595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian mConsumerControlledByApp(false), 75595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian mDequeueBufferCannotBlock(false), 76ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mUseAsyncBuffer(true), 776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mConnectedApi(NO_CONNECTED_API), 786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mAbandoned(false), 79eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mFrameCounter(0), 80b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferHasBeenQueued(false), 811a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888), 82b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mConsumerUsageBits(0), 83b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mTransformHint(0) 846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{ 856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // Choose a name using the PID and a process-unique ID. 86eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); 876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("BufferQueue"); 893e87601170141229d661df93e2f59e1ced73474bMathias Agopian if (allocator == NULL) { 903e87601170141229d661df93e2f59e1ced73474bMathias Agopian sp<ISurfaceComposer> composer(ComposerService::getComposerService()); 913e87601170141229d661df93e2f59e1ced73474bMathias Agopian mGraphicBufferAlloc = composer->createGraphicBufferAlloc(); 923e87601170141229d661df93e2f59e1ced73474bMathias Agopian if (mGraphicBufferAlloc == 0) { 933e87601170141229d661df93e2f59e1ced73474bMathias Agopian ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()"); 943e87601170141229d661df93e2f59e1ced73474bMathias Agopian } 953e87601170141229d661df93e2f59e1ced73474bMathias Agopian } else { 963e87601170141229d661df93e2f59e1ced73474bMathias Agopian mGraphicBufferAlloc = allocator; 97abe61bfda4938abd932465e27c29ba9e41aea606Daniel Lam } 986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1006b091c53000c843211c218ce40287a7edca9bc63Daniel LamBufferQueue::~BufferQueue() { 1016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("~BufferQueue"); 1026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 1036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 10431a353da225af5329735451c761b430d82dfda1bJamie Gennisstatus_t BufferQueue::setDefaultMaxBufferCountLocked(int count) { 105ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian const int minBufferCount = mUseAsyncBuffer ? 2 : 1; 106ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (count < minBufferCount || count > NUM_BUFFER_SLOTS) 1076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 1086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 10931a353da225af5329735451c761b430d82dfda1bJamie Gennis mDefaultMaxBufferCount = count; 110e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis mDequeueCondition.broadcast(); 1111a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 112753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden return NO_ERROR; 1136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 1146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 115eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamvoid BufferQueue::setConsumerName(const String8& name) { 116eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 117eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mConsumerName = name; 118eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 119eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 120b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setDefaultBufferFormat(uint32_t defaultFormat) { 121b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 122b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mDefaultBufferFormat = defaultFormat; 123753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden return NO_ERROR; 124b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 125b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 126b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setConsumerUsageBits(uint32_t usage) { 127b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 128b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mConsumerUsageBits = usage; 129753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden return NO_ERROR; 130b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 131b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 132b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setTransformHint(uint32_t hint) { 1336905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden ST_LOGV("setTransformHint: %02x", hint); 134b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 135b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mTransformHint = hint; 136753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden return NO_ERROR; 137b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 138b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 1396b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setBufferCount(int bufferCount) { 1406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("setBufferCount: count=%d", bufferCount); 1416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 142a4e19521ac4563f2ff6517bcfd63d9b8d33a6d0bMathias Agopian sp<IConsumerListener> listener; 1439abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam { 1449abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam Mutex::Autolock lock(mMutex); 1456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1469abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (mAbandoned) { 1472adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("setBufferCount: BufferQueue has been abandoned!"); 1489abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return NO_INIT; 1499abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 1509abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (bufferCount > NUM_BUFFER_SLOTS) { 151753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden ST_LOGE("setBufferCount: bufferCount too large (max %d)", 152753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden NUM_BUFFER_SLOTS); 1539abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return BAD_VALUE; 1546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1569abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // Error out if the user has dequeued buffers 1577cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian for (int i=0 ; i<NUM_BUFFER_SLOTS; i++) { 1589abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) { 1599abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGE("setBufferCount: client owns some buffers"); 1609abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return -EINVAL; 1619abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 1629abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 1636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 1649abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (bufferCount == 0) { 16531a353da225af5329735451c761b430d82dfda1bJamie Gennis mOverrideMaxBufferCount = 0; 166e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis mDequeueCondition.broadcast(); 167753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden return NO_ERROR; 1689abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 1699abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 1707cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian // fine to assume async to false before we're setting the buffer count 1717cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian const int minBufferSlots = getMinMaxBufferCountLocked(false); 1729abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (bufferCount < minBufferSlots) { 1739abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGE("setBufferCount: requested buffer count (%d) is less than " 1749abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam "minimum (%d)", bufferCount, minBufferSlots); 1759abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return BAD_VALUE; 1769abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 1779abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 1789abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // here we're guaranteed that the client doesn't have dequeued buffers 1799e3cb55b8f6f007906872decfe3b8a2541e94dd2Lajos Molnar // and will release all of its buffer references. We don't clear the 1809e3cb55b8f6f007906872decfe3b8a2541e94dd2Lajos Molnar // queue, however, so currently queued buffers still get displayed. 1819abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam freeAllBuffersLocked(); 18231a353da225af5329735451c761b430d82dfda1bJamie Gennis mOverrideMaxBufferCount = bufferCount; 1839abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mDequeueCondition.broadcast(); 1849abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam listener = mConsumerListener; 1859abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } // scope for lock 1869abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 1879abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (listener != NULL) { 1889abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam listener->onBuffersReleased(); 1896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 1906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 191753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden return NO_ERROR; 1926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 1936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 194b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lamint BufferQueue::query(int what, int* outValue) 195b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam{ 1961c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 197b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam Mutex::Autolock lock(mMutex); 198b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 199b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam if (mAbandoned) { 2002adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("query: BufferQueue has been abandoned!"); 201b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return NO_INIT; 202b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam } 203b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 204b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam int value; 205b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam switch (what) { 206b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_WIDTH: 207b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mDefaultWidth; 208b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 209b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_HEIGHT: 210b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam value = mDefaultHeight; 211b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 212b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_FORMAT: 2131a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis value = mDefaultBufferFormat; 214b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 215b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 2167cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian value = getMinUndequeuedBufferCount(false); 217b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam break; 2182488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: 2192488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian value = (mQueue.size() >= 2); 2202488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian break; 221f7c6087bcc6a85cc82fd8dd83566550f880600ecEino-Ville Talvala case NATIVE_WINDOW_CONSUMER_USAGE_BITS: 222f7c6087bcc6a85cc82fd8dd83566550f880600ecEino-Ville Talvala value = mConsumerUsageBits; 223f7c6087bcc6a85cc82fd8dd83566550f880600ecEino-Ville Talvala break; 224b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam default: 225b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return BAD_VALUE; 226b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam } 227b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam outValue[0] = value; 228b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam return NO_ERROR; 229b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam} 230b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam 2316b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 2321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 2336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("requestBuffer: slot=%d", slot); 2346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 2356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 2362adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("requestBuffer: BufferQueue has been abandoned!"); 2376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 2386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2397cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian if (slot < 0 || slot >= NUM_BUFFER_SLOTS) { 2406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d", 2417cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian NUM_BUFFER_SLOTS, slot); 242e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis return BAD_VALUE; 243e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 244e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis ST_LOGE("requestBuffer: slot %d is not owned by the client (state=%d)", 245e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis slot, mSlots[slot].mBufferState); 2466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 2476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[slot].mRequestBufferCalled = true; 2496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *buf = mSlots[slot].mGraphicBuffer; 2506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_ERROR; 2516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 2526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2537cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopianstatus_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence, bool async, 254f78575400977f644cf0b12beb2fa5fc278b6ed4cJesse Hall uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { 2551c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 2566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage); 2576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if ((w && !h) || (!w && h)) { 2596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h); 2606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return BAD_VALUE; 2616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam status_t returnFlags(OK); 2646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam EGLDisplay dpy = EGL_NO_DISPLAY; 265c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; 2666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { // Scope for the lock 2686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 2696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 270b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam if (format == 0) { 271b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam format = mDefaultBufferFormat; 272b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam } 273b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam // turn on usage bits the consumer requested 274b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam usage |= mConsumerUsageBits; 275b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 2766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int found = -1; 2776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam bool tryAgain = true; 2786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam while (tryAgain) { 2796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 2802adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("dequeueBuffer: BufferQueue has been abandoned!"); 2816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 2826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 2836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 2847cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian const int maxBufferCount = getMaxBufferCountLocked(async); 2857cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian if (async && mOverrideMaxBufferCount) { 2867cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian // FIXME: some drivers are manually setting the buffer-count (which they 2877cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian // shouldn't), so we do this extra test here to handle that case. 2887cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian // This is TEMPORARY, until we get this fixed. 2897cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian if (mOverrideMaxBufferCount < maxBufferCount) { 2907cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian ST_LOGE("dequeueBuffer: async mode is invalid with buffercount override"); 2917cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian return BAD_VALUE; 2927cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian } 2937cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian } 2946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 295e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // Free up any buffers that are in slots beyond the max buffer 296e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // count. 297e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) { 298e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis assert(mSlots[i].mBufferState == BufferSlot::FREE); 299e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis if (mSlots[i].mGraphicBuffer != NULL) { 300e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis freeBufferLocked(i); 3012adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden returnFlags |= IGraphicBufferProducer::RELEASE_ALL_BUFFERS; 302e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis } 3036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // look for a free buffer to give to the client 3066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam found = INVALID_BUFFER_SLOT; 3076bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian int dequeuedCount = 0; 3086bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian int acquiredCount = 0; 309e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis for (int i = 0; i < maxBufferCount; i++) { 3106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int state = mSlots[i].mBufferState; 3116bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian switch (state) { 3126bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian case BufferSlot::DEQUEUED: 3136bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian dequeuedCount++; 3146bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian break; 3156bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian case BufferSlot::ACQUIRED: 3166bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian acquiredCount++; 3176bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian break; 3186bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian case BufferSlot::FREE: 3196bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian /* We return the oldest of the free buffers to avoid 3206bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian * stalling the producer if possible. This is because 3216bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian * the consumer may still have pending reads of the 3226bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian * buffers in flight. 3236bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian */ 3246bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian if ((found < 0) || 3256bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian mSlots[i].mFrameNumber < mSlots[found].mFrameNumber) { 3266bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian found = i; 3276bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian } 3286bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian break; 3296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // clients are not allowed to dequeue more than one buffer 3336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // if they didn't set a buffer count. 33431a353da225af5329735451c761b430d82dfda1bJamie Gennis if (!mOverrideMaxBufferCount && dequeuedCount) { 3356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without " 3366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "setting the buffer count"); 3376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 3386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // See whether a buffer has been queued since the last 34172f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis // setBufferCount so we know whether to perform the min undequeued 34272f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis // buffers check below. 343eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (mBufferHasBeenQueued) { 3446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // make sure the client is not trying to dequeue more buffers 3456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // than allowed. 34672f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis const int newUndequeuedCount = maxBufferCount - (dequeuedCount+1); 3477cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian const int minUndequeuedCount = getMinUndequeuedBufferCount(async); 34872f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis if (newUndequeuedCount < minUndequeuedCount) { 34972f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis ST_LOGE("dequeueBuffer: min undequeued buffer count (%d) " 35072f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis "exceeded (dequeued=%d undequeudCount=%d)", 35172f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis minUndequeuedCount, dequeuedCount, 35272f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis newUndequeuedCount); 3536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EBUSY; 3546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 357e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // If no buffer is found, wait for a buffer to be released or for 358e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // the max buffer count to change. 359c2c1f2f24cd70bdcf1958157bab38467bf0fdc71Daniel Lam tryAgain = found == INVALID_BUFFER_SLOT; 3606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (tryAgain) { 3616bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian // return an error if we're in "cannot block" mode (producer and consumer 3626bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian // are controlled by the application) -- however, the consumer is allowed 3636bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian // to acquire briefly an extra buffer (which could cause us to have to wait here) 3646bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian // and that's okay because we know the wait will be brief (it happens 3656bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian // if we dequeue a buffer while the consumer has acquired one but not released 3666bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian // the old one yet -- for e.g.: see GLConsumer::updateTexImage()). 3676bac363cbdca7f5c4135d66c0e379475ecbd7319Mathias Agopian if (mDequeueBufferCannotBlock && (acquiredCount <= mMaxAcquiredBufferCount)) { 368595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian ST_LOGE("dequeueBuffer: would block! returning an error instead."); 369595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian return WOULD_BLOCK; 370595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian } 3716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mDequeueCondition.wait(mMutex); 3726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (found == INVALID_BUFFER_SLOT) { 3776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // This should not happen. 3786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("dequeueBuffer: no available buffer slots"); 3796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EBUSY; 3806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const int buf = found; 3836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *outBuf = found; 3846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 385546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 386546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 3876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const bool useDefaultSize = !w && !h; 3886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (useDefaultSize) { 3896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // use the default size 3906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam w = mDefaultWidth; 3916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam h = mDefaultHeight; 3926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 3936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mBufferState = BufferSlot::DEQUEUED; 3956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 3966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer); 3976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if ((buffer == NULL) || 3986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->width) != w) || 3996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->height) != h) || 4006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam (uint32_t(buffer->format) != format) || 4016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ((uint32_t(buffer->usage) & usage) != usage)) 4026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { 403eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mAcquireCalled = false; 4041efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis mSlots[buf].mGraphicBuffer = NULL; 4056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mRequestBufferCalled = false; 406c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 4071df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis mSlots[buf].mFence = Fence::NO_FENCE; 408eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; 409eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 4102adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden returnFlags |= IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION; 4116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 413ba93b3f8e403636b614a4a379f9421bc70dca84fMathias Agopian 414ba93b3f8e403636b614a4a379f9421bc70dca84fMathias Agopian if (CC_UNLIKELY(mSlots[buf].mFence == NULL)) { 415ba93b3f8e403636b614a4a379f9421bc70dca84fMathias Agopian ST_LOGE("dequeueBuffer: about to return a NULL fence from mSlot. " 416ba93b3f8e403636b614a4a379f9421bc70dca84fMathias Agopian "buf=%d, w=%d, h=%d, format=%d", 417ba93b3f8e403636b614a4a379f9421bc70dca84fMathias Agopian buf, buffer->width, buffer->height, buffer->format); 418ba93b3f8e403636b614a4a379f9421bc70dca84fMathias Agopian } 419ba93b3f8e403636b614a4a379f9421bc70dca84fMathias Agopian 4206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam dpy = mSlots[buf].mEglDisplay; 421c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall eglFence = mSlots[buf].mEglFence; 4224c00cc11141da7d159eb2323b186ed344115c0f1Jesse Hall *outFence = mSlots[buf].mFence; 423c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 4241df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis mSlots[buf].mFence = Fence::NO_FENCE; 425eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } // end lock scope 4266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4272adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden if (returnFlags & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) { 4281efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis status_t error; 4291efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis sp<GraphicBuffer> graphicBuffer( 430ba93b3f8e403636b614a4a379f9421bc70dca84fMathias Agopian mGraphicBufferAlloc->createGraphicBuffer(w, h, format, usage, &error)); 4311efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis if (graphicBuffer == 0) { 432ba93b3f8e403636b614a4a379f9421bc70dca84fMathias Agopian ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer failed"); 4331efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis return error; 4341efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis } 4351efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis 4361efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis { // Scope for the lock 4371efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis Mutex::Autolock lock(mMutex); 4381efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis 4391efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis if (mAbandoned) { 4402adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("dequeueBuffer: BufferQueue has been abandoned!"); 4411efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis return NO_INIT; 4421efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis } 4431efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis 444c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mSlots[*outBuf].mFrameNumber = ~0; 4451efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis mSlots[*outBuf].mGraphicBuffer = graphicBuffer; 4461efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis } 4471efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis } 4481efe099a51e2231bd938a6afcf66e6584deec0f2Jamie Gennis 449c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall if (eglFence != EGL_NO_SYNC_KHR) { 450c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000); 4516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // If something goes wrong, log the error, but return the buffer without 4526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // synchronizing access to it. It's too late at this point to abort the 4536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // dequeue operation. 4546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (result == EGL_FALSE) { 455b7a6b96301c00c630610df4cb55a45d666200817Jamie Gennis ST_LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError()); 4566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 457b7a6b96301c00c630610df4cb55a45d666200817Jamie Gennis ST_LOGE("dequeueBuffer: timeout waiting for fence"); 4586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 459c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall eglDestroySyncKHR(dpy, eglFence); 4606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 4616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 462c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar ST_LOGV("dequeueBuffer: returning slot=%d/%llu buf=%p flags=%#x", *outBuf, 463c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mSlots[*outBuf].mFrameNumber, 4646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[*outBuf].mGraphicBuffer->handle, returnFlags); 4656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 4666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return returnFlags; 4676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 4686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 469f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopianstatus_t BufferQueue::queueBuffer(int buf, 470f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopian const QueueBufferInput& input, QueueBufferOutput* output) { 4711c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 472546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 473546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 474efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis Rect crop; 475efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis uint32_t transform; 476efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis int scalingMode; 477efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis int64_t timestamp; 4783c25621ad7d13f64d3ab95a27fa970fbc9998f73Andy McFadden bool isAutoTimestamp; 4797cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian bool async; 480c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall sp<Fence> fence; 481efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis 4823c25621ad7d13f64d3ab95a27fa970fbc9998f73Andy McFadden input.deflate(×tamp, &isAutoTimestamp, &crop, &scalingMode, &transform, 4833c25621ad7d13f64d3ab95a27fa970fbc9998f73Andy McFadden &async, &fence); 484efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis 4851df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (fence == NULL) { 4861df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis ST_LOGE("queueBuffer: fence is NULL"); 4871df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis return BAD_VALUE; 4881df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } 4891df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis 490c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar switch (scalingMode) { 491c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar case NATIVE_WINDOW_SCALING_MODE_FREEZE: 492c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 493c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 494c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: 495c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar break; 496c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar default: 497c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar ST_LOGE("unknown scaling mode: %d", scalingMode); 498c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar return -EINVAL; 499c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar } 5006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 501a4e19521ac4563f2ff6517bcfd63d9b8d33a6d0bMathias Agopian sp<IConsumerListener> listener; 5026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam { // scope for the lock 5046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 505c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar 5066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 5072adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("queueBuffer: BufferQueue has been abandoned!"); 5086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 5096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5107cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian 5117cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian const int maxBufferCount = getMaxBufferCountLocked(async); 5127cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian if (async && mOverrideMaxBufferCount) { 5137cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian // FIXME: some drivers are manually setting the buffer-count (which they 5147cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian // shouldn't), so we do this extra test here to handle that case. 5157cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian // This is TEMPORARY, until we get this fixed. 5167cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian if (mOverrideMaxBufferCount < maxBufferCount) { 5177cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian ST_LOGE("queueBuffer: async mode is invalid with buffercount override"); 5187cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian return BAD_VALUE; 5197cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian } 5207cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian } 521e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis if (buf < 0 || buf >= maxBufferCount) { 5226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d", 523e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis maxBufferCount, buf); 5246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 5266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot %d is not owned by the client " 5276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "(state=%d)", buf, mSlots[buf].mBufferState); 5286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (!mSlots[buf].mRequestBufferCalled) { 5306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("queueBuffer: slot %d was enqueued without requesting a " 5316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam "buffer", buf); 5326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return -EINVAL; 5336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 535c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar ST_LOGV("queueBuffer: slot=%d/%llu time=%#llx crop=[%d,%d,%d,%d] " 536c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar "tr=%#x scale=%s", 537c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar buf, mFrameCounter + 1, timestamp, 538c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar crop.left, crop.top, crop.right, crop.bottom, 539c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar transform, scalingModeName(scalingMode)); 540c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar 541d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer); 542d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight()); 543d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis Rect croppedCrop; 544d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis crop.intersect(bufferRect, &croppedCrop); 545d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis if (croppedCrop != crop) { 546d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis ST_LOGE("queueBuffer: crop rect is not contained within the " 547d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis "buffer in slot %d", buf); 548d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis return -EINVAL; 549d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis } 550d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis 551c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mSlots[buf].mFence = fence; 552c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mSlots[buf].mBufferState = BufferSlot::QUEUED; 553c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mFrameCounter++; 554c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mSlots[buf].mFrameNumber = mFrameCounter; 555c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar 556c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar BufferItem item; 557c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar item.mAcquireCalled = mSlots[buf].mAcquireCalled; 558c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar item.mGraphicBuffer = mSlots[buf].mGraphicBuffer; 559c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar item.mCrop = crop; 560c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian item.mTransform = transform & ~NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; 561c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian item.mTransformToDisplayInverse = bool(transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY); 562c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar item.mScalingMode = scalingMode; 563c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar item.mTimestamp = timestamp; 5643c25621ad7d13f64d3ab95a27fa970fbc9998f73Andy McFadden item.mIsAutoTimestamp = isAutoTimestamp; 565c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar item.mFrameNumber = mFrameCounter; 566c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar item.mBuf = buf; 567c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar item.mFence = fence; 5687cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian item.mIsDroppable = mDequeueBufferCannotBlock || async; 569c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar 570a3fbda3cef04d51a35a3eb64b2f744a989800856Mathias Agopian if (mQueue.empty()) { 571a3fbda3cef04d51a35a3eb64b2f744a989800856Mathias Agopian // when the queue is empty, we can ignore "mDequeueBufferCannotBlock", and 572a3fbda3cef04d51a35a3eb64b2f744a989800856Mathias Agopian // simply queue this buffer. 573c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mQueue.push_back(item); 574fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener = mConsumerListener; 5756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else { 576a3fbda3cef04d51a35a3eb64b2f744a989800856Mathias Agopian // when the queue is not empty, we need to look at the front buffer 577a3fbda3cef04d51a35a3eb64b2f744a989800856Mathias Agopian // state and see if we need to replace it. 578a3fbda3cef04d51a35a3eb64b2f744a989800856Mathias Agopian Fifo::iterator front(mQueue.begin()); 5797cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian if (front->mIsDroppable) { 580c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // buffer slot currently queued is marked free if still tracked 581c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar if (stillTracking(front)) { 582c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mSlots[front->mBuf].mBufferState = BufferSlot::FREE; 58326a6f37cc06b8014edcedbee8d5558ca7da9abe3Mathias Agopian // reset the frame number of the freed buffer so that it is the first in 58426a6f37cc06b8014edcedbee8d5558ca7da9abe3Mathias Agopian // line to be dequeued again. 58526a6f37cc06b8014edcedbee8d5558ca7da9abe3Mathias Agopian mSlots[front->mBuf].mFrameNumber = 0; 586c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar } 587a3fbda3cef04d51a35a3eb64b2f744a989800856Mathias Agopian // and we record the new buffer in the queued list 588c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar *front = item; 589a3fbda3cef04d51a35a3eb64b2f744a989800856Mathias Agopian } else { 590a3fbda3cef04d51a35a3eb64b2f744a989800856Mathias Agopian mQueue.push_back(item); 591a3fbda3cef04d51a35a3eb64b2f744a989800856Mathias Agopian listener = mConsumerListener; 5926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 5946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 595eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = true; 59674ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 5976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 5982488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, 5992488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian mQueue.size()); 6001c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 6011c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_INT(mConsumerName.string(), mQueue.size()); 6026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } // scope for the lock 6036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam // call back without lock held 6056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (listener != 0) { 6066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam listener->onFrameAvailable(); 6076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 608753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden return NO_ERROR; 6096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 6106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6114c00cc11141da7d159eb2323b186ed344115c0f1Jesse Hallvoid BufferQueue::cancelBuffer(int buf, const sp<Fence>& fence) { 6121c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 6136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("cancelBuffer: slot=%d", buf); 6146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 6156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 6176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGW("cancelBuffer: BufferQueue has been abandoned!"); 6186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 6196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6217cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian if (buf < 0 || buf >= NUM_BUFFER_SLOTS) { 6226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d", 6237cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian NUM_BUFFER_SLOTS, buf); 6246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 6256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 6266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)", 6276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam buf, mSlots[buf].mBufferState); 6286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return; 6291df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } else if (fence == NULL) { 6301df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis ST_LOGE("cancelBuffer: fence is NULL"); 6311df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis return; 6326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mBufferState = BufferSlot::FREE; 6346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam mSlots[buf].mFrameNumber = 0; 635c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall mSlots[buf].mFence = fence; 63674ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 6376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 6386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 639365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian 640365857df8b94c959dea984a63013f6e7730ef976Mathias Agopianstatus_t BufferQueue::connect(const sp<IBinder>& token, 641365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian int api, bool producerControlledByApp, QueueBufferOutput* output) { 6421c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 6438db92553e9e6263cd41eaf1a1ebc9e3f88f92b5fJesse Hall ST_LOGV("connect: api=%d producerControlledByApp=%s", api, 6448db92553e9e6263cd41eaf1a1ebc9e3f88f92b5fJesse Hall producerControlledByApp ? "true" : "false"); 6456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam Mutex::Autolock lock(mMutex); 6466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 6478507586903fa803abf535853a169913f2cf2e555Andy McFaddenretry: 6486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam if (mAbandoned) { 6496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGE("connect: BufferQueue has been abandoned!"); 6506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return NO_INIT; 6516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 653fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mConsumerListener == NULL) { 654fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("connect: BufferQueue has no consumer!"); 655fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_INIT; 656fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 657fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 6588507586903fa803abf535853a169913f2cf2e555Andy McFadden if (mConnectedApi != NO_CONNECTED_API) { 6598507586903fa803abf535853a169913f2cf2e555Andy McFadden ST_LOGE("connect: already connected (cur=%d, req=%d)", 6608507586903fa803abf535853a169913f2cf2e555Andy McFadden mConnectedApi, api); 6618507586903fa803abf535853a169913f2cf2e555Andy McFadden return -EINVAL; 6628507586903fa803abf535853a169913f2cf2e555Andy McFadden } 6638507586903fa803abf535853a169913f2cf2e555Andy McFadden 6648507586903fa803abf535853a169913f2cf2e555Andy McFadden // If we disconnect and reconnect quickly, we can be in a state where our slots are 6658507586903fa803abf535853a169913f2cf2e555Andy McFadden // empty but we have many buffers in the queue. This can cause us to run out of 6668507586903fa803abf535853a169913f2cf2e555Andy McFadden // memory if we outrun the consumer. Wait here if it looks like we have too many 6678507586903fa803abf535853a169913f2cf2e555Andy McFadden // buffers queued up. 6688507586903fa803abf535853a169913f2cf2e555Andy McFadden int maxBufferCount = getMaxBufferCountLocked(false); // worst-case, i.e. largest value 6698507586903fa803abf535853a169913f2cf2e555Andy McFadden if (mQueue.size() > (size_t) maxBufferCount) { 6708507586903fa803abf535853a169913f2cf2e555Andy McFadden // TODO: make this bound tighter? 6718507586903fa803abf535853a169913f2cf2e555Andy McFadden ST_LOGV("queue size is %d, waiting", mQueue.size()); 6728507586903fa803abf535853a169913f2cf2e555Andy McFadden mDequeueCondition.wait(mMutex); 6738507586903fa803abf535853a169913f2cf2e555Andy McFadden goto retry; 6748507586903fa803abf535853a169913f2cf2e555Andy McFadden } 6758507586903fa803abf535853a169913f2cf2e555Andy McFadden 6766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int err = NO_ERROR; 6776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam switch (api) { 6786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_EGL: 6796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_CPU: 6806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_MEDIA: 6816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam case NATIVE_WINDOW_API_CAMERA: 6828507586903fa803abf535853a169913f2cf2e555Andy McFadden mConnectedApi = api; 6838507586903fa803abf535853a169913f2cf2e555Andy McFadden output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, mQueue.size()); 6848507586903fa803abf535853a169913f2cf2e555Andy McFadden 6858507586903fa803abf535853a169913f2cf2e555Andy McFadden // set-up a death notification so that we can disconnect 6868507586903fa803abf535853a169913f2cf2e555Andy McFadden // automatically when/if the remote producer dies. 6878507586903fa803abf535853a169913f2cf2e555Andy McFadden if (token != NULL && token->remoteBinder() != NULL) { 6888507586903fa803abf535853a169913f2cf2e555Andy McFadden status_t err = token->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 6898507586903fa803abf535853a169913f2cf2e555Andy McFadden if (err == NO_ERROR) { 6908507586903fa803abf535853a169913f2cf2e555Andy McFadden mConnectedProducerToken = token; 6918507586903fa803abf535853a169913f2cf2e555Andy McFadden } else { 6928507586903fa803abf535853a169913f2cf2e555Andy McFadden ALOGE("linkToDeath failed: %s (%d)", strerror(-err), err); 693365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian } 6946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 6956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam break; 6966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam default: 6976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 6986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam break; 6996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 700eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 701eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = false; 702595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian mDequeueBufferCannotBlock = mConsumerControlledByApp && producerControlledByApp; 703eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 7046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 7056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 7066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 707365857df8b94c959dea984a63013f6e7730ef976Mathias Agopianvoid BufferQueue::binderDied(const wp<IBinder>& who) { 708365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian // If we're here, it means that a producer we were connected to died. 709365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian // We're GUARANTEED that we still are connected to it because it has no other way 710365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian // to get disconnected -- or -- we wouldn't be here because we're removing this 711365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian // callback upon disconnect. Therefore, it's okay to read mConnectedApi without 712365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian // synchronization here. 713365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian int api = mConnectedApi; 714365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian this->disconnect(api); 715365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian} 716365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian 7176b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::disconnect(int api) { 7181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 7196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam ST_LOGV("disconnect: api=%d", api); 7206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 7216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam int err = NO_ERROR; 722a4e19521ac4563f2ff6517bcfd63d9b8d33a6d0bMathias Agopian sp<IConsumerListener> listener; 723fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 724fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis { // Scope for the lock 725fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis Mutex::Autolock lock(mMutex); 726fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 727fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mAbandoned) { 728fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // it is not really an error to disconnect after the surface 729fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // has been abandoned, it should just be a no-op. 730fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_ERROR; 731fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 732fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 733fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis switch (api) { 734fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_EGL: 735fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_CPU: 736fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_MEDIA: 737fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis case NATIVE_WINDOW_API_CAMERA: 738fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mConnectedApi == api) { 739a3fbda3cef04d51a35a3eb64b2f744a989800856Mathias Agopian freeAllBuffersLocked(); 740365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian // remove our death notification callback if we have one 741365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian sp<IBinder> token = mConnectedProducerToken; 742365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian if (token != NULL) { 743365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian // this can fail if we're here because of the death notification 744365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian // either way, we just ignore. 745365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian token->unlinkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 746365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian } 747365857df8b94c959dea984a63013f6e7730ef976Mathias Agopian mConnectedProducerToken = NULL; 748fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConnectedApi = NO_CONNECTED_API; 749fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mDequeueCondition.broadcast(); 750fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener = mConsumerListener; 751fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } else { 752fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)", 753fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConnectedApi, api); 754fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis err = -EINVAL; 755fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 756fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis break; 757fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis default: 758fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("disconnect: unknown API %d", api); 7596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam err = -EINVAL; 760fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis break; 761fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 7626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 763fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 764fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (listener != NULL) { 765fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener->onBuffersReleased(); 766fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 767fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 7686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam return err; 7696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 7706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 77174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid BufferQueue::dump(String8& result, const char* prefix) const { 772eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 773eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 774eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam String8 fifo; 775eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam int fifoSize = 0; 776eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Fifo::const_iterator i(mQueue.begin()); 777eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam while (i != mQueue.end()) { 778c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar fifo.appendFormat("%02d:%p crop=[%d,%d,%d,%d], " 779c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar "xform=0x%02x, time=%#llx, scale=%s\n", 780c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar i->mBuf, i->mGraphicBuffer.get(), 781c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar i->mCrop.left, i->mCrop.top, i->mCrop.right, 782c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar i->mCrop.bottom, i->mTransform, i->mTimestamp, 783c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar scalingModeName(i->mScalingMode) 784c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar ); 785c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar i++; 78674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian fifoSize++; 787eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 788eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 789e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis 79074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 7917cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian "%s-BufferQueue mMaxAcquiredBufferCount=%d, mDequeueBufferCannotBlock=%d, default-size=[%dx%d], " 7926905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden "default-format=%d, transform-hint=%02x, FIFO(%d)={%s}\n", 7937cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian prefix, mMaxAcquiredBufferCount, mDequeueBufferCannotBlock, mDefaultWidth, 7946905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden mDefaultHeight, mDefaultBufferFormat, mTransformHint, 7956905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden fifoSize, fifo.string()); 796eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 797eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam struct { 798eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam const char * operator()(int state) const { 799eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam switch (state) { 800eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::DEQUEUED: return "DEQUEUED"; 801eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::QUEUED: return "QUEUED"; 802eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::FREE: return "FREE"; 803eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam case BufferSlot::ACQUIRED: return "ACQUIRED"; 804eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam default: return "Unknown"; 805eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 806eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 807eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } stateName; 808eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 8097cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian // just trim the free buffers to not spam the dump 8107cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian int maxBufferCount = 0; 8117cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian for (int i=NUM_BUFFER_SLOTS-1 ; i>=0 ; i--) { 8127cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian const BufferSlot& slot(mSlots[i]); 8137cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian if ((slot.mBufferState != BufferSlot::FREE) || (slot.mGraphicBuffer != NULL)) { 8147cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian maxBufferCount = i+1; 8157cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian break; 8167cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian } 8177cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian } 8187cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian 819e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis for (int i=0 ; i<maxBufferCount ; i++) { 820eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam const BufferSlot& slot(mSlots[i]); 8217cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian const sp<GraphicBuffer>& buf(slot.mGraphicBuffer); 82274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 823c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar "%s%s[%02d:%p] state=%-8s", 8247cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i, buf.get(), 825c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar stateName(slot.mBufferState) 826eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ); 827eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 828eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (buf != NULL) { 82974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 830eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ", %p [%4ux%4u:%4u,%3X]", 831eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buf->handle, buf->width, buf->height, buf->stride, 832eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buf->format); 833eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 834eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam result.append("\n"); 835eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 836eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 837eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 8381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid BufferQueue::freeBufferLocked(int slot) { 8391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ST_LOGV("freeBufferLocked: slot=%d", slot); 8401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mGraphicBuffer = 0; 8411a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) { 8421a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mNeedsCleanupOnRelease = true; 8439abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 8441a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mBufferState = BufferSlot::FREE; 8451a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mFrameNumber = 0; 8461a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mAcquireCalled = false; 847eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 848eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // destroy fence as BufferQueue now takes ownership 8491a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) { 8501a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence); 8511a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mSlots[slot].mEglFence = EGL_NO_SYNC_KHR; 8526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 8531df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis mSlots[slot].mFence = Fence::NO_FENCE; 8546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 8556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 8566b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::freeAllBuffersLocked() { 857eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mBufferHasBeenQueued = false; 8586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 8596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam freeBufferLocked(i); 8606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam } 8616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam} 8626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam 86314fab7dd794cd6bf29e6425340683c6221062b3cAndy McFaddenstatus_t BufferQueue::acquireBuffer(BufferItem *buffer, nsecs_t expectedPresent) { 864546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_CALL(); 865eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 8665e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis 8675e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis // Check that the consumer doesn't currently have the maximum number of 8685e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis // buffers acquired. We allow the max buffer count to be exceeded by one 8695e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis // buffer, so that the consumer can successfully set up the newly acquired 8705e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis // buffer before releasing the old one. 8715e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis int numAcquiredBuffers = 0; 8725e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 8735e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis if (mSlots[i].mBufferState == BufferSlot::ACQUIRED) { 8745e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis numAcquiredBuffers++; 8755e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis } 8765e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis } 8775e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis if (numAcquiredBuffers >= mMaxAcquiredBufferCount+1) { 8785e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis ST_LOGE("acquireBuffer: max acquired buffer count reached: %d (max=%d)", 8795e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis numAcquiredBuffers, mMaxAcquiredBufferCount); 8805e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis return INVALID_OPERATION; 8815e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis } 8825e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis 883eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // check if queue is empty 884eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // In asynchronous mode the list is guaranteed to be one buffer 885eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // deep, while in synchronous mode we use the oldest buffer. 8861585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden if (mQueue.empty()) { 8871585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden return NO_BUFFER_AVAILABLE; 8881585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden } 889546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 8901585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden Fifo::iterator front(mQueue.begin()); 8911585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden 89214fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // If expectedPresent is specified, we may not want to return a buffer yet. 89314fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // If it's specified and there's more than one buffer queued, we may 89414fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // want to drop a buffer. 89514fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden if (expectedPresent != 0) { 89614fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second 89714fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden 89814fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // The "expectedPresent" argument indicates when the buffer is expected 89914fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // to be presented on-screen. If the buffer's desired-present time 90014fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // is earlier (less) than expectedPresent, meaning it'll be displayed 90114fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // on time or possibly late if we show it ASAP, we acquire and return 90214fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // it. If we don't want to display it until after the expectedPresent 90314fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // time, we return PRESENT_LATER without acquiring it. 90414fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // 90514fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // To be safe, we don't defer acquisition if expectedPresent is 90614fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // more than one second in the future beyond the desired present time 90714fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // (i.e. we'd be holding the buffer for a long time). 90814fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // 90914fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // NOTE: code assumes monotonic time values from the system clock are 91014fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // positive. 9113c25621ad7d13f64d3ab95a27fa970fbc9998f73Andy McFadden 9123c25621ad7d13f64d3ab95a27fa970fbc9998f73Andy McFadden // Start by checking to see if we can drop frames. We skip this check 9133c25621ad7d13f64d3ab95a27fa970fbc9998f73Andy McFadden // if the timestamps are being auto-generated by Surface -- if the 9143c25621ad7d13f64d3ab95a27fa970fbc9998f73Andy McFadden // app isn't generating timestamps explicitly, they probably don't 9153c25621ad7d13f64d3ab95a27fa970fbc9998f73Andy McFadden // want frames to be discarded based on them. 9163c25621ad7d13f64d3ab95a27fa970fbc9998f73Andy McFadden while (mQueue.size() > 1 && !mQueue[0].mIsAutoTimestamp) { 91714fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // If entry[1] is timely, drop entry[0] (and repeat). We apply 91814fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // an additional criteria here: we only drop the earlier buffer if 91914fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // our desiredPresent falls within +/- 1 second of the expected 92014fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // present. Otherwise, bogus desiredPresent times (e.g. 0 or 92114fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // a small relative timestamp), which normally mean "ignore the 92214fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // timestamp and acquire immediately", would cause us to drop 92314fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // frames. 92414fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // 92514fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // We may want to add an additional criteria: don't drop the 92614fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // earlier buffer if entry[1]'s fence hasn't signaled yet. 92714fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // 92814fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // (Vector front is [0], back is [size()-1]) 92914fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden const BufferItem& bi(mQueue[1]); 93014fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden nsecs_t desiredPresent = bi.mTimestamp; 93114fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC || 93214fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden desiredPresent > expectedPresent) { 93314fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // This buffer is set to display in the near future, or 93414fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // desiredPresent is garbage. Either way we don't want to 93514fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // drop the previous buffer just to get this on screen sooner. 93614fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden ST_LOGV("pts nodrop: des=%lld expect=%lld (%lld) now=%lld", 93714fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden desiredPresent, expectedPresent, desiredPresent - expectedPresent, 93814fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden systemTime(CLOCK_MONOTONIC)); 93914fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden break; 94014fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden } 94114fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden ST_LOGV("pts drop: queue1des=%lld expect=%lld size=%d", 94214fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden desiredPresent, expectedPresent, mQueue.size()); 94314fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden if (stillTracking(front)) { 94414fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // front buffer is still in mSlots, so mark the slot as free 94514fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden mSlots[front->mBuf].mBufferState = BufferSlot::FREE; 94614fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden } 94714fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden mQueue.erase(front); 94814fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden front = mQueue.begin(); 94914fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden } 95014fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden 95114fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden // See if the front buffer is due. 95214fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden nsecs_t desiredPresent = front->mTimestamp; 95314fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden if (desiredPresent > expectedPresent && 95414fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden desiredPresent < expectedPresent + MAX_REASONABLE_NSEC) { 95514fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden ST_LOGV("pts defer: des=%lld expect=%lld (%lld) now=%lld", 95614fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden desiredPresent, expectedPresent, desiredPresent - expectedPresent, 95714fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden systemTime(CLOCK_MONOTONIC)); 95814fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden return PRESENT_LATER; 95914fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden } 96014fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden 96114fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden ST_LOGV("pts accept: des=%lld expect=%lld (%lld) now=%lld", 96214fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden desiredPresent, expectedPresent, desiredPresent - expectedPresent, 9631585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden systemTime(CLOCK_MONOTONIC)); 9641585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden } 965c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar 96614fab7dd794cd6bf29e6425340683c6221062b3cAndy McFadden int buf = front->mBuf; 9671585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden *buffer = *front; 9681585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden ATRACE_BUFFER_INDEX(buf); 9691a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 9701585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden ST_LOGV("acquireBuffer: acquiring { slot=%d/%llu, buffer=%p }", 9711585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden front->mBuf, front->mFrameNumber, 9721585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden front->mGraphicBuffer->handle); 9731585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // if front buffer still being tracked update slot state 9741585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden if (stillTracking(front)) { 9751585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden mSlots[buf].mAcquireCalled = true; 9761585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden mSlots[buf].mNeedsCleanupOnRelease = false; 9771585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden mSlots[buf].mBufferState = BufferSlot::ACQUIRED; 9781585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden mSlots[buf].mFence = Fence::NO_FENCE; 9791585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden } 9801c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 9811585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // If the buffer has previously been acquired by the consumer, set 9821585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // mGraphicBuffer to NULL to avoid unnecessarily remapping this 9831585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // buffer on the consumer side. 9841585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden if (buffer->mAcquireCalled) { 9851585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden buffer->mGraphicBuffer = NULL; 986eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 987eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 9881585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden mQueue.erase(front); 9891585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden mDequeueCondition.broadcast(); 9901585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden 9911585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden ATRACE_INT(mConsumerName.string(), mQueue.size()); 9921585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden 993753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden return NO_ERROR; 994eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 995eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 996c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnarstatus_t BufferQueue::releaseBuffer( 997c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar int buf, uint64_t frameNumber, EGLDisplay display, 998c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall EGLSyncKHR eglFence, const sp<Fence>& fence) { 999546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_CALL(); 1000546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian ATRACE_BUFFER_INDEX(buf); 1001546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian 10021df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (buf == INVALID_BUFFER_SLOT || fence == NULL) { 10031df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis return BAD_VALUE; 1004eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 1005eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 1006207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian Mutex::Autolock _l(mMutex); 1007c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar 1008c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // If the frame number has changed because buffer has been reallocated, 1009c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // we can ignore this releaseBuffer for the old buffer. 1010c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar if (frameNumber != mSlots[buf].mFrameNumber) { 1011c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar return STALE_BUFFER_SLOT; 1012c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar } 1013207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian 1014207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian 1015207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian // Internal state consistency checks: 1016207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian // Make sure this buffers hasn't been queued while we were owning it (acquired) 1017207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian Fifo::iterator front(mQueue.begin()); 1018207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian Fifo::const_iterator const end(mQueue.end()); 1019207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian while (front != end) { 1020207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian if (front->mBuf == buf) { 1021207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian LOG_ALWAYS_FATAL("[%s] received new buffer(#%lld) on slot #%d that has not yet been " 1022207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian "acquired", mConsumerName.string(), frameNumber, buf); 1023207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian break; // never reached 1024207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian } 1025207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian front++; 1026207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopian } 1027eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 10289abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // The buffer can now only be released if its in the acquired state 10299abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) { 1030c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mSlots[buf].mEglDisplay = display; 1031c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mSlots[buf].mEglFence = eglFence; 1032c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mSlots[buf].mFence = fence; 1033eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mSlots[buf].mBufferState = BufferSlot::FREE; 10349abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } else if (mSlots[buf].mNeedsCleanupOnRelease) { 10359abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGV("releasing a stale buf %d its state was %d", buf, mSlots[buf].mBufferState); 10369abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mSlots[buf].mNeedsCleanupOnRelease = false; 10379abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return STALE_BUFFER_SLOT; 10389abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } else { 10399abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ST_LOGE("attempted to release buf %d but its state was %d", buf, mSlots[buf].mBufferState); 10409abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return -EINVAL; 1041eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 1042eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 10439abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mDequeueCondition.broadcast(); 1044753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden return NO_ERROR; 1045eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 1046eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 1047a4e19521ac4563f2ff6517bcfd63d9b8d33a6d0bMathias Agopianstatus_t BufferQueue::consumerConnect(const sp<IConsumerListener>& consumerListener, 1048595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian bool controlledByApp) { 10498db92553e9e6263cd41eaf1a1ebc9e3f88f92b5fJesse Hall ST_LOGV("consumerConnect controlledByApp=%s", 10508db92553e9e6263cd41eaf1a1ebc9e3f88f92b5fJesse Hall controlledByApp ? "true" : "false"); 1051fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis Mutex::Autolock lock(mMutex); 1052fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1053fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mAbandoned) { 1054fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("consumerConnect: BufferQueue has been abandoned!"); 1055fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_INIT; 1056fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 1057753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden if (consumerListener == NULL) { 1058753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden ST_LOGE("consumerConnect: consumerListener may not be NULL"); 1059753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden return BAD_VALUE; 1060753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden } 1061fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1062fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConsumerListener = consumerListener; 1063595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian mConsumerControlledByApp = controlledByApp; 1064fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1065753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden return NO_ERROR; 1066fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 1067fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1068eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatus_t BufferQueue::consumerDisconnect() { 1069fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("consumerDisconnect"); 1070eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 1071b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 1072fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mConsumerListener == NULL) { 1073fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("consumerDisconnect: No consumer is connected!"); 1074fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return -EINVAL; 1075fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 1076b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 1077fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mAbandoned = true; 1078fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConsumerListener = NULL; 1079b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mQueue.clear(); 1080eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam freeAllBuffersLocked(); 108174ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke mDequeueCondition.broadcast(); 1082753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden return NO_ERROR; 1083eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 1084eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 1085fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisstatus_t BufferQueue::getReleasedBuffers(uint32_t* slotMask) { 1086fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("getReleasedBuffers"); 1087fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis Mutex::Autolock lock(mMutex); 1088fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1089fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mAbandoned) { 1090fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("getReleasedBuffers: BufferQueue has been abandoned!"); 1091fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_INIT; 1092fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 1093fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1094fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis uint32_t mask = 0; 1095fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 1096fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (!mSlots[i].mAcquireCalled) { 1097fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mask |= 1 << i; 1098fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 1099fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 1100c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar 1101c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // Remove buffers in flight (on the queue) from the mask where acquire has 1102c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // been called, as the consumer will not receive the buffer address, so 1103c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // it should not free these slots. 1104c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar Fifo::iterator front(mQueue.begin()); 1105c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar while (front != mQueue.end()) { 1106c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar if (front->mAcquireCalled) 1107c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mask &= ~(1 << front->mBuf); 1108c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar front++; 1109c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar } 1110c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar 1111fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis *slotMask = mask; 1112fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1113fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("getReleasedBuffers: returning mask %#x", mask); 1114fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return NO_ERROR; 1115fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 1116fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1117207c1e287c129e7ebf679a3aaf2076c3c47c1afbMathias Agopianstatus_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h) { 1118eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h); 1119eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (!w || !h) { 1120eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)", 1121eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam w, h); 1122eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return BAD_VALUE; 1123eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 1124eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 1125eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 1126eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mDefaultWidth = w; 1127eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mDefaultHeight = h; 1128753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden return NO_ERROR; 1129eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 1130eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 113131a353da225af5329735451c761b430d82dfda1bJamie Gennisstatus_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) { 11321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 1133eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock lock(mMutex); 113431a353da225af5329735451c761b430d82dfda1bJamie Gennis return setDefaultMaxBufferCountLocked(bufferCount); 1135eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 1136eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 1137ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopianstatus_t BufferQueue::disableAsyncBuffer() { 1138ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ATRACE_CALL(); 1139ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian Mutex::Autolock lock(mMutex); 1140ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (mConsumerListener != NULL) { 1141ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGE("disableAsyncBuffer: consumer already connected!"); 1142ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return INVALID_OPERATION; 1143ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 1144ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mUseAsyncBuffer = false; 1145ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return NO_ERROR; 1146ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian} 1147ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 114872f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennisstatus_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { 114972f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis ATRACE_CALL(); 115072f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis Mutex::Autolock lock(mMutex); 1151c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > MAX_MAX_ACQUIRED_BUFFERS) { 1152c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis ST_LOGE("setMaxAcquiredBufferCount: invalid count specified: %d", 1153c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis maxAcquiredBuffers); 1154c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis return BAD_VALUE; 1155c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis } 115672f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis if (mConnectedApi != NO_CONNECTED_API) { 115772f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis return INVALID_OPERATION; 115872f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis } 115972f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis mMaxAcquiredBufferCount = maxAcquiredBuffers; 1160753e3415cdaa99f9453d1ea71b163bf1b148e127Andy McFadden return NO_ERROR; 116172f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis} 116272f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis 11637cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopianint BufferQueue::getMinUndequeuedBufferCount(bool async) const { 1164ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // if dequeueBuffer is allowed to error out, we don't have to 1165ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // add an extra buffer. 1166ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (!mUseAsyncBuffer) 1167ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return mMaxAcquiredBufferCount; 1168ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 1169ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // we're in async mode, or we want to prevent the app to 1170ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // deadlock itself, we throw-in an extra buffer to guarantee it. 1171ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (mDequeueBufferCannotBlock || async) 1172ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return mMaxAcquiredBufferCount+1; 1173ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 1174ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return mMaxAcquiredBufferCount; 11757cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian} 11767cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian 11777cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopianint BufferQueue::getMinMaxBufferCountLocked(bool async) const { 11787cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian return getMinUndequeuedBufferCount(async) + 1; 117931a353da225af5329735451c761b430d82dfda1bJamie Gennis} 118031a353da225af5329735451c761b430d82dfda1bJamie Gennis 11817cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopianint BufferQueue::getMaxBufferCountLocked(bool async) const { 11827cdd786fa80cf03551291ae8feca7b77583be1c5Mathias Agopian int minMaxBufferCount = getMinMaxBufferCountLocked(async); 1183e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis 1184e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis int maxBufferCount = mDefaultMaxBufferCount; 1185e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis if (maxBufferCount < minMaxBufferCount) { 1186e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis maxBufferCount = minMaxBufferCount; 1187e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis } 1188e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis if (mOverrideMaxBufferCount != 0) { 1189e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis assert(mOverrideMaxBufferCount >= minMaxBufferCount); 1190e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis maxBufferCount = mOverrideMaxBufferCount; 1191e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis } 1192e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis 1193e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // Any buffers that are dequeued by the producer or sitting in the queue 1194e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // waiting to be consumed need to have their slots preserved. Such 1195e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // buffers will temporarily keep the max buffer count up until the slots 1196e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis // no longer need to be preserved. 1197e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) { 1198e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis BufferSlot::BufferState state = mSlots[i].mBufferState; 1199e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis if (state == BufferSlot::QUEUED || state == BufferSlot::DEQUEUED) { 1200e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis maxBufferCount = i + 1; 1201e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis } 1202e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis } 1203e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis 1204e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis return maxBufferCount; 1205e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis} 1206e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis 1207c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnarbool BufferQueue::stillTracking(const BufferItem *item) const { 1208c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar const BufferSlot &slot = mSlots[item->mBuf]; 1209c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar 1210c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar ST_LOGV("stillTracking?: item: { slot=%d/%llu, buffer=%p }, " 1211c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar "slot: { slot=%d/%llu, buffer=%p }", 1212c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar item->mBuf, item->mFrameNumber, 1213c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar (item->mGraphicBuffer.get() ? item->mGraphicBuffer->handle : 0), 1214c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar item->mBuf, slot.mFrameNumber, 1215c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar (slot.mGraphicBuffer.get() ? slot.mGraphicBuffer->handle : 0)); 1216c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar 1217c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // Compare item with its original buffer slot. We can check the slot 1218c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // as the buffer would not be moved to a different slot by the producer. 1219c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar return (slot.mGraphicBuffer != NULL && 1220c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar item->mGraphicBuffer->handle == slot.mGraphicBuffer->handle); 1221c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar} 1222c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar 1223fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie GennisBufferQueue::ProxyConsumerListener::ProxyConsumerListener( 1224a4e19521ac4563f2ff6517bcfd63d9b8d33a6d0bMathias Agopian const wp<ConsumerListener>& consumerListener): 1225fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mConsumerListener(consumerListener) {} 1226fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1227fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie GennisBufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {} 1228fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1229fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid BufferQueue::ProxyConsumerListener::onFrameAvailable() { 1230a4e19521ac4563f2ff6517bcfd63d9b8d33a6d0bMathias Agopian sp<ConsumerListener> listener(mConsumerListener.promote()); 1231fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (listener != NULL) { 1232fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener->onFrameAvailable(); 1233fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 1234fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 1235fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1236fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid BufferQueue::ProxyConsumerListener::onBuffersReleased() { 1237a4e19521ac4563f2ff6517bcfd63d9b8d33a6d0bMathias Agopian sp<ConsumerListener> listener(mConsumerListener.promote()); 1238fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (listener != NULL) { 1239fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener->onBuffersReleased(); 1240fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 1241fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 1242fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 12436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}; // namespace android 1244