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(&timestamp, &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