blob: 1ee6673558d4901b23deb49494786258d64dc4bd [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
20#include <utils/Log.h>
21
22#include <gui/CpuConsumer.h>
23
24#define CC_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
25#define CC_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
26#define CC_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
27#define CC_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
28#define CC_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
29
30namespace android {
31
Eino-Ville Talvalaeb0d1292013-02-28 11:01:32 -080032CpuConsumer::CpuConsumer(uint32_t maxLockedBuffers, bool synchronousMode) :
Jamie Gennis72f096f2012-08-27 18:48:37 -070033 ConsumerBase(new BufferQueue(true) ),
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070034 mMaxLockedBuffers(maxLockedBuffers),
35 mCurrentLockedBuffers(0)
36{
Eino-Ville Talvala64d8b192013-02-28 14:08:34 -080037 for (size_t i=0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
38 mLockedSlots[i].mBufferPointer = NULL;
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070039 }
40
Eino-Ville Talvalaeb0d1292013-02-28 11:01:32 -080041 mBufferQueue->setSynchronousMode(synchronousMode);
Eino-Ville Talvalaf57e7542012-08-20 15:44:40 -070042 mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
Jamie Gennis72f096f2012-08-27 18:48:37 -070043 mBufferQueue->setMaxAcquiredBufferCount(maxLockedBuffers);
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070044}
45
Eino-Ville Talvalae232fdc2012-08-21 13:37:35 -070046CpuConsumer::~CpuConsumer() {
Eino-Ville Talvala64d8b192013-02-28 14:08:34 -080047 status_t err;
48 for (size_t i=0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
49 if (mLockedSlots[i].mBufferPointer != NULL) {
50 mLockedSlots[i].mBufferPointer = NULL;
51 err = mLockedSlots[i].mGraphicBuffer->unlock();
52 mLockedSlots[i].mGraphicBuffer.clear();
53 if (err != OK) {
54 CC_LOGE("%s: Unable to unlock graphic buffer %d", __FUNCTION__,
55 i);
56 }
57
58 }
59 }
Eino-Ville Talvalae232fdc2012-08-21 13:37:35 -070060}
61
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070062void CpuConsumer::setName(const String8& name) {
63 Mutex::Autolock _l(mMutex);
64 mName = name;
65 mBufferQueue->setConsumerName(name);
66}
67
68status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) {
69 status_t err;
70
71 if (!nativeBuffer) return BAD_VALUE;
72 if (mCurrentLockedBuffers == mMaxLockedBuffers) {
73 return INVALID_OPERATION;
74 }
75
76 BufferQueue::BufferItem b;
77
78 Mutex::Autolock _l(mMutex);
79
Eino-Ville Talvalaf57e7542012-08-20 15:44:40 -070080 err = acquireBufferLocked(&b);
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -070081 if (err != OK) {
82 if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
83 return BAD_VALUE;
84 } else {
85 CC_LOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
86 return err;
87 }
88 }
89
90 int buf = b.mBuf;
91
Jesse Hallb42b1ac2012-06-28 14:27:53 -070092 if (b.mFence.get()) {
Jesse Hallba607d52012-10-01 14:05:20 -070093 err = b.mFence->waitForever(1000, "CpuConsumer::lockNextBuffer");
Jesse Hallb42b1ac2012-06-28 14:27:53 -070094 if (err != OK) {
95 CC_LOGE("Failed to wait for fence of acquired buffer: %s (%d)",
96 strerror(-err), err);
97 return err;
98 }
99 }
100
Eino-Ville Talvala64d8b192013-02-28 14:08:34 -0800101 void *bufferPointer = NULL;
Eino-Ville Talvalaf57e7542012-08-20 15:44:40 -0700102 err = mSlots[buf].mGraphicBuffer->lock(
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700103 GraphicBuffer::USAGE_SW_READ_OFTEN,
104 b.mCrop,
Eino-Ville Talvala64d8b192013-02-28 14:08:34 -0800105 &bufferPointer);
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700106
Eino-Ville Talvala64d8b192013-02-28 14:08:34 -0800107 if (bufferPointer != NULL && err != OK) {
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700108 CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)", strerror(-err),
109 err);
110 return err;
111 }
Eino-Ville Talvala64d8b192013-02-28 14:08:34 -0800112 mLockedSlots[buf].mBufferPointer = bufferPointer;
113 mLockedSlots[buf].mGraphicBuffer = mSlots[buf].mGraphicBuffer;
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700114
Eino-Ville Talvala64d8b192013-02-28 14:08:34 -0800115 nativeBuffer->data =
116 reinterpret_cast<uint8_t*>(bufferPointer);
Eino-Ville Talvalaf57e7542012-08-20 15:44:40 -0700117 nativeBuffer->width = mSlots[buf].mGraphicBuffer->getWidth();
118 nativeBuffer->height = mSlots[buf].mGraphicBuffer->getHeight();
119 nativeBuffer->format = mSlots[buf].mGraphicBuffer->getPixelFormat();
120 nativeBuffer->stride = mSlots[buf].mGraphicBuffer->getStride();
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700121
122 nativeBuffer->crop = b.mCrop;
123 nativeBuffer->transform = b.mTransform;
124 nativeBuffer->scalingMode = b.mScalingMode;
125 nativeBuffer->timestamp = b.mTimestamp;
126 nativeBuffer->frameNumber = b.mFrameNumber;
127
128 mCurrentLockedBuffers++;
129
130 return OK;
131}
132
133status_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) {
134 Mutex::Autolock _l(mMutex);
Eino-Ville Talvalaf57e7542012-08-20 15:44:40 -0700135 int slotIndex = 0;
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700136 status_t err;
137
138 void *bufPtr = reinterpret_cast<void *>(nativeBuffer.data);
Eino-Ville Talvalaf57e7542012-08-20 15:44:40 -0700139 for (; slotIndex < BufferQueue::NUM_BUFFER_SLOTS; slotIndex++) {
Eino-Ville Talvala64d8b192013-02-28 14:08:34 -0800140 if (bufPtr == mLockedSlots[slotIndex].mBufferPointer) break;
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700141 }
Eino-Ville Talvalaf57e7542012-08-20 15:44:40 -0700142 if (slotIndex == BufferQueue::NUM_BUFFER_SLOTS) {
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700143 CC_LOGE("%s: Can't find buffer to free", __FUNCTION__);
144 return BAD_VALUE;
145 }
146
Eino-Ville Talvala64d8b192013-02-28 14:08:34 -0800147 mLockedSlots[slotIndex].mBufferPointer = NULL;
148 err = mLockedSlots[slotIndex].mGraphicBuffer->unlock();
149 mLockedSlots[slotIndex].mGraphicBuffer.clear();
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700150 if (err != OK) {
Eino-Ville Talvalaf57e7542012-08-20 15:44:40 -0700151 CC_LOGE("%s: Unable to unlock graphic buffer %d", __FUNCTION__, slotIndex);
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700152 return err;
153 }
Jamie Gennisb2725412012-09-05 20:09:05 -0700154 releaseBufferLocked(slotIndex, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700155
156 mCurrentLockedBuffers--;
157
158 return OK;
159}
160
Eino-Ville Talvalaf57e7542012-08-20 15:44:40 -0700161void CpuConsumer::freeBufferLocked(int slotIndex) {
Eino-Ville Talvalaf57e7542012-08-20 15:44:40 -0700162 ConsumerBase::freeBufferLocked(slotIndex);
Eino-Ville Talvalae41b3182012-04-16 17:54:33 -0700163}
164
165} // namespace android