1cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/*
2cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Copyright (C) 2012 The Android Open Source Project
3cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *
4cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * you may not use this file except in compliance with the License.
6cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * You may obtain a copy of the License at
7cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *
8cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *
10cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
11cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * See the License for the specific language governing permissions and
14cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * limitations under the License.
15cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */
16cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
17cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn//#define LOG_NDEBUG 0
18cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn#define LOG_TAG "CpuConsumer"
19cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn#define ATRACE_TAG ATRACE_TAG_GRAPHICS
20cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn#include <utils/Log.h>
21cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
22cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn#include <gui/CpuConsumer.h>
23cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
24cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn#define CC_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
25cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn#define CC_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
26cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn#define CC_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
27cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn#define CC_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
28cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn#define CC_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
29cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
30cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornnamespace android {
31cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
32cba2e2c881e8e16ea5025b564c94320174d65f01Dianne HackbornCpuConsumer::CpuConsumer(uint32_t maxLockedBuffers) :
33cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    ConsumerBase(new BufferQueue(true) ),
34cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    mMaxLockedBuffers(maxLockedBuffers),
35cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    mCurrentLockedBuffers(0)
36cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn{
37cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
38cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
39cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBufferPointers[i] = NULL;
40cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
41cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
42cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    mBufferQueue->setSynchronousMode(true);
43cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
44cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    mBufferQueue->setMaxAcquiredBufferCount(maxLockedBuffers);
45cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn}
46cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
47cba2e2c881e8e16ea5025b564c94320174d65f01Dianne HackbornCpuConsumer::~CpuConsumer() {
48cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn}
49cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
50cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornvoid CpuConsumer::setName(const String8& name) {
51cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    Mutex::Autolock _l(mMutex);
52cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    mName = name;
53cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    mBufferQueue->setConsumerName(name);
54cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn}
55cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
56cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornstatus_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) {
57cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    status_t err;
58cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
59cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    if (!nativeBuffer) return BAD_VALUE;
60cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    if (mCurrentLockedBuffers == mMaxLockedBuffers) {
61cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return INVALID_OPERATION;
62cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
63cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
64cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    BufferQueue::BufferItem b;
65cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
66cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    Mutex::Autolock _l(mMutex);
67cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
68cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    err = acquireBufferLocked(&b);
69cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    if (err != OK) {
70cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
71cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return BAD_VALUE;
72cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        } else {
73cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            CC_LOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
74cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return err;
75cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
76cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
77cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
78cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    int buf = b.mBuf;
79cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
80cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    if (b.mFence.get()) {
81cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        err = b.mFence->waitForever(1000, "CpuConsumer::lockNextBuffer");
82cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (err != OK) {
83cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            CC_LOGE("Failed to wait for fence of acquired buffer: %s (%d)",
84cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    strerror(-err), err);
85cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return err;
86cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
87cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
88cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
89cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    err = mSlots[buf].mGraphicBuffer->lock(
90cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        GraphicBuffer::USAGE_SW_READ_OFTEN,
91cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        b.mCrop,
92cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        &mBufferPointers[buf]);
93cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
94cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    if (mBufferPointers[buf] != NULL && err != OK) {
95cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)", strerror(-err),
96cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                err);
97cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return err;
98cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
99cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
100cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    nativeBuffer->data   = reinterpret_cast<uint8_t*>(mBufferPointers[buf]);
101cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    nativeBuffer->width  = mSlots[buf].mGraphicBuffer->getWidth();
102cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    nativeBuffer->height = mSlots[buf].mGraphicBuffer->getHeight();
103cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    nativeBuffer->format = mSlots[buf].mGraphicBuffer->getPixelFormat();
104cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    nativeBuffer->stride = mSlots[buf].mGraphicBuffer->getStride();
105cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
106cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    nativeBuffer->crop        = b.mCrop;
107cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    nativeBuffer->transform   = b.mTransform;
108cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    nativeBuffer->scalingMode = b.mScalingMode;
109cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    nativeBuffer->timestamp   = b.mTimestamp;
110cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    nativeBuffer->frameNumber = b.mFrameNumber;
111cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
112cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    mCurrentLockedBuffers++;
113cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
114cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    return OK;
115cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn}
116cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
117cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornstatus_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) {
118cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    Mutex::Autolock _l(mMutex);
119cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    int slotIndex = 0;
120cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    status_t err;
121cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
122cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    void *bufPtr = reinterpret_cast<void *>(nativeBuffer.data);
123cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    for (; slotIndex < BufferQueue::NUM_BUFFER_SLOTS; slotIndex++) {
124cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (bufPtr == mBufferPointers[slotIndex]) break;
125cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
126cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    if (slotIndex == BufferQueue::NUM_BUFFER_SLOTS) {
127cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        CC_LOGE("%s: Can't find buffer to free", __FUNCTION__);
128cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return BAD_VALUE;
129cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
130cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
131cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    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
144void 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