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