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 "rsAdapter.h"
22ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#include "rs_hal.h"
23ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
24ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#include <cutils/compiler.h>
25ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#include <utils/Log.h>
26ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#include "rsGrallocConsumer.h"
27bdbb50169b7c3a31da2980fe9d1edb817b7d4bdaDan Stoza#include <gui/BufferItem.h>
28ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#include <ui/GraphicBuffer.h>
29ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
30ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
31ddceab9a001f07a3395226c5e06e3b420720af0fJason Samsnamespace android {
32ddceab9a001f07a3395226c5e06e3b420720af0fJason Samsnamespace renderscript {
33ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
341c19f05bd67126598ae51f1cf4ef5e906039299fJason SamsGrallocConsumer::GrallocConsumer(Allocation *a, const sp<IGraphicBufferConsumer>& bq, int flags) :
35ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    ConsumerBase(bq, true)
36ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams{
37ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mAlloc = a;
381c19f05bd67126598ae51f1cf4ef5e906039299fJason Sams    if (flags == 0) {
391c19f05bd67126598ae51f1cf4ef5e906039299fJason Sams        flags = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_RENDERSCRIPT;
401c19f05bd67126598ae51f1cf4ef5e906039299fJason Sams    } else {
411c19f05bd67126598ae51f1cf4ef5e906039299fJason Sams        flags |= GRALLOC_USAGE_RENDERSCRIPT;
421c19f05bd67126598ae51f1cf4ef5e906039299fJason Sams    }
431c19f05bd67126598ae51f1cf4ef5e906039299fJason Sams    mConsumer->setConsumerUsageBits(flags);
44ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mConsumer->setMaxAcquiredBufferCount(2);
45ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
46ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    uint32_t y = a->mHal.drvState.lod[0].dimY;
47ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (y < 1) y = 1;
48ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mConsumer->setDefaultBufferSize(a->mHal.drvState.lod[0].dimX, y);
49ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
5061656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    if (a->mHal.state.yuv) {
5161656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams        bq->setDefaultBufferFormat(a->mHal.state.yuv);
5261656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    }
53ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    //mBufferQueue->setConsumerName(name);
54ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams}
55ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
56ddceab9a001f07a3395226c5e06e3b420720af0fJason SamsGrallocConsumer::~GrallocConsumer() {
57ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    // ConsumerBase destructor does all the work.
58ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams}
59ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
60ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
61ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
62ddceab9a001f07a3395226c5e06e3b420720af0fJason Samsstatus_t GrallocConsumer::lockNextBuffer() {
63ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    Mutex::Autolock _l(mMutex);
64ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    status_t err;
65ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
66ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (mAcquiredBuffer.mSlot != BufferQueue::INVALID_BUFFER_SLOT) {
67ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        err = releaseAcquiredBufferLocked();
68ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        if (err) {
69ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            return err;
70ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        }
71ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
72ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
73bdbb50169b7c3a31da2980fe9d1edb817b7d4bdaDan Stoza    BufferItem b;
74ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
75ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    err = acquireBufferLocked(&b, 0);
76ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (err != OK) {
77ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
78ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            return BAD_VALUE;
79ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        } else {
80ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            ALOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
81ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            return err;
82ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        }
83ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
84ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
85ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    int buf = b.mBuf;
86ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
87ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (b.mFence.get()) {
88ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        err = b.mFence->waitForever("GrallocConsumer::lockNextBuffer");
89ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        if (err != OK) {
90ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            ALOGE("Failed to wait for fence of acquired buffer: %s (%d)",
91ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams                    strerror(-err), err);
92ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            return err;
93ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        }
94ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
95ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
9644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    void *bufferPointer = nullptr;
97ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    android_ycbcr ycbcr = android_ycbcr();
98ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
99ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (mSlots[buf].mGraphicBuffer->getPixelFormat() ==
100ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            HAL_PIXEL_FORMAT_YCbCr_420_888) {
101ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        err = mSlots[buf].mGraphicBuffer->lockYCbCr(
102ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            GraphicBuffer::USAGE_SW_READ_OFTEN,
103ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            b.mCrop,
104ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            &ycbcr);
105ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
106ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        if (err != OK) {
107ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            ALOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)",
108ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams                    strerror(-err), err);
109ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            return err;
110ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        }
111ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        bufferPointer = ycbcr.y;
112ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    } else {
113ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        err = mSlots[buf].mGraphicBuffer->lock(
114ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            GraphicBuffer::USAGE_SW_READ_OFTEN,
115ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            b.mCrop,
116ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            &bufferPointer);
117ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
118ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        if (err != OK) {
119ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            ALOGE("Unable to lock buffer for CPU reading: %s (%d)",
120ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams                    strerror(-err), err);
121ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            return err;
122ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        }
123ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
124ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
125ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    size_t lockedIdx = 0;
126ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    assert(mAcquiredBuffer.mSlot == BufferQueue::INVALID_BUFFER_SLOT);
127ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
128ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mAcquiredBuffer.mSlot = buf;
129ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mAcquiredBuffer.mBufferPointer = bufferPointer;
130ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mAcquiredBuffer.mGraphicBuffer = mSlots[buf].mGraphicBuffer;
131ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
132ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mAlloc->mHal.drvState.lod[0].mallocPtr = reinterpret_cast<uint8_t*>(bufferPointer);
133ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mAlloc->mHal.drvState.lod[0].stride = mSlots[buf].mGraphicBuffer->getStride() *
134ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            mAlloc->mHal.state.type->getElementSizeBytes();
135ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mAlloc->mHal.state.nativeBuffer = mAcquiredBuffer.mGraphicBuffer->getNativeBuffer();
136ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mAlloc->mHal.state.timestamp = b.mTimestamp;
137ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
138ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    assert(mAlloc->mHal.drvState.lod[0].dimX ==
139ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams           mSlots[buf].mGraphicBuffer->getWidth());
140ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    assert(mAlloc->mHal.drvState.lod[0].dimY ==
141ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams           mSlots[buf].mGraphicBuffer->getHeight());
142ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
143ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    //mAlloc->format = mSlots[buf].mGraphicBuffer->getPixelFormat();
144ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
145ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    //mAlloc->crop        = b.mCrop;
146ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    //mAlloc->transform   = b.mTransform;
147ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    //mAlloc->scalingMode = b.mScalingMode;
148ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    //mAlloc->frameNumber = b.mFrameNumber;
149ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
1507314cca8575544195e475ecc53d995311ac269c0Jason Sams    if (mAlloc->mHal.state.yuv == HAL_PIXEL_FORMAT_YCbCr_420_888) {
151c765a55556c597bd5e1f75072e8e3ce25cd836baJason Sams        mAlloc->mHal.drvState.lod[1].mallocPtr = ycbcr.cb;
152c765a55556c597bd5e1f75072e8e3ce25cd836baJason Sams        mAlloc->mHal.drvState.lod[2].mallocPtr = ycbcr.cr;
153ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
154ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        mAlloc->mHal.drvState.lod[0].stride = ycbcr.ystride;
155ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        mAlloc->mHal.drvState.lod[1].stride = ycbcr.cstride;
156ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        mAlloc->mHal.drvState.lod[2].stride = ycbcr.cstride;
15761656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams
15861656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams        mAlloc->mHal.drvState.yuv.shift = 1;
15961656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams        mAlloc->mHal.drvState.yuv.step = ycbcr.chroma_step;
160ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
161ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
162ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    return OK;
163ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams}
164ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
165ddceab9a001f07a3395226c5e06e3b420720af0fJason Samsstatus_t GrallocConsumer::unlockBuffer() {
166ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    Mutex::Autolock _l(mMutex);
167ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    return releaseAcquiredBufferLocked();
168ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams}
169ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
170ddceab9a001f07a3395226c5e06e3b420720af0fJason Samsstatus_t GrallocConsumer::releaseAcquiredBufferLocked() {
171ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    status_t err;
172ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
173ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    err = mAcquiredBuffer.mGraphicBuffer->unlock();
174ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (err != OK) {
175ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        ALOGE("%s: Unable to unlock graphic buffer", __FUNCTION__);
176ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        return err;
177ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
178ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    int buf = mAcquiredBuffer.mSlot;
179ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
180ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    // release the buffer if it hasn't already been freed by the BufferQueue.
181ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    // This can happen, for example, when the producer of this buffer
182ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    // disconnected after this buffer was acquired.
183ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (CC_LIKELY(mAcquiredBuffer.mGraphicBuffer ==
184ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            mSlots[buf].mGraphicBuffer)) {
185ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        releaseBufferLocked(
186ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams                buf, mAcquiredBuffer.mGraphicBuffer,
187ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams                EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
188ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
189ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
190ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mAcquiredBuffer.mSlot = BufferQueue::INVALID_BUFFER_SLOT;
19144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mAcquiredBuffer.mBufferPointer = nullptr;
192ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mAcquiredBuffer.mGraphicBuffer.clear();
193ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    return OK;
194ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams}
195ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
196ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams} // namespace renderscript
197ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams} // namespace android
198ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
199