1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define ATRACE_TAG ATRACE_TAG_RS 18 19#include "rsContext.h" 20#include "rsAllocation.h" 21#include "rsAdapter.h" 22#include "rs_hal.h" 23 24#include <cutils/compiler.h> 25#include <utils/Log.h> 26#include "rsGrallocConsumer.h" 27#include <gui/BufferItem.h> 28#include <ui/GraphicBuffer.h> 29 30 31namespace android { 32namespace renderscript { 33 34GrallocConsumer::GrallocConsumer(Allocation *a, const sp<IGraphicBufferConsumer>& bq, int flags) : 35 ConsumerBase(bq, true) 36{ 37 mAlloc = a; 38 if (flags == 0) { 39 flags = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_RENDERSCRIPT; 40 } else { 41 flags |= GRALLOC_USAGE_RENDERSCRIPT; 42 } 43 mConsumer->setConsumerUsageBits(flags); 44 mConsumer->setMaxAcquiredBufferCount(2); 45 46 uint32_t y = a->mHal.drvState.lod[0].dimY; 47 if (y < 1) y = 1; 48 mConsumer->setDefaultBufferSize(a->mHal.drvState.lod[0].dimX, y); 49 50 if (a->mHal.state.yuv) { 51 bq->setDefaultBufferFormat(a->mHal.state.yuv); 52 } 53 //mBufferQueue->setConsumerName(name); 54} 55 56GrallocConsumer::~GrallocConsumer() { 57 // ConsumerBase destructor does all the work. 58} 59 60 61 62status_t GrallocConsumer::lockNextBuffer() { 63 Mutex::Autolock _l(mMutex); 64 status_t err; 65 66 if (mAcquiredBuffer.mSlot != BufferQueue::INVALID_BUFFER_SLOT) { 67 err = releaseAcquiredBufferLocked(); 68 if (err) { 69 return err; 70 } 71 } 72 73 BufferItem b; 74 75 err = acquireBufferLocked(&b, 0); 76 if (err != OK) { 77 if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 78 return BAD_VALUE; 79 } else { 80 ALOGE("Error acquiring buffer: %s (%d)", strerror(err), err); 81 return err; 82 } 83 } 84 85 int buf = b.mBuf; 86 87 if (b.mFence.get()) { 88 err = b.mFence->waitForever("GrallocConsumer::lockNextBuffer"); 89 if (err != OK) { 90 ALOGE("Failed to wait for fence of acquired buffer: %s (%d)", 91 strerror(-err), err); 92 return err; 93 } 94 } 95 96 void *bufferPointer = nullptr; 97 android_ycbcr ycbcr = android_ycbcr(); 98 99 if (mSlots[buf].mGraphicBuffer->getPixelFormat() == 100 HAL_PIXEL_FORMAT_YCbCr_420_888) { 101 err = mSlots[buf].mGraphicBuffer->lockYCbCr( 102 GraphicBuffer::USAGE_SW_READ_OFTEN, 103 b.mCrop, 104 &ycbcr); 105 106 if (err != OK) { 107 ALOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)", 108 strerror(-err), err); 109 return err; 110 } 111 bufferPointer = ycbcr.y; 112 } else { 113 err = mSlots[buf].mGraphicBuffer->lock( 114 GraphicBuffer::USAGE_SW_READ_OFTEN, 115 b.mCrop, 116 &bufferPointer); 117 118 if (err != OK) { 119 ALOGE("Unable to lock buffer for CPU reading: %s (%d)", 120 strerror(-err), err); 121 return err; 122 } 123 } 124 125 size_t lockedIdx = 0; 126 assert(mAcquiredBuffer.mSlot == BufferQueue::INVALID_BUFFER_SLOT); 127 128 mAcquiredBuffer.mSlot = buf; 129 mAcquiredBuffer.mBufferPointer = bufferPointer; 130 mAcquiredBuffer.mGraphicBuffer = mSlots[buf].mGraphicBuffer; 131 132 mAlloc->mHal.drvState.lod[0].mallocPtr = reinterpret_cast<uint8_t*>(bufferPointer); 133 mAlloc->mHal.drvState.lod[0].stride = mSlots[buf].mGraphicBuffer->getStride() * 134 mAlloc->mHal.state.type->getElementSizeBytes(); 135 mAlloc->mHal.state.nativeBuffer = mAcquiredBuffer.mGraphicBuffer->getNativeBuffer(); 136 mAlloc->mHal.state.timestamp = b.mTimestamp; 137 138 assert(mAlloc->mHal.drvState.lod[0].dimX == 139 mSlots[buf].mGraphicBuffer->getWidth()); 140 assert(mAlloc->mHal.drvState.lod[0].dimY == 141 mSlots[buf].mGraphicBuffer->getHeight()); 142 143 //mAlloc->format = mSlots[buf].mGraphicBuffer->getPixelFormat(); 144 145 //mAlloc->crop = b.mCrop; 146 //mAlloc->transform = b.mTransform; 147 //mAlloc->scalingMode = b.mScalingMode; 148 //mAlloc->frameNumber = b.mFrameNumber; 149 150 if (mAlloc->mHal.state.yuv == HAL_PIXEL_FORMAT_YCbCr_420_888) { 151 mAlloc->mHal.drvState.lod[1].mallocPtr = ycbcr.cb; 152 mAlloc->mHal.drvState.lod[2].mallocPtr = ycbcr.cr; 153 154 mAlloc->mHal.drvState.lod[0].stride = ycbcr.ystride; 155 mAlloc->mHal.drvState.lod[1].stride = ycbcr.cstride; 156 mAlloc->mHal.drvState.lod[2].stride = ycbcr.cstride; 157 158 mAlloc->mHal.drvState.yuv.shift = 1; 159 mAlloc->mHal.drvState.yuv.step = ycbcr.chroma_step; 160 } 161 162 return OK; 163} 164 165status_t GrallocConsumer::unlockBuffer() { 166 Mutex::Autolock _l(mMutex); 167 return releaseAcquiredBufferLocked(); 168} 169 170status_t GrallocConsumer::releaseAcquiredBufferLocked() { 171 status_t err; 172 173 err = mAcquiredBuffer.mGraphicBuffer->unlock(); 174 if (err != OK) { 175 ALOGE("%s: Unable to unlock graphic buffer", __FUNCTION__); 176 return err; 177 } 178 int buf = mAcquiredBuffer.mSlot; 179 180 // release the buffer if it hasn't already been freed by the BufferQueue. 181 // This can happen, for example, when the producer of this buffer 182 // disconnected after this buffer was acquired. 183 if (CC_LIKELY(mAcquiredBuffer.mGraphicBuffer == 184 mSlots[buf].mGraphicBuffer)) { 185 releaseBufferLocked( 186 buf, mAcquiredBuffer.mGraphicBuffer, 187 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); 188 } 189 190 mAcquiredBuffer.mSlot = BufferQueue::INVALID_BUFFER_SLOT; 191 mAcquiredBuffer.mBufferPointer = nullptr; 192 mAcquiredBuffer.mGraphicBuffer.clear(); 193 return OK; 194} 195 196} // namespace renderscript 197} // namespace android 198 199