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