1ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams/*
2ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams * Copyright (C) 2013 The Android Open Source Project
3ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams *
4ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams * you may not use this file except in compliance with the License.
6ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams * You may obtain a copy of the License at
7ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams *
8ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams *
10ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams * Unless required by applicable law or agreed to in writing, software
11ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams * See the License for the specific language governing permissions and
14ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams * limitations under the License.
15ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams */
16ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
17ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#define ATRACE_TAG ATRACE_TAG_RS
18ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
19ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#include "rsContext.h"
20ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#include "rsAllocation.h"
21ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#include "rs_hal.h"
22ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
23ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#include <cutils/compiler.h>
24ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#include <utils/Log.h>
25ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#include "rsGrallocConsumer.h"
268265914da27f43c8be973cd3882ed2d8e772a7c9Dan Stoza#include <gui/BufferItem.h>
27ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#include <ui/GraphicBuffer.h>
28ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
29ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
30ddceab9a001f07a3395226c5e06e3b420720af0fJason Samsnamespace android {
31ddceab9a001f07a3395226c5e06e3b420720af0fJason Samsnamespace renderscript {
32ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
33754746883bd46ec2fbdd23572cb6c90ab589346cMiao WangGrallocConsumer::GrallocConsumer(Allocation *a, const sp<IGraphicBufferConsumer>& bq, int flags, uint32_t numAlloc) :
34ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    ConsumerBase(bq, true)
35ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams{
36754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mAlloc = new Allocation *[numAlloc];
37754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mAcquiredBuffer = new AcquiredBuffer[numAlloc];
38754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    isIdxUsed = new bool[numAlloc];
39754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang
40754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mAlloc[0] = a;
41754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    isIdxUsed[0] = true;
42754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mNumAlloc = numAlloc;
431c19f05bd67126598ae51f1cf4ef5e906039299fJason Sams    if (flags == 0) {
441c19f05bd67126598ae51f1cf4ef5e906039299fJason Sams        flags = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_RENDERSCRIPT;
451c19f05bd67126598ae51f1cf4ef5e906039299fJason Sams    } else {
461c19f05bd67126598ae51f1cf4ef5e906039299fJason Sams        flags |= GRALLOC_USAGE_RENDERSCRIPT;
471c19f05bd67126598ae51f1cf4ef5e906039299fJason Sams    }
481c19f05bd67126598ae51f1cf4ef5e906039299fJason Sams    mConsumer->setConsumerUsageBits(flags);
49754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mConsumer->setMaxAcquiredBufferCount(numAlloc + 1);
50ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
51ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    uint32_t y = a->mHal.drvState.lod[0].dimY;
52ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (y < 1) y = 1;
53ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mConsumer->setDefaultBufferSize(a->mHal.drvState.lod[0].dimX, y);
54ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
5561656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    if (a->mHal.state.yuv) {
5661656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams        bq->setDefaultBufferFormat(a->mHal.state.yuv);
5761656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    }
58754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    for (uint32_t i = 1; i < numAlloc; i++) {
59754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        isIdxUsed[i] = false;
60754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    }
61ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    //mBufferQueue->setConsumerName(name);
62ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams}
63ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
64ddceab9a001f07a3395226c5e06e3b420720af0fJason SamsGrallocConsumer::~GrallocConsumer() {
65754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    delete[] mAlloc;
66754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    delete[] mAcquiredBuffer;
67754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    delete[] isIdxUsed;
68ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams}
69ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
70ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
71ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
72754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wangstatus_t GrallocConsumer::lockNextBuffer(uint32_t idx) {
73ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    Mutex::Autolock _l(mMutex);
74ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    status_t err;
75ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
76754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    if (idx >= mNumAlloc) {
77754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        ALOGE("Invalid buffer index: %d", idx);
78754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        return BAD_VALUE;
79754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    }
80754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang
81754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    if (mAcquiredBuffer[idx].mSlot != BufferQueue::INVALID_BUFFER_SLOT) {
82754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        err = releaseAcquiredBufferLocked(idx);
83ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        if (err) {
84ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            return err;
85ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        }
86ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
87ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
888265914da27f43c8be973cd3882ed2d8e772a7c9Dan Stoza    BufferItem b;
89ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
90ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    err = acquireBufferLocked(&b, 0);
91ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (err != OK) {
92ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
93ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            return BAD_VALUE;
94ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        } else {
95ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            ALOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
96ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            return err;
97ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        }
98ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
99ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
1005c1cd93b6639d0851a39aaa306323070de166716Pablo Ceballos    int slot = b.mSlot;
101ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
102ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (b.mFence.get()) {
103ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        err = b.mFence->waitForever("GrallocConsumer::lockNextBuffer");
104ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        if (err != OK) {
105ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            ALOGE("Failed to wait for fence of acquired buffer: %s (%d)",
106ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams                    strerror(-err), err);
107ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            return err;
108ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        }
109ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
110ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
11144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    void *bufferPointer = nullptr;
112ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    android_ycbcr ycbcr = android_ycbcr();
113ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
1145c1cd93b6639d0851a39aaa306323070de166716Pablo Ceballos    if (mSlots[slot].mGraphicBuffer->getPixelFormat() ==
115ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            HAL_PIXEL_FORMAT_YCbCr_420_888) {
1165c1cd93b6639d0851a39aaa306323070de166716Pablo Ceballos        err = mSlots[slot].mGraphicBuffer->lockYCbCr(
117ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            GraphicBuffer::USAGE_SW_READ_OFTEN,
118ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            b.mCrop,
119ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            &ycbcr);
120ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
121ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        if (err != OK) {
122ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            ALOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)",
123ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams                    strerror(-err), err);
124ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            return err;
125ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        }
126ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        bufferPointer = ycbcr.y;
127ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    } else {
1285c1cd93b6639d0851a39aaa306323070de166716Pablo Ceballos        err = mSlots[slot].mGraphicBuffer->lock(
129ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            GraphicBuffer::USAGE_SW_READ_OFTEN,
130ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            b.mCrop,
131ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            &bufferPointer);
132ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
133ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        if (err != OK) {
134ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            ALOGE("Unable to lock buffer for CPU reading: %s (%d)",
135ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams                    strerror(-err), err);
136ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            return err;
137ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        }
138ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
139ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
140ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    size_t lockedIdx = 0;
141754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    rsAssert(mAcquiredBuffer[idx].mSlot == BufferQueue::INVALID_BUFFER_SLOT);
142ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
143e13f0a615bbf96d211fad8326006003fac9957d3Miao Wang    mAcquiredBuffer[idx].mSlot = slot;
144754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mAcquiredBuffer[idx].mBufferPointer = bufferPointer;
145e13f0a615bbf96d211fad8326006003fac9957d3Miao Wang    mAcquiredBuffer[idx].mGraphicBuffer = mSlots[slot].mGraphicBuffer;
146ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
147754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mAlloc[idx]->mHal.drvState.lod[0].mallocPtr = reinterpret_cast<uint8_t*>(bufferPointer);
148e13f0a615bbf96d211fad8326006003fac9957d3Miao Wang    mAlloc[idx]->mHal.drvState.lod[0].stride = mSlots[slot].mGraphicBuffer->getStride() *
149754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang            mAlloc[idx]->mHal.state.type->getElementSizeBytes();
150754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mAlloc[idx]->mHal.state.nativeBuffer = mAcquiredBuffer[idx].mGraphicBuffer->getNativeBuffer();
151754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mAlloc[idx]->mHal.state.timestamp = b.mTimestamp;
152ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
153754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    rsAssert(mAlloc[idx]->mHal.drvState.lod[0].dimX ==
1545c1cd93b6639d0851a39aaa306323070de166716Pablo Ceballos             mSlots[slot].mGraphicBuffer->getWidth());
155754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    rsAssert(mAlloc[idx]->mHal.drvState.lod[0].dimY ==
1565c1cd93b6639d0851a39aaa306323070de166716Pablo Ceballos             mSlots[slot].mGraphicBuffer->getHeight());
157ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
158ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    //mAlloc->format = mSlots[buf].mGraphicBuffer->getPixelFormat();
159ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
160ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    //mAlloc->crop        = b.mCrop;
161ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    //mAlloc->transform   = b.mTransform;
162ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    //mAlloc->scalingMode = b.mScalingMode;
163ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    //mAlloc->frameNumber = b.mFrameNumber;
164ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
1653e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang    // For YUV Allocations, we need to populate the drvState with details of how
1663e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang    // the data is layed out.
1673e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang    // RenderScript requests a buffer in the YCbCr_420_888 format.
1683e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang    // The Camera HAL can return a buffer of YCbCr_420_888 or YV12, regardless
1693e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang    // of the requested format.
1703e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang    // mHal.state.yuv contains the requested format,
1713e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang    // mGraphicBuffer->getPixelFormat() is the returned format.
172754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    if (mAlloc[idx]->mHal.state.yuv == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1733e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang        const int yWidth = mAlloc[idx]->mHal.drvState.lod[0].dimX;
1743e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang        const int yHeight = mAlloc[idx]->mHal.drvState.lod[0].dimY;
1753e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang
1763e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang        if (mSlots[slot].mGraphicBuffer->getPixelFormat() ==
1773e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang                HAL_PIXEL_FORMAT_YCbCr_420_888) {
1783e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            const int cWidth = yWidth / 2;
1793e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            const int cHeight = yHeight / 2;
1803e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang
1813e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[1].dimX = cWidth;
1823e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[1].dimY = cHeight;
1833e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[2].dimX = cWidth;
1843e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[2].dimY = cHeight;
1853e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang
1863e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[0].mallocPtr = ycbcr.y;
1873e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[1].mallocPtr = ycbcr.cb;
1883e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[2].mallocPtr = ycbcr.cr;
1893e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang
1903e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[0].stride = ycbcr.ystride;
1913e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[1].stride = ycbcr.cstride;
1923e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[2].stride = ycbcr.cstride;
1933e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang
1943e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.yuv.shift = 1;
1953e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.yuv.step = ycbcr.chroma_step;
1963e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lodCount = 3;
1973e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang        } else if (mSlots[slot].mGraphicBuffer->getPixelFormat() ==
1983e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang                       HAL_PIXEL_FORMAT_YV12) {
1993e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            // For YV12, the data layout is Y, followed by Cr, followed by Cb;
2003e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            // for YCbCr_420_888, it's Y, followed by Cb, followed by Cr.
2013e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            // RenderScript assumes lod[0] is Y, lod[1] is Cb, and lod[2] is Cr.
2023e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            const int cWidth = yWidth / 2;
2033e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            const int cHeight = yHeight / 2;
2043e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang
2053e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[1].dimX = cWidth;
2063e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[1].dimY = cHeight;
2073e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[2].dimX = cWidth;
2083e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[2].dimY = cHeight;
2093e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang
2103e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            size_t yStride = rsRound(yWidth *
2113e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang                 mAlloc[idx]->mHal.state.type->getElementSizeBytes(), 16);
2123e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            size_t cStride = rsRound(yStride >> 1, 16);
2133e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang
2143e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            uint8_t *yPtr = (uint8_t *)mAlloc[idx]->mHal.drvState.lod[0].mallocPtr;
2153e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            uint8_t *crPtr = yPtr + yStride * yHeight;
2163e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            uint8_t *cbPtr = crPtr + cStride * cHeight;
2173e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang
2183e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[1].mallocPtr = cbPtr;
2193e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[2].mallocPtr = crPtr;
2203e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang
2213e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[0].stride = yStride;
2223e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[1].stride = cStride;
2233e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lod[2].stride = cStride;
2243e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang
2253e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.yuv.shift = 1;
2263e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.yuv.step = 1;
2273e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            mAlloc[idx]->mHal.drvState.lodCount = 3;
2283e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang        } else {
2293e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang            ALOGD("Unrecognized format: %d",
2303e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang               mSlots[slot].mGraphicBuffer->getPixelFormat());
2313e02db8681f8adb34c9ee54be28de8c68ed9a59bMiao Wang        }
232ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
233ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
234ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    return OK;
235ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams}
236ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
237754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wangstatus_t GrallocConsumer::unlockBuffer(uint32_t idx) {
238ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    Mutex::Autolock _l(mMutex);
239754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    return releaseAcquiredBufferLocked(idx);
240ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams}
241ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
242754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wangstatus_t GrallocConsumer::releaseAcquiredBufferLocked(uint32_t idx) {
243ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    status_t err;
244ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
245754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    if (idx >= mNumAlloc) {
246754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        ALOGE("Invalid buffer index: %d", idx);
247754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        return BAD_VALUE;
248754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    }
249754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    if (mAcquiredBuffer[idx].mGraphicBuffer == nullptr) {
250754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang       return OK;
251754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    }
252754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang
253754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    err = mAcquiredBuffer[idx].mGraphicBuffer->unlock();
254ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (err != OK) {
255ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        ALOGE("%s: Unable to unlock graphic buffer", __FUNCTION__);
256ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        return err;
257ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
258754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    int buf = mAcquiredBuffer[idx].mSlot;
259ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
260ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    // release the buffer if it hasn't already been freed by the BufferQueue.
261ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    // This can happen, for example, when the producer of this buffer
262ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    // disconnected after this buffer was acquired.
263754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    if (CC_LIKELY(mAcquiredBuffer[idx].mGraphicBuffer ==
264ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            mSlots[buf].mGraphicBuffer)) {
265ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        releaseBufferLocked(
266754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang                buf, mAcquiredBuffer[idx].mGraphicBuffer,
267ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams                EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
268ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
269ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
270754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mAcquiredBuffer[idx].mSlot = BufferQueue::INVALID_BUFFER_SLOT;
271754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mAcquiredBuffer[idx].mBufferPointer = nullptr;
272754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mAcquiredBuffer[idx].mGraphicBuffer.clear();
273ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    return OK;
274ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams}
275ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
276754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wanguint32_t GrallocConsumer::getNextAvailableIdx(Allocation *a) {
277754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    for (uint32_t i = 0; i < mNumAlloc; i++) {
278754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        if (isIdxUsed[i] == false) {
279754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang            mAlloc[i] = a;
280754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang            isIdxUsed[i] = true;
281754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang            return i;
282754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        }
283754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    }
284754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    return mNumAlloc;
285754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang}
286754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang
287754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wangbool GrallocConsumer::releaseIdx(uint32_t idx) {
288754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    if (idx >= mNumAlloc) {
289754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        ALOGE("Invalid buffer index: %d", idx);
290754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        return false;
291754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    }
292754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    if (isIdxUsed[idx] == false) {
293754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        ALOGV("Buffer index already released: %d", idx);
294754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        return true;
295754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    }
296754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    status_t err;
297754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    err = unlockBuffer(idx);
298754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    if (err != OK) {
299754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        ALOGE("Unable to unlock graphic buffer");
300754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        return false;
301754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    }
302754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mAlloc[idx] = nullptr;
303754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    isIdxUsed[idx] = false;
304754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    return true;
305754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang}
306754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang
307ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams} // namespace renderscript
308ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams} // namespace android
309