• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
30 namespace android {
31 
CpuConsumer(uint32_t maxLockedBuffers)32 CpuConsumer::CpuConsumer(uint32_t maxLockedBuffers) :
33     ConsumerBase(new BufferQueue(true) ),
34     mMaxLockedBuffers(maxLockedBuffers),
35     mCurrentLockedBuffers(0)
36 {
37 
38     for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
39         mBufferPointers[i] = NULL;
40     }
41 
42     mBufferQueue->setSynchronousMode(true);
43     mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
44     mBufferQueue->setMaxAcquiredBufferCount(maxLockedBuffers);
45 }
46 
~CpuConsumer()47 CpuConsumer::~CpuConsumer() {
48 }
49 
setName(const String8 & name)50 void CpuConsumer::setName(const String8& name) {
51     Mutex::Autolock _l(mMutex);
52     mName = name;
53     mBufferQueue->setConsumerName(name);
54 }
55 
lockNextBuffer(LockedBuffer * nativeBuffer)56 status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) {
57     status_t err;
58 
59     if (!nativeBuffer) return BAD_VALUE;
60     if (mCurrentLockedBuffers == mMaxLockedBuffers) {
61         return INVALID_OPERATION;
62     }
63 
64     BufferQueue::BufferItem b;
65 
66     Mutex::Autolock _l(mMutex);
67 
68     err = acquireBufferLocked(&b);
69     if (err != OK) {
70         if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
71             return BAD_VALUE;
72         } else {
73             CC_LOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
74             return err;
75         }
76     }
77 
78     int buf = b.mBuf;
79 
80     if (b.mFence.get()) {
81         err = b.mFence->waitForever(1000, "CpuConsumer::lockNextBuffer");
82         if (err != OK) {
83             CC_LOGE("Failed to wait for fence of acquired buffer: %s (%d)",
84                     strerror(-err), err);
85             return err;
86         }
87     }
88 
89     err = mSlots[buf].mGraphicBuffer->lock(
90         GraphicBuffer::USAGE_SW_READ_OFTEN,
91         b.mCrop,
92         &mBufferPointers[buf]);
93 
94     if (mBufferPointers[buf] != NULL && err != OK) {
95         CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)", strerror(-err),
96                 err);
97         return err;
98     }
99 
100     nativeBuffer->data   = reinterpret_cast<uint8_t*>(mBufferPointers[buf]);
101     nativeBuffer->width  = mSlots[buf].mGraphicBuffer->getWidth();
102     nativeBuffer->height = mSlots[buf].mGraphicBuffer->getHeight();
103     nativeBuffer->format = mSlots[buf].mGraphicBuffer->getPixelFormat();
104     nativeBuffer->stride = mSlots[buf].mGraphicBuffer->getStride();
105 
106     nativeBuffer->crop        = b.mCrop;
107     nativeBuffer->transform   = b.mTransform;
108     nativeBuffer->scalingMode = b.mScalingMode;
109     nativeBuffer->timestamp   = b.mTimestamp;
110     nativeBuffer->frameNumber = b.mFrameNumber;
111 
112     mCurrentLockedBuffers++;
113 
114     return OK;
115 }
116 
unlockBuffer(const LockedBuffer & nativeBuffer)117 status_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) {
118     Mutex::Autolock _l(mMutex);
119     int slotIndex = 0;
120     status_t err;
121 
122     void *bufPtr = reinterpret_cast<void *>(nativeBuffer.data);
123     for (; slotIndex < BufferQueue::NUM_BUFFER_SLOTS; slotIndex++) {
124         if (bufPtr == mBufferPointers[slotIndex]) break;
125     }
126     if (slotIndex == BufferQueue::NUM_BUFFER_SLOTS) {
127         CC_LOGE("%s: Can't find buffer to free", __FUNCTION__);
128         return BAD_VALUE;
129     }
130 
131     mBufferPointers[slotIndex] = NULL;
132     err = mSlots[slotIndex].mGraphicBuffer->unlock();
133     if (err != OK) {
134         CC_LOGE("%s: Unable to unlock graphic buffer %d", __FUNCTION__, slotIndex);
135         return err;
136     }
137     releaseBufferLocked(slotIndex, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
138 
139     mCurrentLockedBuffers--;
140 
141     return OK;
142 }
143 
freeBufferLocked(int slotIndex)144 void CpuConsumer::freeBufferLocked(int slotIndex) {
145     if (mBufferPointers[slotIndex] != NULL) {
146         status_t err;
147         CC_LOGW("Buffer %d freed while locked by consumer", slotIndex);
148         mBufferPointers[slotIndex] = NULL;
149         err = mSlots[slotIndex].mGraphicBuffer->unlock();
150         if (err != OK) {
151             CC_LOGE("%s: Unable to unlock graphic buffer %d", __FUNCTION__,
152                     slotIndex);
153         }
154         mCurrentLockedBuffers--;
155     }
156     ConsumerBase::freeBufferLocked(slotIndex);
157 }
158 
159 } // namespace android
160