BufferQueue.cpp revision 5e5efde7874a9fab650fd4b724ceef46db850470
16b091c53000c843211c218ce40287a7edca9bc63Daniel Lam/*
26b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * Copyright (C) 2012 The Android Open Source Project
36b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *
46b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * Licensed under the Apache License, Version 2.0 (the "License");
56b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * you may not use this file except in compliance with the License.
66b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * You may obtain a copy of the License at
76b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *
86b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *      http://www.apache.org/licenses/LICENSE-2.0
96b091c53000c843211c218ce40287a7edca9bc63Daniel Lam *
106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * Unless required by applicable law or agreed to in writing, software
116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * distributed under the License is distributed on an "AS IS" BASIS,
126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * See the License for the specific language governing permissions and
146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam * limitations under the License.
156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam */
166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#define LOG_TAG "BufferQueue"
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
19fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis//#define LOG_NDEBUG 0
206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#define GL_GLEXT_PROTOTYPES
226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#define EGL_EGLEXT_PROTOTYPES
236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <EGL/egl.h>
256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <EGL/eglext.h>
266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <gui/BufferQueue.h>
2890ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/ISurfaceComposer.h>
296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <private/gui/ComposerService.h>
306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#include <utils/Log.h>
32eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#include <gui/SurfaceTexture.h>
331c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// This compile option causes SurfaceTexture to return the buffer that is currently
366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// attached to the GL texture from dequeueBuffer when no other buffers are
376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// available.  It requires the drivers (Gralloc, GL, OMX IL, and Camera) to do
386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// implicit cross-process synchronization to prevent the buffer from being
396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// written to before the buffer has (a) been detached from the GL texture and
406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// (b) all GL reads from the buffer have completed.
41eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
42eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam// During refactoring, do not support dequeuing the current buffer
43eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#undef ALLOW_DEQUEUE_CURRENT_BUFFER
44eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER
466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER    true
476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled"
486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#else
496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER    false
506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam#endif
516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// Macros for including the BufferQueue name in log messages
53eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
54eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
55eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
56eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
57eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam#define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
59546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian#define ATRACE_BUFFER_INDEX(index)                                            \
60695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis    if (ATRACE_ENABLED()) {                                                   \
61695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis        char ___traceBuf[1024];                                               \
62695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis        snprintf(___traceBuf, 1024, "%s: %d", mConsumerName.string(),         \
63695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis                (index));                                                     \
64695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis        android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf);           \
65695e331f01b136155b1559b3c878b7c5bb631bc1Jamie Gennis    }
66546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian
676b091c53000c843211c218ce40287a7edca9bc63Daniel Lamnamespace android {
686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam// Get an ID that's unique within this process.
706b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatic int32_t createProcessUniqueId() {
716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    static volatile int32_t globalCounter = 0;
726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    return android_atomic_inc(&globalCounter);
736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
75cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennisstatic const char* scalingModeName(int scalingMode) {
76cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis    switch (scalingMode) {
77cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis        case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
78cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis        case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
79cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis        case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
80cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis        default: return "Unknown";
81cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis    }
82cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis}
83cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis
8472f096fb1ad0a0deadbfac5f88627461905d38e8Jamie GennisBufferQueue::BufferQueue(bool allowSynchronousMode,
853e87601170141229d661df93e2f59e1ced73474bMathias Agopian        const sp<IGraphicBufferAlloc>& allocator) :
866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    mDefaultWidth(1),
876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    mDefaultHeight(1),
8872f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis    mMaxAcquiredBufferCount(1),
8972f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis    mDefaultMaxBufferCount(2),
9031a353da225af5329735451c761b430d82dfda1bJamie Gennis    mOverrideMaxBufferCount(0),
916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    mSynchronousMode(false),
926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    mAllowSynchronousMode(allowSynchronousMode),
936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    mConnectedApi(NO_CONNECTED_API),
946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    mAbandoned(false),
95eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    mFrameCounter(0),
96b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mBufferHasBeenQueued(false),
971a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
98b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mConsumerUsageBits(0),
99b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mTransformHint(0)
1006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{
1016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    // Choose a name using the PID and a process-unique ID.
102eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
1036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
1046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    ST_LOGV("BufferQueue");
1053e87601170141229d661df93e2f59e1ced73474bMathias Agopian    if (allocator == NULL) {
1063e87601170141229d661df93e2f59e1ced73474bMathias Agopian        sp<ISurfaceComposer> composer(ComposerService::getComposerService());
1073e87601170141229d661df93e2f59e1ced73474bMathias Agopian        mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
1083e87601170141229d661df93e2f59e1ced73474bMathias Agopian        if (mGraphicBufferAlloc == 0) {
1093e87601170141229d661df93e2f59e1ced73474bMathias Agopian            ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()");
1103e87601170141229d661df93e2f59e1ced73474bMathias Agopian        }
1113e87601170141229d661df93e2f59e1ced73474bMathias Agopian    } else {
1123e87601170141229d661df93e2f59e1ced73474bMathias Agopian        mGraphicBufferAlloc = allocator;
113abe61bfda4938abd932465e27c29ba9e41aea606Daniel Lam    }
1146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
1156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
1166b091c53000c843211c218ce40287a7edca9bc63Daniel LamBufferQueue::~BufferQueue() {
1176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    ST_LOGV("~BufferQueue");
1186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
1196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
12031a353da225af5329735451c761b430d82dfda1bJamie Gennisstatus_t BufferQueue::setDefaultMaxBufferCountLocked(int count) {
121e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    if (count < 2 || count > NUM_BUFFER_SLOTS)
1226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        return BAD_VALUE;
1236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
12431a353da225af5329735451c761b430d82dfda1bJamie Gennis    mDefaultMaxBufferCount = count;
125e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    mDequeueCondition.broadcast();
1261a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    return OK;
1286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
1296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
130eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lambool BufferQueue::isSynchronousMode() const {
131eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    Mutex::Autolock lock(mMutex);
132eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    return mSynchronousMode;
133eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam}
134eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
135eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamvoid BufferQueue::setConsumerName(const String8& name) {
136eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    Mutex::Autolock lock(mMutex);
137eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    mConsumerName = name;
138eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam}
139eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
140b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setDefaultBufferFormat(uint32_t defaultFormat) {
141b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    Mutex::Autolock lock(mMutex);
142b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mDefaultBufferFormat = defaultFormat;
143b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    return OK;
144b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam}
145b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
146b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setConsumerUsageBits(uint32_t usage) {
147b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    Mutex::Autolock lock(mMutex);
148b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mConsumerUsageBits = usage;
149b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    return OK;
150b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam}
151b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
152b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t BufferQueue::setTransformHint(uint32_t hint) {
153b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    Mutex::Autolock lock(mMutex);
154b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mTransformHint = hint;
155b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    return OK;
156b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam}
157b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1586b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setBufferCount(int bufferCount) {
1596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    ST_LOGV("setBufferCount: count=%d", bufferCount);
1606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
1619abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    sp<ConsumerListener> listener;
1629abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    {
1639abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        Mutex::Autolock lock(mMutex);
1646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
1659abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        if (mAbandoned) {
1669abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!");
1679abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            return NO_INIT;
1689abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
1699abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        if (bufferCount > NUM_BUFFER_SLOTS) {
1709abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            ST_LOGE("setBufferCount: bufferCount larger than slots available");
1719abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            return BAD_VALUE;
1726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        }
1736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
1749abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        // Error out if the user has dequeued buffers
175e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        int maxBufferCount = getMaxBufferCountLocked();
176e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        for (int i=0 ; i<maxBufferCount; i++) {
1779abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
1789abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                ST_LOGE("setBufferCount: client owns some buffers");
1799abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                return -EINVAL;
1809abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            }
1819abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
1826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
18331a353da225af5329735451c761b430d82dfda1bJamie Gennis        const int minBufferSlots = getMinMaxBufferCountLocked();
1849abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        if (bufferCount == 0) {
18531a353da225af5329735451c761b430d82dfda1bJamie Gennis            mOverrideMaxBufferCount = 0;
186e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis            mDequeueCondition.broadcast();
187e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis            return OK;
1889abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
1899abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
1909abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        if (bufferCount < minBufferSlots) {
1919abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            ST_LOGE("setBufferCount: requested buffer count (%d) is less than "
1929abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                    "minimum (%d)", bufferCount, minBufferSlots);
1939abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            return BAD_VALUE;
1949abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
1959abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
1969abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        // here we're guaranteed that the client doesn't have dequeued buffers
1979abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        // and will release all of its buffer references.
198e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        //
199e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        // XXX: Should this use drainQueueAndFreeBuffersLocked instead?
2009abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        freeAllBuffersLocked();
20131a353da225af5329735451c761b430d82dfda1bJamie Gennis        mOverrideMaxBufferCount = bufferCount;
2029abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        mBufferHasBeenQueued = false;
2039abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        mDequeueCondition.broadcast();
2049abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        listener = mConsumerListener;
2059abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    } // scope for lock
2069abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
2079abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    if (listener != NULL) {
2089abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        listener->onBuffersReleased();
2096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
2106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
2116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    return OK;
2126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
2136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
214b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lamint BufferQueue::query(int what, int* outValue)
215b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam{
2161c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
217b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam    Mutex::Autolock lock(mMutex);
218b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam
219b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam    if (mAbandoned) {
220b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam        ST_LOGE("query: SurfaceTexture has been abandoned!");
221b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam        return NO_INIT;
222b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam    }
223b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam
224b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam    int value;
225b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam    switch (what) {
226b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam    case NATIVE_WINDOW_WIDTH:
227b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam        value = mDefaultWidth;
228b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam        break;
229b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam    case NATIVE_WINDOW_HEIGHT:
230b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam        value = mDefaultHeight;
231b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam        break;
232b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam    case NATIVE_WINDOW_FORMAT:
2331a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        value = mDefaultBufferFormat;
234b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam        break;
235b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
23672f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis        value = getMinUndequeuedBufferCountLocked();
237b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam        break;
2382488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian    case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
2392488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian        value = (mQueue.size() >= 2);
2402488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian        break;
241b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam    default:
242b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam        return BAD_VALUE;
243b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam    }
244b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam    outValue[0] = value;
245b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam    return NO_ERROR;
246b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam}
247b856052c00dfef70d0957482c72c2979ffc4733aDaniel Lam
2486b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
2491c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
2506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    ST_LOGV("requestBuffer: slot=%d", slot);
2516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    Mutex::Autolock lock(mMutex);
2526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    if (mAbandoned) {
2536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!");
2546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        return NO_INIT;
2556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
256e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    int maxBufferCount = getMaxBufferCountLocked();
257e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    if (slot < 0 || maxBufferCount <= slot) {
2586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d",
259e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis                maxBufferCount, slot);
260e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        return BAD_VALUE;
261e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
262e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        // XXX: I vaguely recall there was some reason this can be valid, but
263e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        // for the life of me I can't recall under what circumstances that's
264e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        // the case.
265e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        ST_LOGE("requestBuffer: slot %d is not owned by the client (state=%d)",
266e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis                slot, mSlots[slot].mBufferState);
2676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        return BAD_VALUE;
2686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
2696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    mSlots[slot].mRequestBufferCalled = true;
2706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    *buf = mSlots[slot].mGraphicBuffer;
2716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    return NO_ERROR;
2726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
2736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
274f78575400977f644cf0b12beb2fa5fc278b6ed4cJesse Hallstatus_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
275f78575400977f644cf0b12beb2fa5fc278b6ed4cJesse Hall        uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
2761c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
2776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage);
2786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
2796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    if ((w && !h) || (!w && h)) {
2806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
2816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        return BAD_VALUE;
2826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
2836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
2846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    status_t returnFlags(OK);
2856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    EGLDisplay dpy = EGL_NO_DISPLAY;
286c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall    EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
2876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
2886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    { // Scope for the lock
2896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        Mutex::Autolock lock(mMutex);
2906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
291b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam        if (format == 0) {
292b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam            format = mDefaultBufferFormat;
293b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam        }
294b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam        // turn on usage bits the consumer requested
295b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam        usage |= mConsumerUsageBits;
296b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
2976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        int found = -1;
2986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        int dequeuedCount = 0;
2996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        bool tryAgain = true;
3006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        while (tryAgain) {
3016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            if (mAbandoned) {
3026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
3036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                return NO_INIT;
3046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            }
3056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
306e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis            const int maxBufferCount = getMaxBufferCountLocked();
3076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
308e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis            // Free up any buffers that are in slots beyond the max buffer
309e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis            // count.
310e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis            for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) {
311e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis                assert(mSlots[i].mBufferState == BufferSlot::FREE);
312e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis                if (mSlots[i].mGraphicBuffer != NULL) {
313e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis                    freeBufferLocked(i);
314e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis                    returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
315e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis                }
3166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            }
3176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
3186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            // look for a free buffer to give to the client
3196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            found = INVALID_BUFFER_SLOT;
3206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            dequeuedCount = 0;
321e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis            for (int i = 0; i < maxBufferCount; i++) {
3226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                const int state = mSlots[i].mBufferState;
3236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                if (state == BufferSlot::DEQUEUED) {
3246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                    dequeuedCount++;
3256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                }
3266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
327eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                // this logic used to be if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER)
328eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                // but dequeuing the current buffer is disabled.
329eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                if (false) {
330eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                    // This functionality has been temporarily removed so
331eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                    // BufferQueue and SurfaceTexture can be refactored into
332eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                    // separate objects
3336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                } else {
3346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                    if (state == BufferSlot::FREE) {
3356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                        /* We return the oldest of the free buffers to avoid
3366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                         * stalling the producer if possible.  This is because
3376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                         * the consumer may still have pending reads of the
3386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                         * buffers in flight.
3396b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                         */
3406b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                        bool isOlder = mSlots[i].mFrameNumber <
3416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                                mSlots[found].mFrameNumber;
3426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                        if (found < 0 || isOlder) {
3436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                            found = i;
3446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                        }
3456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                    }
3466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                }
3476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            }
3486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
3496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            // clients are not allowed to dequeue more than one buffer
3506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            // if they didn't set a buffer count.
35131a353da225af5329735451c761b430d82dfda1bJamie Gennis            if (!mOverrideMaxBufferCount && dequeuedCount) {
3526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without "
3536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                        "setting the buffer count");
3546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                return -EINVAL;
3556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            }
3566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
3576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            // See whether a buffer has been queued since the last
35872f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis            // setBufferCount so we know whether to perform the min undequeued
35972f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis            // buffers check below.
360eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam            if (mBufferHasBeenQueued) {
3616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                // make sure the client is not trying to dequeue more buffers
3626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                // than allowed.
36372f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis                const int newUndequeuedCount = maxBufferCount - (dequeuedCount+1);
36472f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis                const int minUndequeuedCount = getMinUndequeuedBufferCountLocked();
36572f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis                if (newUndequeuedCount < minUndequeuedCount) {
36672f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis                    ST_LOGE("dequeueBuffer: min undequeued buffer count (%d) "
36772f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis                            "exceeded (dequeued=%d undequeudCount=%d)",
36872f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis                            minUndequeuedCount, dequeuedCount,
36972f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis                            newUndequeuedCount);
3706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                    return -EBUSY;
3716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                }
3726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            }
3736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
374e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis            // If no buffer is found, wait for a buffer to be released or for
375e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis            // the max buffer count to change.
376c2c1f2f24cd70bdcf1958157bab38467bf0fdc71Daniel Lam            tryAgain = found == INVALID_BUFFER_SLOT;
3776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            if (tryAgain) {
3786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                mDequeueCondition.wait(mMutex);
3796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            }
3806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        }
3816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
3826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
3836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        if (found == INVALID_BUFFER_SLOT) {
3846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            // This should not happen.
3856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            ST_LOGE("dequeueBuffer: no available buffer slots");
3866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            return -EBUSY;
3876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        }
3886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
3896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        const int buf = found;
3906b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        *outBuf = found;
3916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
392546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian        ATRACE_BUFFER_INDEX(buf);
393546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian
3946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        const bool useDefaultSize = !w && !h;
3956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        if (useDefaultSize) {
3966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            // use the default size
3976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            w = mDefaultWidth;
3986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            h = mDefaultHeight;
3996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        }
4006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
4016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        // buffer is now in DEQUEUED (but can also be current at the same time,
4026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        // if we're in synchronous mode)
4036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
4046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
4056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
4066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        if ((buffer == NULL) ||
4076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            (uint32_t(buffer->width)  != w) ||
4086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            (uint32_t(buffer->height) != h) ||
4096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            (uint32_t(buffer->format) != format) ||
4106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            ((uint32_t(buffer->usage) & usage) != usage))
4116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        {
4126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            status_t error;
4136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            sp<GraphicBuffer> graphicBuffer(
4146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                    mGraphicBufferAlloc->createGraphicBuffer(
4156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                            w, h, format, usage, &error));
4166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            if (graphicBuffer == 0) {
4176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "
4186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                        "failed");
4196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                return error;
4206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            }
421eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
422eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam            mSlots[buf].mAcquireCalled = false;
4236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            mSlots[buf].mGraphicBuffer = graphicBuffer;
4246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            mSlots[buf].mRequestBufferCalled = false;
425c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall            mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
426c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall            mSlots[buf].mFence.clear();
427eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam            mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
428eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
4296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
4306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        }
4316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
4326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        dpy = mSlots[buf].mEglDisplay;
433c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall        eglFence = mSlots[buf].mEglFence;
434c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall        outFence = mSlots[buf].mFence;
435c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall        mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
436c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall        mSlots[buf].mFence.clear();
437eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    }  // end lock scope
4386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
439c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall    if (eglFence != EGL_NO_SYNC_KHR) {
440c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall        EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000);
4416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        // If something goes wrong, log the error, but return the buffer without
4426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        // synchronizing access to it.  It's too late at this point to abort the
4436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        // dequeue operation.
4446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        if (result == EGL_FALSE) {
445b7a6b96301c00c630610df4cb55a45d666200817Jamie Gennis            ST_LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError());
4466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
447b7a6b96301c00c630610df4cb55a45d666200817Jamie Gennis            ST_LOGE("dequeueBuffer: timeout waiting for fence");
4486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        }
449c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall        eglDestroySyncKHR(dpy, eglFence);
4506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
4516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
4526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf,
4536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            mSlots[*outBuf].mGraphicBuffer->handle, returnFlags);
4546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
4556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    return returnFlags;
4566b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
4576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
4586b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::setSynchronousMode(bool enabled) {
4591c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
4606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    ST_LOGV("setSynchronousMode: enabled=%d", enabled);
4616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    Mutex::Autolock lock(mMutex);
4626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
4636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    if (mAbandoned) {
4646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!");
4656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        return NO_INIT;
4666b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
4676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
4686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    status_t err = OK;
4696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    if (!mAllowSynchronousMode && enabled)
4706b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        return err;
4716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
4726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    if (!enabled) {
4736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        // going to asynchronous mode, drain the queue
4746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        err = drainQueueLocked();
4756b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        if (err != NO_ERROR)
4766b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            return err;
4776b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
4786b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
4796b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    if (mSynchronousMode != enabled) {
4806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        // - if we're going to asynchronous mode, the queue is guaranteed to be
4816b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        // empty here
4826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        // - if the client set the number of buffers, we're guaranteed that
4836b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        // we have at least 3 (because we don't allow less)
4846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        mSynchronousMode = enabled;
48574ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke        mDequeueCondition.broadcast();
4866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
4876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    return err;
4886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
4896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
490f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopianstatus_t BufferQueue::queueBuffer(int buf,
491f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopian        const QueueBufferInput& input, QueueBufferOutput* output) {
4921c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
493546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian    ATRACE_BUFFER_INDEX(buf);
494546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian
495efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    Rect crop;
496efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    uint32_t transform;
497efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    int scalingMode;
498efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    int64_t timestamp;
499c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall    sp<Fence> fence;
500efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis
501c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall    input.deflate(&timestamp, &crop, &scalingMode, &transform, &fence);
502efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis
503cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis    ST_LOGV("queueBuffer: slot=%d time=%#llx crop=[%d,%d,%d,%d] tr=%#x "
504cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis            "scale=%s",
505cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis            buf, timestamp, crop.left, crop.top, crop.right, crop.bottom,
506cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis            transform, scalingModeName(scalingMode));
5076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
508fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    sp<ConsumerListener> listener;
5096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
5106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    { // scope for the lock
5116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        Mutex::Autolock lock(mMutex);
5126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        if (mAbandoned) {
5136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!");
5146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            return NO_INIT;
5156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        }
516e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        int maxBufferCount = getMaxBufferCountLocked();
517e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        if (buf < 0 || buf >= maxBufferCount) {
5186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d",
519e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis                    maxBufferCount, buf);
5206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            return -EINVAL;
5216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
5226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            ST_LOGE("queueBuffer: slot %d is not owned by the client "
5236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                    "(state=%d)", buf, mSlots[buf].mBufferState);
5246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            return -EINVAL;
5256b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        } else if (!mSlots[buf].mRequestBufferCalled) {
5266b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "
5276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                    "buffer", buf);
5286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            return -EINVAL;
5296b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        }
5306b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
531d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis        const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer);
532d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis        Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
533d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis        Rect croppedCrop;
534d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis        crop.intersect(bufferRect, &croppedCrop);
535d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis        if (croppedCrop != crop) {
536d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis            ST_LOGE("queueBuffer: crop rect is not contained within the "
537d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis                    "buffer in slot %d", buf);
538d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis            return -EINVAL;
539d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis        }
540d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis
5416b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        if (mSynchronousMode) {
5426b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            // In synchronous mode we queue all buffers in a FIFO.
5436b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            mQueue.push_back(buf);
5446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
5456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            // Synchronous mode always signals that an additional frame should
5466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            // be consumed.
547fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis            listener = mConsumerListener;
5486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        } else {
5496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            // In asynchronous mode we only keep the most recent buffer.
5506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            if (mQueue.empty()) {
5516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                mQueue.push_back(buf);
5526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
5536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                // Asynchronous mode only signals that a frame should be
5546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                // consumed if no previous frame was pending. If a frame were
5556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                // pending then the consumer would have already been notified.
556fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                listener = mConsumerListener;
5576b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            } else {
5586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                Fifo::iterator front(mQueue.begin());
5596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                // buffer currently queued is freed
5606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                mSlots[*front].mBufferState = BufferSlot::FREE;
5616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                // and we record the new buffer index in the queued list
5626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                *front = buf;
5636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            }
5646b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        }
5656b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
566efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis        mSlots[buf].mTimestamp = timestamp;
567efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis        mSlots[buf].mCrop = crop;
568efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis        mSlots[buf].mTransform = transform;
569c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall        mSlots[buf].mFence = fence;
570f0bc2f1d8d37977bd3aef3d3326a70e9e69d4246Mathias Agopian
571851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian        switch (scalingMode) {
572851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian            case NATIVE_WINDOW_SCALING_MODE_FREEZE:
573851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian            case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
574016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
575851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian                break;
576851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian            default:
577851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian                ST_LOGE("unknown scaling mode: %d (ignoring)", scalingMode);
578851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian                scalingMode = mSlots[buf].mScalingMode;
579851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian                break;
580851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian        }
581851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian
5826b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        mSlots[buf].mBufferState = BufferSlot::QUEUED;
583851ef8f1bfbb164d61b1528a529a464f0a60dbafMathias Agopian        mSlots[buf].mScalingMode = scalingMode;
5846b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        mFrameCounter++;
5856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        mSlots[buf].mFrameNumber = mFrameCounter;
5866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
587eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        mBufferHasBeenQueued = true;
58874ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke        mDequeueCondition.broadcast();
5896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
5902488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian        output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
5912488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian                mQueue.size());
5921c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
5931c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis        ATRACE_INT(mConsumerName.string(), mQueue.size());
5946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    } // scope for the lock
5956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
5966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    // call back without lock held
5976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    if (listener != 0) {
5986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        listener->onFrameAvailable();
5996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
6006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    return OK;
6016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
6026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
603c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hallvoid BufferQueue::cancelBuffer(int buf, sp<Fence> fence) {
6041c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
6056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    ST_LOGV("cancelBuffer: slot=%d", buf);
6066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    Mutex::Autolock lock(mMutex);
6076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
6086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    if (mAbandoned) {
6096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        ST_LOGW("cancelBuffer: BufferQueue has been abandoned!");
6106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        return;
6116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
6126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
613e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    int maxBufferCount = getMaxBufferCountLocked();
614e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    if (buf < 0 || buf >= maxBufferCount) {
6156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
616e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis                maxBufferCount, buf);
6176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        return;
6186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
6196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
6206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                buf, mSlots[buf].mBufferState);
6216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        return;
6226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
6236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    mSlots[buf].mBufferState = BufferSlot::FREE;
6246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    mSlots[buf].mFrameNumber = 0;
625c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall    mSlots[buf].mFence = fence;
62674ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke    mDequeueCondition.broadcast();
6276b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
6286b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
62924202f5676c32edeef6544cf36e06b9fc970dbdeMathias Agopianstatus_t BufferQueue::connect(int api, QueueBufferOutput* output) {
6301c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
6316b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    ST_LOGV("connect: api=%d", api);
6326b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    Mutex::Autolock lock(mMutex);
6336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
6346b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    if (mAbandoned) {
6356b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        ST_LOGE("connect: BufferQueue has been abandoned!");
6366b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        return NO_INIT;
6376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
6386b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
639fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    if (mConsumerListener == NULL) {
640fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        ST_LOGE("connect: BufferQueue has no consumer!");
641fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        return NO_INIT;
642fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    }
643fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
6446b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    int err = NO_ERROR;
6456b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    switch (api) {
6466b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        case NATIVE_WINDOW_API_EGL:
6476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        case NATIVE_WINDOW_API_CPU:
6486b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        case NATIVE_WINDOW_API_MEDIA:
6496b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        case NATIVE_WINDOW_API_CAMERA:
6506b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            if (mConnectedApi != NO_CONNECTED_API) {
6516b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                ST_LOGE("connect: already connected (cur=%d, req=%d)",
6526b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                        mConnectedApi, api);
6536b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                err = -EINVAL;
6546b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            } else {
6556b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                mConnectedApi = api;
6562488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian                output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
6572488b20aec097accb20a853d9876bb0a5dc04636Mathias Agopian                        mQueue.size());
6586b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            }
6596b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            break;
6606b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        default:
6616b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            err = -EINVAL;
6626b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            break;
6636b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
664eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
665eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    mBufferHasBeenQueued = false;
666eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
6676b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    return err;
6686b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
6696b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
6706b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::disconnect(int api) {
6711c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
6726b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    ST_LOGV("disconnect: api=%d", api);
6736b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
6746b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    int err = NO_ERROR;
675fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    sp<ConsumerListener> listener;
676fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
677fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    { // Scope for the lock
678fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        Mutex::Autolock lock(mMutex);
679fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
680fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        if (mAbandoned) {
681fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis            // it is not really an error to disconnect after the surface
682fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis            // has been abandoned, it should just be a no-op.
683fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis            return NO_ERROR;
684fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        }
685fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
686fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        switch (api) {
687fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis            case NATIVE_WINDOW_API_EGL:
688fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis            case NATIVE_WINDOW_API_CPU:
689fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis            case NATIVE_WINDOW_API_MEDIA:
690fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis            case NATIVE_WINDOW_API_CAMERA:
691fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                if (mConnectedApi == api) {
692fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                    drainQueueAndFreeBuffersLocked();
693fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                    mConnectedApi = NO_CONNECTED_API;
694fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                    mDequeueCondition.broadcast();
695fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                    listener = mConsumerListener;
696fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                } else {
697fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                    ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)",
698fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                            mConnectedApi, api);
699fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                    err = -EINVAL;
700fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                }
701fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                break;
702fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis            default:
703fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                ST_LOGE("disconnect: unknown API %d", api);
7046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam                err = -EINVAL;
705fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                break;
706fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        }
7076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
708fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
709fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    if (listener != NULL) {
710fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        listener->onBuffersReleased();
711fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    }
712fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
7136b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    return err;
7146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
7156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
716eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamvoid BufferQueue::dump(String8& result) const
717eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam{
718eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    char buffer[1024];
719eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    BufferQueue::dump(result, "", buffer, 1024);
720eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam}
721eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
722eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamvoid BufferQueue::dump(String8& result, const char* prefix,
723eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        char* buffer, size_t SIZE) const
724eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam{
725eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    Mutex::Autolock _l(mMutex);
726eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
727eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    String8 fifo;
728eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    int fifoSize = 0;
729eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    Fifo::const_iterator i(mQueue.begin());
730eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    while (i != mQueue.end()) {
731eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam       snprintf(buffer, SIZE, "%02d ", *i++);
732eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam       fifoSize++;
733eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam       fifo.append(buffer);
734eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    }
735eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
736e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    int maxBufferCount = getMaxBufferCountLocked();
737e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis
738eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    snprintf(buffer, SIZE,
739e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis            "%s-BufferQueue maxBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
7401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis            "default-format=%d, FIFO(%d)={%s}\n",
741e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis            prefix, maxBufferCount, mSynchronousMode, mDefaultWidth,
7421a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis            mDefaultHeight, mDefaultBufferFormat, fifoSize, fifo.string());
743eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    result.append(buffer);
744eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
745eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
746eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    struct {
747eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        const char * operator()(int state) const {
748eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam            switch (state) {
749eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                case BufferSlot::DEQUEUED: return "DEQUEUED";
750eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                case BufferSlot::QUEUED: return "QUEUED";
751eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                case BufferSlot::FREE: return "FREE";
752eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                case BufferSlot::ACQUIRED: return "ACQUIRED";
753eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                default: return "Unknown";
754eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam            }
755eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        }
756eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    } stateName;
757eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
758e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    for (int i=0 ; i<maxBufferCount ; i++) {
759eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        const BufferSlot& slot(mSlots[i]);
760eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        snprintf(buffer, SIZE,
761eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                "%s%s[%02d] "
762eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                "state=%-8s, crop=[%d,%d,%d,%d], "
763cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis                "xform=0x%02x, time=%#llx, scale=%s",
764eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i,
765eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                stateName(slot.mBufferState),
766eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
767cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis                slot.mCrop.bottom, slot.mTransform, slot.mTimestamp,
768cd1806e210f2633423f0fb14d39fa00d03974223Jamie Gennis                scalingModeName(slot.mScalingMode)
769eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        );
770eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        result.append(buffer);
771eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
772eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
773eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        if (buf != NULL) {
774eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam            snprintf(buffer, SIZE,
775eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                    ", %p [%4ux%4u:%4u,%3X]",
776eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                    buf->handle, buf->width, buf->height, buf->stride,
777eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                    buf->format);
778eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam            result.append(buffer);
779eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        }
780eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        result.append("\n");
781eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    }
782eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam}
783eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
7841a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid BufferQueue::freeBufferLocked(int slot) {
7851a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    ST_LOGV("freeBufferLocked: slot=%d", slot);
7861a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mSlots[slot].mGraphicBuffer = 0;
7871a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
7881a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        mSlots[slot].mNeedsCleanupOnRelease = true;
7899abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    }
7901a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mSlots[slot].mBufferState = BufferSlot::FREE;
7911a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mSlots[slot].mFrameNumber = 0;
7921a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mSlots[slot].mAcquireCalled = false;
793eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
794eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    // destroy fence as BufferQueue now takes ownership
7951a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) {
7961a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence);
7971a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
7986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
7991a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mSlots[slot].mFence.clear();
8006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
8016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
8026b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::freeAllBuffersLocked() {
8036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    ALOGW_IF(!mQueue.isEmpty(),
8046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            "freeAllBuffersLocked called but mQueue is not empty");
805eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    mQueue.clear();
806eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    mBufferHasBeenQueued = false;
8076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
8086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        freeBufferLocked(i);
8096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
8106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
8116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
812fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisstatus_t BufferQueue::acquireBuffer(BufferItem *buffer) {
813546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian    ATRACE_CALL();
814eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    Mutex::Autolock _l(mMutex);
8155e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis
8165e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis    // Check that the consumer doesn't currently have the maximum number of
8175e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis    // buffers acquired.  We allow the max buffer count to be exceeded by one
8185e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis    // buffer, so that the consumer can successfully set up the newly acquired
8195e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis    // buffer before releasing the old one.
8205e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis    int numAcquiredBuffers = 0;
8215e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
8225e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis        if (mSlots[i].mBufferState == BufferSlot::ACQUIRED) {
8235e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis            numAcquiredBuffers++;
8245e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis        }
8255e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis    }
8265e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis    if (numAcquiredBuffers >= mMaxAcquiredBufferCount+1) {
8275e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis        ST_LOGE("acquireBuffer: max acquired buffer count reached: %d (max=%d)",
8285e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis                numAcquiredBuffers, mMaxAcquiredBufferCount);
8295e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis        return INVALID_OPERATION;
8305e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis    }
8315e5efde7874a9fab650fd4b724ceef46db850470Jamie Gennis
832eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    // check if queue is empty
833eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    // In asynchronous mode the list is guaranteed to be one buffer
834eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    // deep, while in synchronous mode we use the oldest buffer.
835eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    if (!mQueue.empty()) {
836eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        Fifo::iterator front(mQueue.begin());
837eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        int buf = *front;
838eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
839546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian        ATRACE_BUFFER_INDEX(buf);
840546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian
841eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        if (mSlots[buf].mAcquireCalled) {
842eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam            buffer->mGraphicBuffer = NULL;
843fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        } else {
844eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam            buffer->mGraphicBuffer = mSlots[buf].mGraphicBuffer;
845eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        }
846eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        buffer->mCrop = mSlots[buf].mCrop;
847eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        buffer->mTransform = mSlots[buf].mTransform;
848eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        buffer->mScalingMode = mSlots[buf].mScalingMode;
849eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        buffer->mFrameNumber = mSlots[buf].mFrameNumber;
8503fcee50ffaeb745819356e395408b4d7e3239c13Daniel Lam        buffer->mTimestamp = mSlots[buf].mTimestamp;
851eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        buffer->mBuf = buf;
852b42b1ac1587aebda5e2f334d95b620271fafba4eJesse Hall        buffer->mFence = mSlots[buf].mFence;
853eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
8541a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        mSlots[buf].mAcquireCalled = true;
8551a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        mSlots[buf].mNeedsCleanupOnRelease = false;
856eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
8571a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        mSlots[buf].mFence.clear();
8581a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
859eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        mQueue.erase(front);
86074ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke        mDequeueCondition.broadcast();
8611c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
8621c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis        ATRACE_INT(mConsumerName.string(), mQueue.size());
863fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    } else {
864fbcda930dd8b2823cfeb160fd0131f5897b7522fDaniel Lam        return NO_BUFFER_AVAILABLE;
865eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    }
866eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
867eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    return OK;
868eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam}
869eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
870eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatus_t BufferQueue::releaseBuffer(int buf, EGLDisplay display,
871c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall        EGLSyncKHR eglFence, const sp<Fence>& fence) {
872546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian    ATRACE_CALL();
873546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian    ATRACE_BUFFER_INDEX(buf);
874546ed2d7d98ce4f1415647913a231a6b4fc6ca66Mathias Agopian
875eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    Mutex::Autolock _l(mMutex);
876eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
877eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    if (buf == INVALID_BUFFER_SLOT) {
878eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        return -EINVAL;
879eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    }
880eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
881eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    mSlots[buf].mEglDisplay = display;
882c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall    mSlots[buf].mEglFence = eglFence;
883eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    mSlots[buf].mFence = fence;
884eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
8859abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // The buffer can now only be released if its in the acquired state
8869abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) {
887eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        mSlots[buf].mBufferState = BufferSlot::FREE;
8889abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    } else if (mSlots[buf].mNeedsCleanupOnRelease) {
8899abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        ST_LOGV("releasing a stale buf %d its state was %d", buf, mSlots[buf].mBufferState);
8909abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        mSlots[buf].mNeedsCleanupOnRelease = false;
8919abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        return STALE_BUFFER_SLOT;
8929abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    } else {
8939abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        ST_LOGE("attempted to release buf %d but its state was %d", buf, mSlots[buf].mBufferState);
8949abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        return -EINVAL;
895eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    }
896eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
8979abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    mDequeueCondition.broadcast();
898eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    return OK;
899eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam}
900eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
901fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisstatus_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListener) {
902fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    ST_LOGV("consumerConnect");
903fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    Mutex::Autolock lock(mMutex);
904fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
905fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    if (mAbandoned) {
906fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        ST_LOGE("consumerConnect: BufferQueue has been abandoned!");
907fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        return NO_INIT;
908fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    }
909fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
910fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    mConsumerListener = consumerListener;
911fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
912fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    return OK;
913fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis}
914fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
915eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatus_t BufferQueue::consumerDisconnect() {
916fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    ST_LOGV("consumerDisconnect");
917eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    Mutex::Autolock lock(mMutex);
918b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
919fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    if (mConsumerListener == NULL) {
920fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        ST_LOGE("consumerDisconnect: No consumer is connected!");
921fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        return -EINVAL;
922fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    }
923b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
924fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    mAbandoned = true;
925fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    mConsumerListener = NULL;
926b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mQueue.clear();
927eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    freeAllBuffersLocked();
92874ff8c23f44f1546d0c7004302f4c7ba726ff4c0Dave Burke    mDequeueCondition.broadcast();
929eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    return OK;
930eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam}
931eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
932fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisstatus_t BufferQueue::getReleasedBuffers(uint32_t* slotMask) {
933fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    ST_LOGV("getReleasedBuffers");
934fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    Mutex::Autolock lock(mMutex);
935fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
936fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    if (mAbandoned) {
937fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        ST_LOGE("getReleasedBuffers: BufferQueue has been abandoned!");
938fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        return NO_INIT;
939fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    }
940fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
941fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    uint32_t mask = 0;
942fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
943fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        if (!mSlots[i].mAcquireCalled) {
944fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis            mask |= 1 << i;
945fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        }
946fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    }
947fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    *slotMask = mask;
948fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
949fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    ST_LOGV("getReleasedBuffers: returning mask %#x", mask);
950fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    return NO_ERROR;
951fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis}
952fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
953eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatus_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h)
954eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam{
955eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h);
956eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    if (!w || !h) {
957eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
958eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam                w, h);
959eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam        return BAD_VALUE;
960eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    }
961eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
962eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    Mutex::Autolock lock(mMutex);
963eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    mDefaultWidth = w;
964eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    mDefaultHeight = h;
965eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    return OK;
966eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam}
967eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
96831a353da225af5329735451c761b430d82dfda1bJamie Gennisstatus_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) {
9691c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
970eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    Mutex::Autolock lock(mMutex);
97131a353da225af5329735451c761b430d82dfda1bJamie Gennis    return setDefaultMaxBufferCountLocked(bufferCount);
972eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam}
973eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam
97472f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennisstatus_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
97572f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis    ATRACE_CALL();
97672f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis    Mutex::Autolock lock(mMutex);
97772f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis    if (mConnectedApi != NO_CONNECTED_API) {
97872f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis        return INVALID_OPERATION;
97972f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis    }
98072f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis    mMaxAcquiredBufferCount = maxAcquiredBuffers;
98172f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis    return OK;
98272f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis}
98372f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis
9846b091c53000c843211c218ce40287a7edca9bc63Daniel Lamvoid BufferQueue::freeAllBuffersExceptHeadLocked() {
9856b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    int head = -1;
9866b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    if (!mQueue.empty()) {
9876b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        Fifo::iterator front(mQueue.begin());
9886b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        head = *front;
9896b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
990eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam    mBufferHasBeenQueued = false;
9916b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
9926b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        if (i != head) {
9936b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            freeBufferLocked(i);
9946b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        }
9956b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
9966b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
9976b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
9986b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::drainQueueLocked() {
9996b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    while (mSynchronousMode && !mQueue.isEmpty()) {
10006b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        mDequeueCondition.wait(mMutex);
10016b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        if (mAbandoned) {
10026b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            ST_LOGE("drainQueueLocked: BufferQueue has been abandoned!");
10036b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            return NO_INIT;
10046b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        }
10056b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        if (mConnectedApi == NO_CONNECTED_API) {
10066b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            ST_LOGE("drainQueueLocked: BufferQueue is not connected!");
10076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            return NO_INIT;
10086b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        }
10096b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
10106b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    return NO_ERROR;
10116b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
10126b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
10136b091c53000c843211c218ce40287a7edca9bc63Daniel Lamstatus_t BufferQueue::drainQueueAndFreeBuffersLocked() {
10146b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    status_t err = drainQueueLocked();
10156b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    if (err == NO_ERROR) {
10166b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        if (mSynchronousMode) {
10176b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            freeAllBuffersLocked();
10186b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        } else {
10196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam            freeAllBuffersExceptHeadLocked();
10206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam        }
10216b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    }
10226b091c53000c843211c218ce40287a7edca9bc63Daniel Lam    return err;
10236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}
10246b091c53000c843211c218ce40287a7edca9bc63Daniel Lam
102531a353da225af5329735451c761b430d82dfda1bJamie Gennisint BufferQueue::getMinMaxBufferCountLocked() const {
102672f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis    return getMinUndequeuedBufferCountLocked() + 1;
102772f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis}
102872f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis
102972f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennisint BufferQueue::getMinUndequeuedBufferCountLocked() const {
103072f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis    return mSynchronousMode ? mMaxAcquiredBufferCount :
103172f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis            mMaxAcquiredBufferCount + 1;
103231a353da225af5329735451c761b430d82dfda1bJamie Gennis}
103331a353da225af5329735451c761b430d82dfda1bJamie Gennis
1034e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennisint BufferQueue::getMaxBufferCountLocked() const {
1035e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    int minMaxBufferCount = getMinMaxBufferCountLocked();
1036e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis
1037e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    int maxBufferCount = mDefaultMaxBufferCount;
1038e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    if (maxBufferCount < minMaxBufferCount) {
1039e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        maxBufferCount = minMaxBufferCount;
1040e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    }
1041e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    if (mOverrideMaxBufferCount != 0) {
1042e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        assert(mOverrideMaxBufferCount >= minMaxBufferCount);
1043e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        maxBufferCount = mOverrideMaxBufferCount;
1044e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    }
1045e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis
1046e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    // Any buffers that are dequeued by the producer or sitting in the queue
1047e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    // waiting to be consumed need to have their slots preserved.  Such
1048e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    // buffers will temporarily keep the max buffer count up until the slots
1049e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    // no longer need to be preserved.
1050e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) {
1051e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        BufferSlot::BufferState state = mSlots[i].mBufferState;
1052e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        if (state == BufferSlot::QUEUED || state == BufferSlot::DEQUEUED) {
1053e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis            maxBufferCount = i + 1;
1054e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis        }
1055e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    }
1056e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis
1057e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis    return maxBufferCount;
1058e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis}
1059e191e6c34829aec406a9cfe3e95211f884a311ffJamie Gennis
1060fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie GennisBufferQueue::ProxyConsumerListener::ProxyConsumerListener(
1061fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        const wp<BufferQueue::ConsumerListener>& consumerListener):
1062fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        mConsumerListener(consumerListener) {}
1063fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
1064fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie GennisBufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {}
1065fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
1066fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid BufferQueue::ProxyConsumerListener::onFrameAvailable() {
1067fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote());
1068fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    if (listener != NULL) {
1069fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        listener->onFrameAvailable();
1070fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    }
1071fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis}
1072fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
1073fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid BufferQueue::ProxyConsumerListener::onBuffersReleased() {
1074fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote());
1075fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    if (listener != NULL) {
1076fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        listener->onBuffersReleased();
1077fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    }
1078fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis}
1079fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
10806b091c53000c843211c218ce40287a7edca9bc63Daniel Lam}; // namespace android
1081