ConsumerBase.cpp revision 7aff4a5de47bf32b0934f5744cd1df4ce666d2d2
11a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis/*
21a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * Copyright (C) 2010 The Android Open Source Project
31a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis *
41a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * Licensed under the Apache License, Version 2.0 (the "License");
51a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * you may not use this file except in compliance with the License.
61a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * You may obtain a copy of the License at
71a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis *
81a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis *      http://www.apache.org/licenses/LICENSE-2.0
91a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis *
101a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * Unless required by applicable law or agreed to in writing, software
111a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * distributed under the License is distributed on an "AS IS" BASIS,
121a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * See the License for the specific language governing permissions and
141a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * limitations under the License.
151a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis */
161a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
171a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#define LOG_TAG "ConsumerBase"
181a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
191a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis//#define LOG_NDEBUG 0
201a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
211a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#define GL_GLEXT_PROTOTYPES
221a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#define EGL_EGLEXT_PROTOTYPES
231a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
241a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <EGL/egl.h>
251a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <EGL/eglext.h>
261a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
271a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <hardware/hardware.h>
281a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
291a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IGraphicBufferAlloc.h>
301a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/ISurfaceComposer.h>
311a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/SurfaceComposerClient.h>
321a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/ConsumerBase.h>
331a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
341a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <private/gui/ComposerService.h>
351a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
361a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <utils/Log.h>
371a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <utils/String8.h>
381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <utils/Trace.h>
391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis// Macros for including the ConsumerBase name in log messages
411a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#define CB_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
421a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#define CB_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
431a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#define CB_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
441a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#define CB_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
451a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#define CB_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
461a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
471a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisnamespace android {
481a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
491a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis// Get an ID that's unique within this process.
501a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisstatic int32_t createProcessUniqueId() {
511a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    static volatile int32_t globalCounter = 0;
521a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    return android_atomic_inc(&globalCounter);
531a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
541a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
551a4d883dcc1725892bfb5c28dec255a233186524Jamie GennisConsumerBase::ConsumerBase(const sp<BufferQueue>& bufferQueue) :
569fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis        mAbandoned(false),
579fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis        mBufferQueue(bufferQueue) {
581a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // Choose a name using the PID and a process-unique ID.
591a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
601a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
611a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // Note that we can't create an sp<...>(this) in a ctor that will not keep a
621a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // reference once the ctor ends, as that would cause the refcount of 'this'
631a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
641a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // that's what we create.
651a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    wp<BufferQueue::ConsumerListener> listener;
661a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    sp<BufferQueue::ConsumerListener> proxy;
671a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    listener = static_cast<BufferQueue::ConsumerListener*>(this);
681a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    proxy = new BufferQueue::ProxyConsumerListener(listener);
691a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
701a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    status_t err = mBufferQueue->consumerConnect(proxy);
711a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (err != NO_ERROR) {
721a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        CB_LOGE("SurfaceTexture: error connecting to BufferQueue: %s (%d)",
731a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis                strerror(-err), err);
741a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    } else {
751a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        mBufferQueue->setConsumerName(mName);
761a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    }
771a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
781a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
791a4d883dcc1725892bfb5c28dec255a233186524Jamie GennisConsumerBase::~ConsumerBase() {
801a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis	CB_LOGV("~ConsumerBase");
811a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    abandon();
821a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
831a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
841a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid ConsumerBase::freeBufferLocked(int slotIndex) {
851a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    CB_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
861a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mSlots[slotIndex].mGraphicBuffer = 0;
871a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mSlots[slotIndex].mFence = 0;
881a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
891a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
901a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis// Used for refactoring, should not be in final interface
911a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennissp<BufferQueue> ConsumerBase::getBufferQueue() const {
921a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    Mutex::Autolock lock(mMutex);
931a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    return mBufferQueue;
941a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
951a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
961a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid ConsumerBase::onFrameAvailable() {
971a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    CB_LOGV("onFrameAvailable");
981a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
991a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    sp<FrameAvailableListener> listener;
1001a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    { // scope for the lock
1011a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        Mutex::Autolock lock(mMutex);
1021a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        listener = mFrameAvailableListener;
1031a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    }
1041a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1051a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (listener != NULL) {
1061a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        CB_LOGV("actually calling onFrameAvailable");
1071a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        listener->onFrameAvailable();
1081a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    }
1091a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
1101a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1111a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid ConsumerBase::onBuffersReleased() {
1121a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    Mutex::Autolock lock(mMutex);
1131a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1141a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    CB_LOGV("onBuffersReleased");
1151a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1161a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (mAbandoned) {
1171a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        // Nothing to do if we're already abandoned.
1181a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        return;
1191a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    }
1201a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1211a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    uint32_t mask = 0;
1221a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mBufferQueue->getReleasedBuffers(&mask);
1231a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
1241a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        if (mask & (1 << i)) {
1251a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis            freeBufferLocked(i);
1261a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        }
1271a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    }
1281a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
1291a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1301a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid ConsumerBase::abandon() {
1311a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    CB_LOGV("abandon");
1321a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    Mutex::Autolock lock(mMutex);
1331a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1341a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (!mAbandoned) {
1351a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        abandonLocked();
1361a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        mAbandoned = true;
1371a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    }
1381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
1391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid ConsumerBase::abandonLocked() {
1411a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis	CB_LOGV("abandonLocked");
1421a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
1431a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        freeBufferLocked(i);
1441a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    }
1451a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // disconnect from the BufferQueue
1461a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mBufferQueue->consumerDisconnect();
1471a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mBufferQueue.clear();
1481a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
1491a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1501a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid ConsumerBase::setFrameAvailableListener(
1511a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        const sp<FrameAvailableListener>& listener) {
1521a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    CB_LOGV("setFrameAvailableListener");
1531a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    Mutex::Autolock lock(mMutex);
1541a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mFrameAvailableListener = listener;
1551a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
1561a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1571a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid ConsumerBase::dump(String8& result) const {
1581a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    char buffer[1024];
1591a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    dump(result, "", buffer, 1024);
1601a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
1611a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1621a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid ConsumerBase::dump(String8& result, const char* prefix,
1631a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        char* buffer, size_t size) const {
1641a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    Mutex::Autolock _l(mMutex);
1651a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    dumpLocked(result, prefix, buffer, size);
1661a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
1671a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1681a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid ConsumerBase::dumpLocked(String8& result, const char* prefix,
1691a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        char* buffer, size_t SIZE) const {
1701a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    snprintf(buffer, SIZE, "%smAbandoned=%d\n", prefix, int(mAbandoned));
1711a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    result.append(buffer);
1721a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1731a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (!mAbandoned) {
1741a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        mBufferQueue->dump(result, prefix, buffer, SIZE);
1751a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    }
1761a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
1771a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1781a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisstatus_t ConsumerBase::acquireBufferLocked(BufferQueue::BufferItem *item) {
1791a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    status_t err = mBufferQueue->acquireBuffer(item);
1801a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (err != NO_ERROR) {
1811a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        return err;
1821a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    }
1831a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1841a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (item->mGraphicBuffer != NULL) {
1851a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        mSlots[item->mBuf].mGraphicBuffer = item->mGraphicBuffer;
1861a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    }
1871a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
188b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis    mSlots[item->mBuf].mFence = item->mFence;
189b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis
1901a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    CB_LOGV("acquireBufferLocked: -> slot=%d", item->mBuf);
1911a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1921a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    return OK;
1931a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
1941a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
195b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennisstatus_t ConsumerBase::addReleaseFence(int slot, const sp<Fence>& fence) {
196b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis    CB_LOGV("addReleaseFence: slot=%d", slot);
197b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis
198b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis    if (!mSlots[slot].mFence.get()) {
199b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis        mSlots[slot].mFence = fence;
200b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis    } else {
201b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis        sp<Fence> mergedFence = Fence::merge(
2027aff4a5de47bf32b0934f5744cd1df4ce666d2d2Jamie Gennis                String8::format("%.28s:%d", mName.string(), slot),
203b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis                mSlots[slot].mFence, fence);
204b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis        if (!mergedFence.get()) {
205b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis            CB_LOGE("failed to merge release fences");
206b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis            // synchronization is broken, the best we can do is hope fences
207b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis            // signal in order so the new fence will act like a union
208b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis            mSlots[slot].mFence = fence;
209b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis            return BAD_VALUE;
210b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis        }
211b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis        mSlots[slot].mFence = mergedFence;
212b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis    }
213b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis
214b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis    return OK;
215b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis}
216b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis
2171a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisstatus_t ConsumerBase::releaseBufferLocked(int slot, EGLDisplay display,
218b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis       EGLSyncKHR eglFence) {
2191a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    CB_LOGV("releaseBufferLocked: slot=%d", slot);
220b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis    status_t err = mBufferQueue->releaseBuffer(slot, display, eglFence,
221b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis            mSlots[slot].mFence);
2221a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (err == BufferQueue::STALE_BUFFER_SLOT) {
2231a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        freeBufferLocked(slot);
2241a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    }
2251a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
2261a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mSlots[slot].mFence.clear();
2271a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
2281a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    return err;
2291a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}
2301a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
2311a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis} // namespace android