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