blob: bff55d1b048d89292297cfc63483470da627ff11 [file] [log] [blame]
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -07001/*
2 * Copyright (C) 2012 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 LOG_NDEBUG 0
18#define LOG_TAG "CpuConsumer"
19#define ATRACE_TAG ATRACE_TAG_GRAPHICS
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070020
Eino-Ville Talvala042ecee2013-02-28 18:23:24 -080021#include <cutils/compiler.h>
22#include <utils/Log.h>
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070023#include <gui/CpuConsumer.h>
24
25#define CC_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
26#define CC_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
27#define CC_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
28#define CC_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
29#define CC_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
30
31namespace android {
32
Mathias Agopiandb89edc2013-08-02 01:40:18 -070033CpuConsumer::CpuConsumer(const sp<IGraphicBufferConsumer>& bq,
Mathias Agopian595264f2013-07-16 22:56:09 -070034 uint32_t maxLockedBuffers, bool controlledByApp) :
35 ConsumerBase(bq, controlledByApp),
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070036 mMaxLockedBuffers(maxLockedBuffers),
37 mCurrentLockedBuffers(0)
38{
Eino-Ville Talvala042ecee2013-02-28 18:23:24 -080039 // Create tracking entries for locked buffers
40 mAcquiredBuffers.insertAt(0, maxLockedBuffers);
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070041
Mathias Agopiandb89edc2013-08-02 01:40:18 -070042 mConsumer->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
43 mConsumer->setMaxAcquiredBufferCount(maxLockedBuffers);
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070044}
45
Eino-Ville Talvalae232fdc2012-08-21 13:37:35 -070046CpuConsumer::~CpuConsumer() {
Eino-Ville Talvala042ecee2013-02-28 18:23:24 -080047 // ConsumerBase destructor does all the work.
Eino-Ville Talvalae232fdc2012-08-21 13:37:35 -070048}
49
Eino-Ville Talvala042ecee2013-02-28 18:23:24 -080050
51
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070052void CpuConsumer::setName(const String8& name) {
53 Mutex::Autolock _l(mMutex);
54 mName = name;
Mathias Agopiandb89edc2013-08-02 01:40:18 -070055 mConsumer->setConsumerName(name);
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070056}
57
Zhijun Heb4b63702013-06-06 11:59:21 -070058status_t CpuConsumer::setDefaultBufferSize(uint32_t width, uint32_t height)
59{
60 Mutex::Autolock _l(mMutex);
Mathias Agopiandb89edc2013-08-02 01:40:18 -070061 return mConsumer->setDefaultBufferSize(width, height);
Zhijun Heb4b63702013-06-06 11:59:21 -070062}
63
64status_t CpuConsumer::setDefaultBufferFormat(uint32_t defaultFormat)
65{
66 Mutex::Autolock _l(mMutex);
Mathias Agopiandb89edc2013-08-02 01:40:18 -070067 return mConsumer->setDefaultBufferFormat(defaultFormat);
Zhijun Heb4b63702013-06-06 11:59:21 -070068}
69
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070070status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) {
71 status_t err;
72
73 if (!nativeBuffer) return BAD_VALUE;
74 if (mCurrentLockedBuffers == mMaxLockedBuffers) {
Igor Murashkina5b75132013-08-14 18:49:12 -070075 CC_LOGW("Max buffers have been locked (%d), cannot lock anymore.",
76 mMaxLockedBuffers);
77 return NOT_ENOUGH_DATA;
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070078 }
79
80 BufferQueue::BufferItem b;
81
82 Mutex::Autolock _l(mMutex);
83
Andy McFadden1585c4d2013-06-28 13:52:40 -070084 err = acquireBufferLocked(&b, 0);
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070085 if (err != OK) {
86 if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
87 return BAD_VALUE;
88 } else {
89 CC_LOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
90 return err;
91 }
92 }
93
94 int buf = b.mBuf;
95
Jesse Hallb42b1ac2012-06-28 14:27:53 -070096 if (b.mFence.get()) {
Mathias Agopianea74d3b2013-05-16 18:03:22 -070097 err = b.mFence->waitForever("CpuConsumer::lockNextBuffer");
Jesse Hallb42b1ac2012-06-28 14:27:53 -070098 if (err != OK) {
99 CC_LOGE("Failed to wait for fence of acquired buffer: %s (%d)",
100 strerror(-err), err);
101 return err;
102 }
103 }
104
Eino-Ville Talvala64d8b192013-02-28 14:08:34 -0800105 void *bufferPointer = NULL;
Eino-Ville Talvalac43946b2013-05-04 18:07:43 -0700106 android_ycbcr ycbcr = android_ycbcr();
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700107
Eino-Ville Talvalac43946b2013-05-04 18:07:43 -0700108 if (mSlots[buf].mGraphicBuffer->getPixelFormat() ==
109 HAL_PIXEL_FORMAT_YCbCr_420_888) {
110 err = mSlots[buf].mGraphicBuffer->lockYCbCr(
111 GraphicBuffer::USAGE_SW_READ_OFTEN,
112 b.mCrop,
113 &ycbcr);
114
115 if (err != OK) {
116 CC_LOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)",
117 strerror(-err), err);
118 return err;
119 }
120 bufferPointer = ycbcr.y;
121 } else {
122 err = mSlots[buf].mGraphicBuffer->lock(
123 GraphicBuffer::USAGE_SW_READ_OFTEN,
124 b.mCrop,
125 &bufferPointer);
126
127 if (err != OK) {
128 CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)",
129 strerror(-err), err);
130 return err;
131 }
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700132 }
Eino-Ville Talvalac43946b2013-05-04 18:07:43 -0700133
Eino-Ville Talvala042ecee2013-02-28 18:23:24 -0800134 size_t lockedIdx = 0;
135 for (; lockedIdx < mMaxLockedBuffers; lockedIdx++) {
136 if (mAcquiredBuffers[lockedIdx].mSlot ==
137 BufferQueue::INVALID_BUFFER_SLOT) {
138 break;
139 }
140 }
141 assert(lockedIdx < mMaxLockedBuffers);
142
143 AcquiredBuffer &ab = mAcquiredBuffers.editItemAt(lockedIdx);
144 ab.mSlot = buf;
145 ab.mBufferPointer = bufferPointer;
146 ab.mGraphicBuffer = mSlots[buf].mGraphicBuffer;
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700147
Eino-Ville Talvala64d8b192013-02-28 14:08:34 -0800148 nativeBuffer->data =
149 reinterpret_cast<uint8_t*>(bufferPointer);
Eino-Ville Talvalaf57e7542012-08-20 15:44:40 -0700150 nativeBuffer->width = mSlots[buf].mGraphicBuffer->getWidth();
151 nativeBuffer->height = mSlots[buf].mGraphicBuffer->getHeight();
152 nativeBuffer->format = mSlots[buf].mGraphicBuffer->getPixelFormat();
Eino-Ville Talvalac43946b2013-05-04 18:07:43 -0700153 nativeBuffer->stride = (ycbcr.y != NULL) ?
154 ycbcr.ystride :
155 mSlots[buf].mGraphicBuffer->getStride();
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700156
157 nativeBuffer->crop = b.mCrop;
158 nativeBuffer->transform = b.mTransform;
159 nativeBuffer->scalingMode = b.mScalingMode;
160 nativeBuffer->timestamp = b.mTimestamp;
161 nativeBuffer->frameNumber = b.mFrameNumber;
162
Eino-Ville Talvalac43946b2013-05-04 18:07:43 -0700163 nativeBuffer->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb);
164 nativeBuffer->dataCr = reinterpret_cast<uint8_t*>(ycbcr.cr);
165 nativeBuffer->chromaStride = ycbcr.cstride;
166 nativeBuffer->chromaStep = ycbcr.chroma_step;
167
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700168 mCurrentLockedBuffers++;
169
170 return OK;
171}
172
173status_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) {
174 Mutex::Autolock _l(mMutex);
Eino-Ville Talvala042ecee2013-02-28 18:23:24 -0800175 size_t lockedIdx = 0;
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700176 status_t err;
177
178 void *bufPtr = reinterpret_cast<void *>(nativeBuffer.data);
Eino-Ville Talvala042ecee2013-02-28 18:23:24 -0800179 for (; lockedIdx < mMaxLockedBuffers; lockedIdx++) {
180 if (bufPtr == mAcquiredBuffers[lockedIdx].mBufferPointer) break;
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700181 }
Eino-Ville Talvala042ecee2013-02-28 18:23:24 -0800182 if (lockedIdx == mMaxLockedBuffers) {
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700183 CC_LOGE("%s: Can't find buffer to free", __FUNCTION__);
184 return BAD_VALUE;
185 }
186
Eino-Ville Talvala042ecee2013-02-28 18:23:24 -0800187 return releaseAcquiredBufferLocked(lockedIdx);
188}
189
190status_t CpuConsumer::releaseAcquiredBufferLocked(int lockedIdx) {
191 status_t err;
192
193 err = mAcquiredBuffers[lockedIdx].mGraphicBuffer->unlock();
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700194 if (err != OK) {
Eino-Ville Talvala042ecee2013-02-28 18:23:24 -0800195 CC_LOGE("%s: Unable to unlock graphic buffer %d", __FUNCTION__,
196 lockedIdx);
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700197 return err;
198 }
Eino-Ville Talvala042ecee2013-02-28 18:23:24 -0800199 int buf = mAcquiredBuffers[lockedIdx].mSlot;
200
201 // release the buffer if it hasn't already been freed by the BufferQueue.
202 // This can happen, for example, when the producer of this buffer
203 // disconnected after this buffer was acquired.
204 if (CC_LIKELY(mAcquiredBuffers[lockedIdx].mGraphicBuffer ==
205 mSlots[buf].mGraphicBuffer)) {
Lajos Molnarc5d7b7d2013-05-03 14:50:50 -0700206 releaseBufferLocked(
207 buf, mAcquiredBuffers[lockedIdx].mGraphicBuffer,
208 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
Eino-Ville Talvala042ecee2013-02-28 18:23:24 -0800209 }
210
211 AcquiredBuffer &ab = mAcquiredBuffers.editItemAt(lockedIdx);
212 ab.mSlot = BufferQueue::INVALID_BUFFER_SLOT;
213 ab.mBufferPointer = NULL;
214 ab.mGraphicBuffer.clear();
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700215
216 mCurrentLockedBuffers--;
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700217 return OK;
218}
219
Eino-Ville Talvalaf57e7542012-08-20 15:44:40 -0700220void CpuConsumer::freeBufferLocked(int slotIndex) {
Eino-Ville Talvalaf57e7542012-08-20 15:44:40 -0700221 ConsumerBase::freeBufferLocked(slotIndex);
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700222}
223
224} // namespace android