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