• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GrallocConsumer(Allocation * a,const sp<IGraphicBufferConsumer> & bq)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 
~GrallocConsumer()50 GrallocConsumer::~GrallocConsumer() {
51     // ConsumerBase destructor does all the work.
52 }
53 
54 
55 
lockNextBuffer()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.cb;
146         mAlloc->mHal.drvState.lod[2].mallocPtr = ycbcr.cr;
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 
unlockBuffer()159 status_t GrallocConsumer::unlockBuffer() {
160     Mutex::Autolock _l(mMutex);
161     return releaseAcquiredBufferLocked();
162 }
163 
releaseAcquiredBufferLocked()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