Home | History | Annotate | Download | only in gui
      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 
     21 #include <cutils/compiler.h>
     22 #include <utils/Log.h>
     23 #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 
     31 namespace android {
     32 
     33 CpuConsumer::CpuConsumer(const sp<IGraphicBufferConsumer>& bq,
     34         uint32_t maxLockedBuffers, bool controlledByApp) :
     35     ConsumerBase(bq, controlledByApp),
     36     mMaxLockedBuffers(maxLockedBuffers),
     37     mCurrentLockedBuffers(0)
     38 {
     39     // Create tracking entries for locked buffers
     40     mAcquiredBuffers.insertAt(0, maxLockedBuffers);
     41 
     42     mConsumer->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
     43     mConsumer->setMaxAcquiredBufferCount(maxLockedBuffers);
     44 }
     45 
     46 CpuConsumer::~CpuConsumer() {
     47     // ConsumerBase destructor does all the work.
     48 }
     49 
     50 
     51 
     52 void CpuConsumer::setName(const String8& name) {
     53     Mutex::Autolock _l(mMutex);
     54     mName = name;
     55     mConsumer->setConsumerName(name);
     56 }
     57 
     58 status_t CpuConsumer::setDefaultBufferSize(uint32_t width, uint32_t height)
     59 {
     60     Mutex::Autolock _l(mMutex);
     61     return mConsumer->setDefaultBufferSize(width, height);
     62 }
     63 
     64 status_t CpuConsumer::setDefaultBufferFormat(uint32_t defaultFormat)
     65 {
     66     Mutex::Autolock _l(mMutex);
     67     return mConsumer->setDefaultBufferFormat(defaultFormat);
     68 }
     69 
     70 status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) {
     71     status_t err;
     72 
     73     if (!nativeBuffer) return BAD_VALUE;
     74     if (mCurrentLockedBuffers == mMaxLockedBuffers) {
     75         CC_LOGW("Max buffers have been locked (%d), cannot lock anymore.",
     76                 mMaxLockedBuffers);
     77         return NOT_ENOUGH_DATA;
     78     }
     79 
     80     BufferQueue::BufferItem b;
     81 
     82     Mutex::Autolock _l(mMutex);
     83 
     84     err = acquireBufferLocked(&b, 0);
     85     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 
     96     void *bufferPointer = NULL;
     97     android_ycbcr ycbcr = android_ycbcr();
     98 
     99     if (b.mFence.get()) {
    100         if (mSlots[buf].mGraphicBuffer->getPixelFormat() ==
    101                 HAL_PIXEL_FORMAT_YCbCr_420_888) {
    102             err = mSlots[buf].mGraphicBuffer->lockAsyncYCbCr(
    103                 GraphicBuffer::USAGE_SW_READ_OFTEN,
    104                 b.mCrop,
    105                 &ycbcr,
    106                 b.mFence->dup());
    107 
    108             if (err != OK) {
    109                 CC_LOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)",
    110                         strerror(-err), err);
    111                 return err;
    112             }
    113             bufferPointer = ycbcr.y;
    114         } else {
    115             err = mSlots[buf].mGraphicBuffer->lockAsync(
    116                 GraphicBuffer::USAGE_SW_READ_OFTEN,
    117                 b.mCrop,
    118                 &bufferPointer,
    119                 b.mFence->dup());
    120 
    121             if (err != OK) {
    122                 CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)",
    123                         strerror(-err), err);
    124                 return err;
    125             }
    126         }
    127     } else {
    128         if (mSlots[buf].mGraphicBuffer->getPixelFormat() ==
    129                 HAL_PIXEL_FORMAT_YCbCr_420_888) {
    130             err = mSlots[buf].mGraphicBuffer->lockYCbCr(
    131                 GraphicBuffer::USAGE_SW_READ_OFTEN,
    132                 b.mCrop,
    133                 &ycbcr);
    134 
    135             if (err != OK) {
    136                 CC_LOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)",
    137                         strerror(-err), err);
    138                 return err;
    139             }
    140             bufferPointer = ycbcr.y;
    141         } else {
    142             err = mSlots[buf].mGraphicBuffer->lock(
    143                 GraphicBuffer::USAGE_SW_READ_OFTEN,
    144                 b.mCrop,
    145                 &bufferPointer);
    146 
    147             if (err != OK) {
    148                 CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)",
    149                         strerror(-err), err);
    150                 return err;
    151             }
    152         }
    153     }
    154 
    155     size_t lockedIdx = 0;
    156     for (; lockedIdx < mMaxLockedBuffers; lockedIdx++) {
    157         if (mAcquiredBuffers[lockedIdx].mSlot ==
    158                 BufferQueue::INVALID_BUFFER_SLOT) {
    159             break;
    160         }
    161     }
    162     assert(lockedIdx < mMaxLockedBuffers);
    163 
    164     AcquiredBuffer &ab = mAcquiredBuffers.editItemAt(lockedIdx);
    165     ab.mSlot = buf;
    166     ab.mBufferPointer = bufferPointer;
    167     ab.mGraphicBuffer = mSlots[buf].mGraphicBuffer;
    168 
    169     nativeBuffer->data   =
    170             reinterpret_cast<uint8_t*>(bufferPointer);
    171     nativeBuffer->width  = mSlots[buf].mGraphicBuffer->getWidth();
    172     nativeBuffer->height = mSlots[buf].mGraphicBuffer->getHeight();
    173     nativeBuffer->format = mSlots[buf].mGraphicBuffer->getPixelFormat();
    174     nativeBuffer->stride = (ycbcr.y != NULL) ?
    175             ycbcr.ystride :
    176             mSlots[buf].mGraphicBuffer->getStride();
    177 
    178     nativeBuffer->crop        = b.mCrop;
    179     nativeBuffer->transform   = b.mTransform;
    180     nativeBuffer->scalingMode = b.mScalingMode;
    181     nativeBuffer->timestamp   = b.mTimestamp;
    182     nativeBuffer->frameNumber = b.mFrameNumber;
    183 
    184     nativeBuffer->dataCb       = reinterpret_cast<uint8_t*>(ycbcr.cb);
    185     nativeBuffer->dataCr       = reinterpret_cast<uint8_t*>(ycbcr.cr);
    186     nativeBuffer->chromaStride = ycbcr.cstride;
    187     nativeBuffer->chromaStep   = ycbcr.chroma_step;
    188 
    189     mCurrentLockedBuffers++;
    190 
    191     return OK;
    192 }
    193 
    194 status_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) {
    195     Mutex::Autolock _l(mMutex);
    196     size_t lockedIdx = 0;
    197     status_t err;
    198 
    199     void *bufPtr = reinterpret_cast<void *>(nativeBuffer.data);
    200     for (; lockedIdx < mMaxLockedBuffers; lockedIdx++) {
    201         if (bufPtr == mAcquiredBuffers[lockedIdx].mBufferPointer) break;
    202     }
    203     if (lockedIdx == mMaxLockedBuffers) {
    204         CC_LOGE("%s: Can't find buffer to free", __FUNCTION__);
    205         return BAD_VALUE;
    206     }
    207 
    208     return releaseAcquiredBufferLocked(lockedIdx);
    209 }
    210 
    211 status_t CpuConsumer::releaseAcquiredBufferLocked(int lockedIdx) {
    212     status_t err;
    213     int fd = -1;
    214 
    215     err = mAcquiredBuffers[lockedIdx].mGraphicBuffer->unlockAsync(&fd);
    216     if (err != OK) {
    217         CC_LOGE("%s: Unable to unlock graphic buffer %d", __FUNCTION__,
    218                 lockedIdx);
    219         return err;
    220     }
    221     int buf = mAcquiredBuffers[lockedIdx].mSlot;
    222     if (CC_LIKELY(fd != -1)) {
    223         sp<Fence> fence(new Fence(fd));
    224         addReleaseFenceLocked(
    225             mAcquiredBuffers[lockedIdx].mSlot,
    226             mSlots[buf].mGraphicBuffer,
    227             fence);
    228     }
    229 
    230     // release the buffer if it hasn't already been freed by the BufferQueue.
    231     // This can happen, for example, when the producer of this buffer
    232     // disconnected after this buffer was acquired.
    233     if (CC_LIKELY(mAcquiredBuffers[lockedIdx].mGraphicBuffer ==
    234             mSlots[buf].mGraphicBuffer)) {
    235         releaseBufferLocked(
    236                 buf, mAcquiredBuffers[lockedIdx].mGraphicBuffer,
    237                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
    238     }
    239 
    240     AcquiredBuffer &ab = mAcquiredBuffers.editItemAt(lockedIdx);
    241     ab.mSlot = BufferQueue::INVALID_BUFFER_SLOT;
    242     ab.mBufferPointer = NULL;
    243     ab.mGraphicBuffer.clear();
    244 
    245     mCurrentLockedBuffers--;
    246     return OK;
    247 }
    248 
    249 void CpuConsumer::freeBufferLocked(int slotIndex) {
    250     ConsumerBase::freeBufferLocked(slotIndex);
    251 }
    252 
    253 } // namespace android
    254