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