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