1e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala/*
2e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * Copyright (C) 2012 The Android Open Source Project
3e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala *
4e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
5e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * you may not use this file except in compliance with the License.
6e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * You may obtain a copy of the License at
7e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala *
8e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
9e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala *
10e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
11e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
12e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * See the License for the specific language governing permissions and
14e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * limitations under the License.
15e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala */
16e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
17e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala//#define LOG_NDEBUG 0
18e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala#define LOG_TAG "CpuConsumer"
19d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza//#define ATRACE_TAG ATRACE_TAG_GRAPHICS
20e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
21042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala#include <cutils/compiler.h>
22042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala#include <utils/Log.h>
23dd26416fe135f93ef2c8570738f8e1ca5e2ca3a3Dan Stoza#include <gui/BufferItem.h>
24e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala#include <gui/CpuConsumer.h>
25e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
26b3ca72ce1ea0d5e9ef1601dd35520f9fcf23cbcaLajos Molnar#define CC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
27d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza//#define CC_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
28d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza//#define CC_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
298b49125f10e3fd991c631e12856ce1ebf5a56d7eDan Albert#define CC_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
308b49125f10e3fd991c631e12856ce1ebf5a56d7eDan Albert#define CC_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
31e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
32e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalanamespace android {
33e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
34db89edc94bd2a78226b407f9f7261e202e7fa325Mathias AgopianCpuConsumer::CpuConsumer(const sp<IGraphicBufferConsumer>& bq,
35d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza        size_t maxLockedBuffers, bool controlledByApp) :
36595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian    ConsumerBase(bq, controlledByApp),
37e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    mMaxLockedBuffers(maxLockedBuffers),
38e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    mCurrentLockedBuffers(0)
39e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala{
40042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    // Create tracking entries for locked buffers
41042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    mAcquiredBuffers.insertAt(0, maxLockedBuffers);
42e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
43db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
44d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza    mConsumer->setMaxAcquiredBufferCount(static_cast<int32_t>(maxLockedBuffers));
45e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
46e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
47e232fdca2a62dc5e81b550f5be8710e36174e7a6Eino-Ville TalvalaCpuConsumer::~CpuConsumer() {
48042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    // ConsumerBase destructor does all the work.
49e232fdca2a62dc5e81b550f5be8710e36174e7a6Eino-Ville Talvala}
50e232fdca2a62dc5e81b550f5be8710e36174e7a6Eino-Ville Talvala
51042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala
52042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala
53e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalavoid CpuConsumer::setName(const String8& name) {
54e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    Mutex::Autolock _l(mMutex);
55e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    mName = name;
56db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian    mConsumer->setConsumerName(name);
57e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
58e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
596a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnarstatic bool isPossiblyYUV(PixelFormat format) {
60b3ca72ce1ea0d5e9ef1601dd35520f9fcf23cbcaLajos Molnar    switch (static_cast<int>(format)) {
616a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_RGBA_8888:
626a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_RGBX_8888:
636a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_RGB_888:
646a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_RGB_565:
656a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_BGRA_8888:
666a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_Y8:
676a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_Y16:
685b75a513e431c097ae704cba2f7affa6bfaecec9Eino-Ville Talvala        case HAL_PIXEL_FORMAT_RAW16:
696a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_RAW10:
706a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
716a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_BLOB:
726a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
736a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar            return false;
746a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar
756a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
766a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_YCbCr_420_888:
776a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
786a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
796a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        case HAL_PIXEL_FORMAT_YCbCr_422_I:
806a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        default:
816a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar            return true;
826a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar    }
836a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar}
846a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar
85e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalastatus_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) {
86e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    status_t err;
87e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
88e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    if (!nativeBuffer) return BAD_VALUE;
89e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    if (mCurrentLockedBuffers == mMaxLockedBuffers) {
90d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza        CC_LOGW("Max buffers have been locked (%zd), cannot lock anymore.",
91a5b7513711555c8681eb9391cfafe30fb7d6dd3dIgor Murashkin                mMaxLockedBuffers);
92a5b7513711555c8681eb9391cfafe30fb7d6dd3dIgor Murashkin        return NOT_ENOUGH_DATA;
93e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    }
94e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
95dd26416fe135f93ef2c8570738f8e1ca5e2ca3a3Dan Stoza    BufferItem b;
96e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
97e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    Mutex::Autolock _l(mMutex);
98e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
991585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden    err = acquireBufferLocked(&b, 0);
100e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    if (err != OK) {
101e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala        if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
102e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala            return BAD_VALUE;
103e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala        } else {
104e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala            CC_LOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
105e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala            return err;
106e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala        }
107e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    }
108e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
109e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    int buf = b.mBuf;
110e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
11164d8b1903e4b5f2838818eedcf4fef748b38709cEino-Ville Talvala    void *bufferPointer = NULL;
112c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala    android_ycbcr ycbcr = android_ycbcr();
113c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala
1146a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar    PixelFormat format = mSlots[buf].mGraphicBuffer->getPixelFormat();
1156a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar    PixelFormat flexFormat = format;
1166a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar    if (isPossiblyYUV(format)) {
1176a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        if (b.mFence.get()) {
118d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews            err = mSlots[buf].mGraphicBuffer->lockAsyncYCbCr(
119d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews                GraphicBuffer::USAGE_SW_READ_OFTEN,
120d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews                b.mCrop,
121d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews                &ycbcr,
122d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews                b.mFence->dup());
123d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews        } else {
1246a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar            err = mSlots[buf].mGraphicBuffer->lockYCbCr(
125d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews                GraphicBuffer::USAGE_SW_READ_OFTEN,
126d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews                b.mCrop,
1276a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar                &ycbcr);
1286a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        }
1296a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        if (err == OK) {
1306a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar            bufferPointer = ycbcr.y;
1316a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar            flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
1326a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar            if (format != HAL_PIXEL_FORMAT_YCbCr_420_888) {
1336a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar                CC_LOGV("locking buffer of format %#x as flex YUV", format);
134d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews            }
1356a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1366a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar            CC_LOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)",
1376a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar                    strerror(-err), err);
1386a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar            return err;
139c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala        }
1406a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar    }
1416a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar
1426a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar    if (bufferPointer == NULL) { // not flexible YUV
1436a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        if (b.mFence.get()) {
1446a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar            err = mSlots[buf].mGraphicBuffer->lockAsync(
145d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews                GraphicBuffer::USAGE_SW_READ_OFTEN,
146d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews                b.mCrop,
1476a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar                &bufferPointer,
1486a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar                b.mFence->dup());
149d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews        } else {
150d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews            err = mSlots[buf].mGraphicBuffer->lock(
151d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews                GraphicBuffer::USAGE_SW_READ_OFTEN,
152d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews                b.mCrop,
153d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews                &bufferPointer);
1546a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        }
1556a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar        if (err != OK) {
1566a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar            CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)",
1576a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar                    strerror(-err), err);
1586a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar            return err;
159c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala        }
160e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    }
161c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala
162042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    size_t lockedIdx = 0;
163d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza    for (; lockedIdx < static_cast<size_t>(mMaxLockedBuffers); lockedIdx++) {
164042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala        if (mAcquiredBuffers[lockedIdx].mSlot ==
165042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala                BufferQueue::INVALID_BUFFER_SLOT) {
166042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala            break;
167042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala        }
168042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    }
169042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    assert(lockedIdx < mMaxLockedBuffers);
170042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala
171042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    AcquiredBuffer &ab = mAcquiredBuffers.editItemAt(lockedIdx);
172042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    ab.mSlot = buf;
173042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    ab.mBufferPointer = bufferPointer;
174042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    ab.mGraphicBuffer = mSlots[buf].mGraphicBuffer;
175e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
17664d8b1903e4b5f2838818eedcf4fef748b38709cEino-Ville Talvala    nativeBuffer->data   =
17764d8b1903e4b5f2838818eedcf4fef748b38709cEino-Ville Talvala            reinterpret_cast<uint8_t*>(bufferPointer);
178f57e7540d4cf799f18fe87d3536c55f1e0064931Eino-Ville Talvala    nativeBuffer->width  = mSlots[buf].mGraphicBuffer->getWidth();
179f57e7540d4cf799f18fe87d3536c55f1e0064931Eino-Ville Talvala    nativeBuffer->height = mSlots[buf].mGraphicBuffer->getHeight();
1806a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar    nativeBuffer->format = format;
1816a26be7c2b1e5a84b5d2105780148016889285e6Lajos Molnar    nativeBuffer->flexFormat = flexFormat;
182c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala    nativeBuffer->stride = (ycbcr.y != NULL) ?
183d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza            static_cast<uint32_t>(ycbcr.ystride) :
184c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala            mSlots[buf].mGraphicBuffer->getStride();
185e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
186e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    nativeBuffer->crop        = b.mCrop;
187e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    nativeBuffer->transform   = b.mTransform;
188e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    nativeBuffer->scalingMode = b.mScalingMode;
189e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    nativeBuffer->timestamp   = b.mTimestamp;
1905b75a513e431c097ae704cba2f7affa6bfaecec9Eino-Ville Talvala    nativeBuffer->dataSpace   = b.mDataSpace;
191e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    nativeBuffer->frameNumber = b.mFrameNumber;
192e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
193c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala    nativeBuffer->dataCb       = reinterpret_cast<uint8_t*>(ycbcr.cb);
194c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala    nativeBuffer->dataCr       = reinterpret_cast<uint8_t*>(ycbcr.cr);
195d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza    nativeBuffer->chromaStride = static_cast<uint32_t>(ycbcr.cstride);
196d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza    nativeBuffer->chromaStep   = static_cast<uint32_t>(ycbcr.chroma_step);
197c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala
198e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    mCurrentLockedBuffers++;
199e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
200e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    return OK;
201e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
202e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
203e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalastatus_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) {
204e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    Mutex::Autolock _l(mMutex);
205042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    size_t lockedIdx = 0;
206e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
207e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    void *bufPtr = reinterpret_cast<void *>(nativeBuffer.data);
208d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza    for (; lockedIdx < static_cast<size_t>(mMaxLockedBuffers); lockedIdx++) {
209042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala        if (bufPtr == mAcquiredBuffers[lockedIdx].mBufferPointer) break;
210e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    }
211042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    if (lockedIdx == mMaxLockedBuffers) {
212e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala        CC_LOGE("%s: Can't find buffer to free", __FUNCTION__);
213e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala        return BAD_VALUE;
214e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    }
215e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
216042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    return releaseAcquiredBufferLocked(lockedIdx);
217042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala}
218042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala
219d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stozastatus_t CpuConsumer::releaseAcquiredBufferLocked(size_t lockedIdx) {
220042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    status_t err;
221d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews    int fd = -1;
222042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala
223d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews    err = mAcquiredBuffers[lockedIdx].mGraphicBuffer->unlockAsync(&fd);
224e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    if (err != OK) {
225d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza        CC_LOGE("%s: Unable to unlock graphic buffer %zd", __FUNCTION__,
226042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala                lockedIdx);
227e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala        return err;
228e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    }
229042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    int buf = mAcquiredBuffers[lockedIdx].mSlot;
230d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews    if (CC_LIKELY(fd != -1)) {
231d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews        sp<Fence> fence(new Fence(fd));
232d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews        addReleaseFenceLocked(
233d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews            mAcquiredBuffers[lockedIdx].mSlot,
234d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews            mSlots[buf].mGraphicBuffer,
235d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews            fence);
236d53e052322c658ce7c67b046caaeee4babc0a657Riley Andrews    }
237042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala
238042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    // release the buffer if it hasn't already been freed by the BufferQueue.
239042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    // This can happen, for example, when the producer of this buffer
240042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    // disconnected after this buffer was acquired.
241042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    if (CC_LIKELY(mAcquiredBuffers[lockedIdx].mGraphicBuffer ==
242042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala            mSlots[buf].mGraphicBuffer)) {
243c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar        releaseBufferLocked(
244c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar                buf, mAcquiredBuffers[lockedIdx].mGraphicBuffer,
245c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar                EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
246042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    }
247e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
248042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    AcquiredBuffer &ab = mAcquiredBuffers.editItemAt(lockedIdx);
249042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    ab.mSlot = BufferQueue::INVALID_BUFFER_SLOT;
250042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    ab.mBufferPointer = NULL;
251042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    ab.mGraphicBuffer.clear();
252e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
253042ecee2abf8584585f1f22f661ac6be9689edf4Eino-Ville Talvala    mCurrentLockedBuffers--;
254e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    return OK;
255e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
256e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
257f57e7540d4cf799f18fe87d3536c55f1e0064931Eino-Ville Talvalavoid CpuConsumer::freeBufferLocked(int slotIndex) {
258f57e7540d4cf799f18fe87d3536c55f1e0064931Eino-Ville Talvala    ConsumerBase::freeBufferLocked(slotIndex);
259e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
260e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
261e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala} // namespace android
262