Home | History | Annotate | Download | only in DisplayHardware
      1 /*
      2  **
      3  ** Copyright 2012 The Android Open Source Project
      4  **
      5  ** Licensed under the Apache License Version 2.0(the "License");
      6  ** you may not use this file except in compliance with the License.
      7  ** You may obtain a copy of the License at
      8  **
      9  **     http://www.apache.org/licenses/LICENSE-2.0
     10  **
     11  ** Unless required by applicable law or agreed to in writing software
     12  ** distributed under the License is distributed on an "AS IS" BASIS
     13  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
     14  ** See the License for the specific language governing permissions and
     15  ** limitations under the License.
     16  */
     17 
     18 #include <stdlib.h>
     19 #include <stdio.h>
     20 #include <string.h>
     21 #include <errno.h>
     22 
     23 #include <cutils/log.h>
     24 
     25 #include <utils/String8.h>
     26 
     27 #include <ui/Rect.h>
     28 
     29 #include <EGL/egl.h>
     30 
     31 #include <hardware/hardware.h>
     32 #include <gui/Surface.h>
     33 #include <gui/GraphicBufferAlloc.h>
     34 #include <ui/GraphicBuffer.h>
     35 
     36 #include "FramebufferSurface.h"
     37 #include "HWComposer.h"
     38 
     39 #ifndef NUM_FRAMEBUFFER_SURFACE_BUFFERS
     40 #define NUM_FRAMEBUFFER_SURFACE_BUFFERS (2)
     41 #endif
     42 
     43 // ----------------------------------------------------------------------------
     44 namespace android {
     45 // ----------------------------------------------------------------------------
     46 
     47 /*
     48  * This implements the (main) framebuffer management. This class is used
     49  * mostly by SurfaceFlinger, but also by command line GL application.
     50  *
     51  */
     52 
     53 FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp) :
     54     ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())),
     55     mDisplayType(disp),
     56     mCurrentBufferSlot(-1),
     57     mCurrentBuffer(0),
     58     mHwc(hwc)
     59 {
     60     mName = "FramebufferSurface";
     61     mBufferQueue->setConsumerName(mName);
     62     mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
     63                                        GRALLOC_USAGE_HW_RENDER |
     64                                        GRALLOC_USAGE_HW_COMPOSER);
     65     mBufferQueue->setDefaultBufferFormat(mHwc.getFormat(disp));
     66     mBufferQueue->setDefaultBufferSize(mHwc.getWidth(disp),  mHwc.getHeight(disp));
     67     mBufferQueue->setSynchronousMode(true);
     68     mBufferQueue->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
     69 }
     70 
     71 sp<IGraphicBufferProducer> FramebufferSurface::getIGraphicBufferProducer() const {
     72     return getBufferQueue();
     73 }
     74 
     75 status_t FramebufferSurface::advanceFrame() {
     76     // Once we remove FB HAL support, we can call nextBuffer() from here
     77     // instead of using onFrameAvailable(). No real benefit, except it'll be
     78     // more like VirtualDisplaySurface.
     79     return NO_ERROR;
     80 }
     81 
     82 status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) {
     83     Mutex::Autolock lock(mMutex);
     84 
     85     BufferQueue::BufferItem item;
     86     status_t err = acquireBufferLocked(&item);
     87     if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
     88         outBuffer = mCurrentBuffer;
     89         return NO_ERROR;
     90     } else if (err != NO_ERROR) {
     91         ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err);
     92         return err;
     93     }
     94 
     95     // If the BufferQueue has freed and reallocated a buffer in mCurrentSlot
     96     // then we may have acquired the slot we already own.  If we had released
     97     // our current buffer before we call acquireBuffer then that release call
     98     // would have returned STALE_BUFFER_SLOT, and we would have called
     99     // freeBufferLocked on that slot.  Because the buffer slot has already
    100     // been overwritten with the new buffer all we have to do is skip the
    101     // releaseBuffer call and we should be in the same state we'd be in if we
    102     // had released the old buffer first.
    103     if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT &&
    104         item.mBuf != mCurrentBufferSlot) {
    105         // Release the previous buffer.
    106         err = releaseBufferLocked(mCurrentBufferSlot, EGL_NO_DISPLAY,
    107                 EGL_NO_SYNC_KHR);
    108         if (err != NO_ERROR && err != BufferQueue::STALE_BUFFER_SLOT) {
    109             ALOGE("error releasing buffer: %s (%d)", strerror(-err), err);
    110             return err;
    111         }
    112     }
    113     mCurrentBufferSlot = item.mBuf;
    114     mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
    115     outFence = item.mFence;
    116     outBuffer = mCurrentBuffer;
    117     return NO_ERROR;
    118 }
    119 
    120 // Overrides ConsumerBase::onFrameAvailable(), does not call base class impl.
    121 void FramebufferSurface::onFrameAvailable() {
    122     sp<GraphicBuffer> buf;
    123     sp<Fence> acquireFence;
    124     status_t err = nextBuffer(buf, acquireFence);
    125     if (err != NO_ERROR) {
    126         ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)",
    127                 strerror(-err), err);
    128         return;
    129     }
    130     err = mHwc.fbPost(mDisplayType, acquireFence, buf);
    131     if (err != NO_ERROR) {
    132         ALOGE("error posting framebuffer: %d", err);
    133     }
    134 }
    135 
    136 void FramebufferSurface::freeBufferLocked(int slotIndex) {
    137     ConsumerBase::freeBufferLocked(slotIndex);
    138     if (slotIndex == mCurrentBufferSlot) {
    139         mCurrentBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
    140     }
    141 }
    142 
    143 void FramebufferSurface::onFrameCommitted() {
    144     sp<Fence> fence = mHwc.getAndResetReleaseFence(mDisplayType);
    145     if (fence->isValid() &&
    146             mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) {
    147         status_t err = addReleaseFence(mCurrentBufferSlot, fence);
    148         ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)",
    149                 strerror(-err), err);
    150     }
    151 }
    152 
    153 status_t FramebufferSurface::compositionComplete()
    154 {
    155     return mHwc.fbCompositionComplete();
    156 }
    157 
    158 // Since DisplaySurface and ConsumerBase both have a method with this
    159 // signature, results will vary based on the static pointer type the caller is
    160 // using:
    161 //   void dump(FrameBufferSurface* fbs, String8& s) {
    162 //       // calls FramebufferSurface::dump()
    163 //       fbs->dump(s);
    164 //
    165 //       // calls ConsumerBase::dump() since it is non-virtual
    166 //       static_cast<ConsumerBase*>(fbs)->dump(s);
    167 //
    168 //       // calls FramebufferSurface::dump() since it is virtual
    169 //       static_cast<DisplaySurface*>(fbs)->dump(s);
    170 //   }
    171 // To make sure that all of these end up doing the same thing, we just redirect
    172 // to ConsumerBase::dump() here. It will take the internal lock, and then call
    173 // virtual dumpLocked(), which is where the real work happens.
    174 void FramebufferSurface::dump(String8& result) const {
    175     ConsumerBase::dump(result);
    176 }
    177 
    178 void FramebufferSurface::dumpLocked(String8& result, const char* prefix,
    179             char* buffer, size_t SIZE) const
    180 {
    181     mHwc.fbDump(result);
    182     ConsumerBase::dumpLocked(result, prefix, buffer, SIZE);
    183 }
    184 
    185 // ----------------------------------------------------------------------------
    186 }; // namespace android
    187 // ----------------------------------------------------------------------------
    188