widget/gonk/libdisplay/FramebufferSurface.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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  */
    18 #include <stdlib.h>
    19 #include <stdio.h>
    20 #include <string.h>
    21 #include <errno.h>
    23 #include <cutils/log.h>
    25 #include <utils/String8.h>
    27 #include <ui/Rect.h>
    29 #include <EGL/egl.h>
    31 #include <hardware/hardware.h>
    32 #if ANDROID_VERSION == 17
    33 #include <gui/SurfaceTextureClient.h>
    34 #endif
    35 #include <ui/GraphicBuffer.h>
    37 #include "FramebufferSurface.h"
    38 #include "GraphicBufferAlloc.h"
    40 #ifndef NUM_FRAMEBUFFER_SURFACE_BUFFERS
    41 #define NUM_FRAMEBUFFER_SURFACE_BUFFERS (2)
    42 #endif
    44 // ----------------------------------------------------------------------------
    45 namespace android {
    46 // ----------------------------------------------------------------------------
    48 /*
    49  * This implements the (main) framebuffer management. This class
    50  * was adapted from the version in SurfaceFlinger
    51  */
    52 FramebufferSurface::FramebufferSurface(int disp, uint32_t width, uint32_t height, uint32_t format,
    53         sp<BufferQueue>& bq) :
    54 #if ANDROID_VERSION >= 19
    55     ConsumerBase(bq, true),
    56 #else
    57     ConsumerBase(bq),
    58 #endif
    59     mDisplayType(disp),
    60     mCurrentBufferSlot(-1),
    61     mCurrentBuffer(0),
    62     lastHandle(0)
    63 {
    64     mName = "FramebufferSurface";
    66 #if ANDROID_VERSION >= 19
    67     sp<IGraphicBufferConsumer> consumer = mConsumer;
    68 #else
    69     sp<BufferQueue> consumer = mBufferQueue;
    70     consumer->setSynchronousMode(true);
    71 #endif
    72     consumer->setConsumerName(mName);
    73     consumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
    74                                    GRALLOC_USAGE_HW_RENDER |
    75                                    GRALLOC_USAGE_HW_COMPOSER);
    76     consumer->setDefaultBufferFormat(format);
    77     consumer->setDefaultBufferSize(width, height);
    78     consumer->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
    79 }
    81 status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) {
    82     Mutex::Autolock lock(mMutex);
    84     BufferQueue::BufferItem item;
    85 #if ANDROID_VERSION >= 19
    86     status_t err = acquireBufferLocked(&item, 0);
    87 #else
    88     status_t err = acquireBufferLocked(&item);
    89 #endif
    90     if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
    91         outBuffer = mCurrentBuffer;
    92         return NO_ERROR;
    93     } else if (err != NO_ERROR) {
    94         ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err);
    95         return err;
    96     }
    98     // If the BufferQueue has freed and reallocated a buffer in mCurrentSlot
    99     // then we may have acquired the slot we already own.  If we had released
   100     // our current buffer before we call acquireBuffer then that release call
   101     // would have returned STALE_BUFFER_SLOT, and we would have called
   102     // freeBufferLocked on that slot.  Because the buffer slot has already
   103     // been overwritten with the new buffer all we have to do is skip the
   104     // releaseBuffer call and we should be in the same state we'd be in if we
   105     // had released the old buffer first.
   106     if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT &&
   107         item.mBuf != mCurrentBufferSlot) {
   108         // Release the previous buffer.
   109 #if ANDROID_VERSION >= 19
   110         err = releaseBufferLocked(mCurrentBufferSlot, mCurrentBuffer,
   111                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
   112 #else
   113         err = releaseBufferLocked(mCurrentBufferSlot, EGL_NO_DISPLAY,
   114                 EGL_NO_SYNC_KHR);
   115 #endif
   116         if (err != NO_ERROR && err != BufferQueue::STALE_BUFFER_SLOT) {
   117             ALOGE("error releasing buffer: %s (%d)", strerror(-err), err);
   118             return err;
   119         }
   120     }
   121     mCurrentBufferSlot = item.mBuf;
   122     mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
   123     outFence = item.mFence;
   124     outBuffer = mCurrentBuffer;
   125     return NO_ERROR;
   126 }
   128 // Overrides ConsumerBase::onFrameAvailable(), does not call base class impl.
   129 void FramebufferSurface::onFrameAvailable() {
   130     sp<GraphicBuffer> buf;
   131     sp<Fence> acquireFence;
   132     status_t err = nextBuffer(buf, acquireFence);
   133     if (err != NO_ERROR) {
   134         ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)",
   135                 strerror(-err), err);
   136         return;
   137     }
   138     if (acquireFence.get() && acquireFence->isValid())
   139         mPrevFBAcquireFence = new Fence(acquireFence->dup());
   140     else
   141         mPrevFBAcquireFence = Fence::NO_FENCE;
   143     lastHandle = buf->handle;
   144 }
   146 void FramebufferSurface::freeBufferLocked(int slotIndex) {
   147     ConsumerBase::freeBufferLocked(slotIndex);
   148     if (slotIndex == mCurrentBufferSlot) {
   149         mCurrentBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
   150     }
   151 }
   153 status_t FramebufferSurface::setReleaseFenceFd(int fenceFd) {
   154     status_t err = NO_ERROR;
   155     if (fenceFd >= 0) {
   156         sp<Fence> fence(new Fence(fenceFd));
   157         if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) {
   158 #if ANDROID_VERSION >= 19
   159             status_t err = addReleaseFence(mCurrentBufferSlot, mCurrentBuffer,  fence);
   160 #else
   161             status_t err = addReleaseFence(mCurrentBufferSlot, fence);
   162 #endif
   163             ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)",
   164                     strerror(-err), err);
   165         }
   166     }
   167     return err;
   168 }
   170 int FramebufferSurface::GetPrevFBAcquireFd() {
   171   return mPrevFBAcquireFence->dup();
   172 }
   174 status_t FramebufferSurface::setUpdateRectangle(const Rect& r)
   175 {
   176     return INVALID_OPERATION;
   177 }
   179 status_t FramebufferSurface::compositionComplete()
   180 {
   181     return NO_ERROR;
   182 }
   184 void FramebufferSurface::dump(String8& result) {
   185     ConsumerBase::dump(result);
   186 }
   188 void FramebufferSurface::dump(String8& result, const char* prefix) {
   189     ConsumerBase::dump(result);
   190 }
   192 // ----------------------------------------------------------------------------
   193 }; // namespace android
   194 // ----------------------------------------------------------------------------

mercurial