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