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