1d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin/*
2d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * Copyright (C) 2013 The Android Open Source Project
3d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *
4d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
5d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * you may not use this file except in compliance with the License.
6d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * You may obtain a copy of the License at
7d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *
8d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
9d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *
10d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * Unless required by applicable law or agreed to in writing, software
11d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
12d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * See the License for the specific language governing permissions and
14d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * limitations under the License.
15d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin */
16d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
17d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin//#define LOG_NDEBUG 0
18d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#define LOG_TAG "RingBufferConsumer"
19d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#define ATRACE_TAG ATRACE_TAG_GRAPHICS
20d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#include <utils/Log.h>
21d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
22d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#include <gui/RingBufferConsumer.h>
23d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
24d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#define BI_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
25d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#define BI_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
26d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#define BI_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
27d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#define BI_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
28d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#define BI_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
29d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
308e2afd9817e53858e3f99f810c0b7abe4c4d5533Igor Murashkin#undef assert
318e2afd9817e53858e3f99f810c0b7abe4c4d5533Igor Murashkin#define assert(x) ALOG_ASSERT((x), #x)
328e2afd9817e53858e3f99f810c0b7abe4c4d5533Igor Murashkin
33d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkintypedef android::RingBufferConsumer::PinnedBufferItem PinnedBufferItem;
34d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
35d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkinnamespace android {
36d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
37deeef54487a34034dc0cfaab20b20d557224c07cMathias AgopianRingBufferConsumer::RingBufferConsumer(const sp<IGraphicBufferConsumer>& consumer,
38deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian        uint32_t consumerUsage,
39d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        int bufferCount) :
40deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian    ConsumerBase(consumer),
41d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    mBufferCount(bufferCount)
42d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin{
43deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian    mConsumer->setConsumerUsageBits(consumerUsage);
44deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian    mConsumer->setMaxAcquiredBufferCount(bufferCount);
45d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
46d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    assert(bufferCount > 0);
47d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin}
48d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
49d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor MurashkinRingBufferConsumer::~RingBufferConsumer() {
50d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin}
51d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
52d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkinvoid RingBufferConsumer::setName(const String8& name) {
53d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    Mutex::Autolock _l(mMutex);
54d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    mName = name;
55deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian    mConsumer->setConsumerName(name);
56d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin}
57d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
58d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkinsp<PinnedBufferItem> RingBufferConsumer::pinSelectedBuffer(
59d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        const RingBufferComparator& filter,
60d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        bool waitForFence) {
61d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
62d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    sp<PinnedBufferItem> pinnedBuffer;
63d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
64d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    {
65d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        List<RingBufferItem>::iterator it, end, accIt;
66d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        BufferInfo acc, cur;
67d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        BufferInfo* accPtr = NULL;
68d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
69d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        Mutex::Autolock _l(mMutex);
70d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
71d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        for (it = mBufferItemList.begin(), end = mBufferItemList.end();
72d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin             it != end;
73d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin             ++it) {
74d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
75d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            const RingBufferItem& item = *it;
76d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
77d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            cur.mCrop = item.mCrop;
78d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            cur.mTransform = item.mTransform;
79d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            cur.mScalingMode = item.mScalingMode;
80d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            cur.mTimestamp = item.mTimestamp;
81d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            cur.mFrameNumber = item.mFrameNumber;
82d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            cur.mPinned = item.mPinCount > 0;
83d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
84d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            int ret = filter.compare(accPtr, &cur);
85d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
86d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            if (ret == 0) {
87d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                accPtr = NULL;
88d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            } else if (ret > 0) {
89d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                acc = cur;
90d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                accPtr = &acc;
91d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                accIt = it;
92d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            } // else acc = acc
93d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
94d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
95d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        if (!accPtr) {
96d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            return NULL;
97d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
98d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
99d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        pinnedBuffer = new PinnedBufferItem(this, *accIt);
100d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        pinBufferLocked(pinnedBuffer->getBufferItem());
101d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
102d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    } // end scope of mMutex autolock
103d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
104d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    if (waitForFence) {
105d76442421eadfa73f2f3a9e50f6caf65b0dd1ce9Mathias Agopian        status_t err = pinnedBuffer->getBufferItem().mFence->waitForever(
106d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                "RingBufferConsumer::pinSelectedBuffer");
107d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        if (err != OK) {
108d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            BI_LOGE("Failed to wait for fence of acquired buffer: %s (%d)",
109d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                    strerror(-err), err);
110d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
111d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    }
112d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
113d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    return pinnedBuffer;
114d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin}
115d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
116d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkinstatus_t RingBufferConsumer::clear() {
117d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
118d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    status_t err;
119d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    Mutex::Autolock _l(mMutex);
120d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
121d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    BI_LOGV("%s", __FUNCTION__);
122d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
123d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // Avoid annoying log warnings by returning early
124d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    if (mBufferItemList.size() == 0) {
125d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        return OK;
126d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    }
127d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
128d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    do {
129d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        size_t pinnedFrames = 0;
130d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        err = releaseOldestBufferLocked(&pinnedFrames);
131d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
132d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        if (err == NO_BUFFER_AVAILABLE) {
133d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            assert(pinnedFrames == mBufferItemList.size());
134d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            break;
135d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
136d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
137d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        if (err == NOT_ENOUGH_DATA) {
138d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            // Fine. Empty buffer item list.
139d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            break;
140d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
141d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
142d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        if (err != OK) {
143d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            BI_LOGE("Clear failed, could not release buffer");
144d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            return err;
145d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
146d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
147d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    } while(true);
148d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
149d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    return OK;
150d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin}
151d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
152d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkinvoid RingBufferConsumer::pinBufferLocked(const BufferItem& item) {
153d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    List<RingBufferItem>::iterator it, end;
154d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
155d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    for (it = mBufferItemList.begin(), end = mBufferItemList.end();
156d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin         it != end;
157d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin         ++it) {
158d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
159d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        RingBufferItem& find = *it;
160d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        if (item.mGraphicBuffer == find.mGraphicBuffer) {
161d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            find.mPinCount++;
162d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            break;
163d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
164d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    }
165d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
166d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    if (it == end) {
167d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        BI_LOGE("Failed to pin buffer (timestamp %lld, framenumber %lld)",
168d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                 item.mTimestamp, item.mFrameNumber);
169efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin    } else {
170efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin        BI_LOGV("Pinned buffer (frame %lld, timestamp %lld)",
171efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin                item.mFrameNumber, item.mTimestamp);
172d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    }
173d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin}
174d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
175d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkinstatus_t RingBufferConsumer::releaseOldestBufferLocked(size_t* pinnedFrames) {
176d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    status_t err = OK;
177d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
178d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    List<RingBufferItem>::iterator it, end, accIt;
179d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
180d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    it = mBufferItemList.begin();
181d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    end = mBufferItemList.end();
182efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin    accIt = end;
183d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
184d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    if (it == end) {
185d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        /**
186d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin         * This is fine. We really care about being able to acquire a buffer
187d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin         * successfully after this function completes, not about it releasing
188d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin         * some buffer.
189d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin         */
190d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        BI_LOGV("%s: No buffers yet acquired, can't release anything",
191d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin              __FUNCTION__);
192d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        return NOT_ENOUGH_DATA;
193d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    }
194d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
195d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    for (; it != end; ++it) {
196d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        RingBufferItem& find = *it;
197efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin
198efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin        if (find.mPinCount > 0) {
199efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin            if (pinnedFrames != NULL) {
200efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin                ++(*pinnedFrames);
201efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin            }
202efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin            // Filter out pinned frame when searching for buffer to release
203efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin            continue;
204d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
205d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
206efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin        if (find.mTimestamp < accIt->mTimestamp || accIt == end) {
207efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin            accIt = it;
208d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
209d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    }
210d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
211d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    if (accIt != end) {
212d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        RingBufferItem& item = *accIt;
213d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
214d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        // In case the object was never pinned, pass the acquire fence
215d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        // back to the release fence. If the fence was already waited on,
216d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        // it'll just be a no-op to wait on it again.
217d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar
218d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar        // item.mGraphicBuffer was populated with the proper graphic-buffer
219d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar        // at acquire even if it was previously acquired
220d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar        err = addReleaseFenceLocked(item.mBuf,
221d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar                item.mGraphicBuffer, item.mFence);
222d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
223d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        if (err != OK) {
224d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            BI_LOGE("Failed to add release fence to buffer "
225d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                    "(timestamp %lld, framenumber %lld",
226d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                    item.mTimestamp, item.mFrameNumber);
227d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            return err;
228d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
229d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
230d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        BI_LOGV("Attempting to release buffer timestamp %lld, frame %lld",
231d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                item.mTimestamp, item.mFrameNumber);
232d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
233d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar        // item.mGraphicBuffer was populated with the proper graphic-buffer
234d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar        // at acquire even if it was previously acquired
235d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar        err = releaseBufferLocked(item.mBuf, item.mGraphicBuffer,
236d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                                  EGL_NO_DISPLAY,
237d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                                  EGL_NO_SYNC_KHR);
238d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        if (err != OK) {
239d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            BI_LOGE("Failed to release buffer: %s (%d)",
240d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                    strerror(-err), err);
241d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            return err;
242d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
243d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
244d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        BI_LOGV("Buffer timestamp %lld, frame %lld evicted",
245d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                item.mTimestamp, item.mFrameNumber);
246d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
247d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        size_t currentSize = mBufferItemList.size();
248d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        mBufferItemList.erase(accIt);
249d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        assert(mBufferItemList.size() == currentSize - 1);
250d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    } else {
251d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        BI_LOGW("All buffers pinned, could not find any to release");
252d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        return NO_BUFFER_AVAILABLE;
253d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
254d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    }
255d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
256d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    return OK;
257d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin}
258d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
259d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkinvoid RingBufferConsumer::onFrameAvailable() {
260d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    status_t err;
261d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
262d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    {
263d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        Mutex::Autolock _l(mMutex);
264d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
265d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        /**
266d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin         * Release oldest frame
267d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin         */
268d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        if (mBufferItemList.size() >= (size_t)mBufferCount) {
269d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            err = releaseOldestBufferLocked(/*pinnedFrames*/NULL);
270d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            assert(err != NOT_ENOUGH_DATA);
271d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
272d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            // TODO: implement the case for NO_BUFFER_AVAILABLE
273d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            assert(err != NO_BUFFER_AVAILABLE);
274d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            if (err != OK) {
275d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                return;
276d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            }
277d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            // TODO: in unpinBuffer rerun this routine if we had buffers
278d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            // we could've locked but didn't because there was no space
279d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
280d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
281d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        RingBufferItem& item = *mBufferItemList.insert(mBufferItemList.end(),
282d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                                                       RingBufferItem());
283d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
284d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        /**
285d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin         * Acquire new frame
286d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin         */
287656e86250cd68f7f362c50a4bc92a865e9deacbeAndy McFadden        err = acquireBufferLocked(&item, 0);
288d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        if (err != OK) {
289d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            if (err != NO_BUFFER_AVAILABLE) {
290d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                BI_LOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
291d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            }
292d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
293d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            mBufferItemList.erase(--mBufferItemList.end());
294d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            return;
295d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
296d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
297d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        BI_LOGV("New buffer acquired (timestamp %lld), "
298d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                "buffer items %u out of %d",
299d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                item.mTimestamp,
300d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                mBufferItemList.size(), mBufferCount);
301d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
302d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        item.mGraphicBuffer = mSlots[item.mBuf].mGraphicBuffer;
303d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    } // end of mMutex lock
304d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
305d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    ConsumerBase::onFrameAvailable();
306d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin}
307d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
308d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkinvoid RingBufferConsumer::unpinBuffer(const BufferItem& item) {
309d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    Mutex::Autolock _l(mMutex);
310d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
311d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    List<RingBufferItem>::iterator it, end, accIt;
312d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
313d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    for (it = mBufferItemList.begin(), end = mBufferItemList.end();
314d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin         it != end;
315d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin         ++it) {
316d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
317d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        RingBufferItem& find = *it;
318d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        if (item.mGraphicBuffer == find.mGraphicBuffer) {
319d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar            status_t res = addReleaseFenceLocked(item.mBuf,
320d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar                    item.mGraphicBuffer, item.mFence);
321d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
322d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            if (res != OK) {
323d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                BI_LOGE("Failed to add release fence to buffer "
324d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                        "(timestamp %lld, framenumber %lld",
325d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                        item.mTimestamp, item.mFrameNumber);
326d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                return;
327d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            }
328d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
329d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            find.mPinCount--;
330d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            break;
331d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
332d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    }
333d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
334d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    if (it == end) {
335efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin        // This should never happen. If it happens, we have a bug.
336efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin        BI_LOGE("Failed to unpin buffer (timestamp %lld, framenumber %lld)",
337efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin                 item.mTimestamp, item.mFrameNumber);
338efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin    } else {
339efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin        BI_LOGV("Unpinned buffer (timestamp %lld, framenumber %lld)",
340d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                 item.mTimestamp, item.mFrameNumber);
341d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    }
342d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin}
343d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
344d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkinstatus_t RingBufferConsumer::setDefaultBufferSize(uint32_t w, uint32_t h) {
345d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    Mutex::Autolock _l(mMutex);
346deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian    return mConsumer->setDefaultBufferSize(w, h);
347d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin}
348d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
349d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkinstatus_t RingBufferConsumer::setDefaultBufferFormat(uint32_t defaultFormat) {
350d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    Mutex::Autolock _l(mMutex);
351deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian    return mConsumer->setDefaultBufferFormat(defaultFormat);
352d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin}
353d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
354d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkinstatus_t RingBufferConsumer::setConsumerUsage(uint32_t usage) {
355d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    Mutex::Autolock _l(mMutex);
356deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian    return mConsumer->setConsumerUsageBits(usage);
357d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin}
358d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
359d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin} // namespace android
360