1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/gonk/libdisplay/FramebufferSurface.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,194 @@ 1.4 +/* 1.5 + ** 1.6 + ** Copyright 2012 The Android Open Source Project 1.7 + ** 1.8 + ** Licensed under the Apache License Version 2.0(the "License"); 1.9 + ** you may not use this file except in compliance with the License. 1.10 + ** You may obtain a copy of the License at 1.11 + ** 1.12 + ** http://www.apache.org/licenses/LICENSE-2.0 1.13 + ** 1.14 + ** Unless required by applicable law or agreed to in writing software 1.15 + ** distributed under the License is distributed on an "AS IS" BASIS 1.16 + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. 1.17 + ** See the License for the specific language governing permissions and 1.18 + ** limitations under the License. 1.19 + */ 1.20 + 1.21 +#include <stdlib.h> 1.22 +#include <stdio.h> 1.23 +#include <string.h> 1.24 +#include <errno.h> 1.25 + 1.26 +#include <cutils/log.h> 1.27 + 1.28 +#include <utils/String8.h> 1.29 + 1.30 +#include <ui/Rect.h> 1.31 + 1.32 +#include <EGL/egl.h> 1.33 + 1.34 +#include <hardware/hardware.h> 1.35 +#if ANDROID_VERSION == 17 1.36 +#include <gui/SurfaceTextureClient.h> 1.37 +#endif 1.38 +#include <ui/GraphicBuffer.h> 1.39 + 1.40 +#include "FramebufferSurface.h" 1.41 +#include "GraphicBufferAlloc.h" 1.42 + 1.43 +#ifndef NUM_FRAMEBUFFER_SURFACE_BUFFERS 1.44 +#define NUM_FRAMEBUFFER_SURFACE_BUFFERS (2) 1.45 +#endif 1.46 + 1.47 +// ---------------------------------------------------------------------------- 1.48 +namespace android { 1.49 +// ---------------------------------------------------------------------------- 1.50 + 1.51 +/* 1.52 + * This implements the (main) framebuffer management. This class 1.53 + * was adapted from the version in SurfaceFlinger 1.54 + */ 1.55 +FramebufferSurface::FramebufferSurface(int disp, uint32_t width, uint32_t height, uint32_t format, 1.56 + sp<BufferQueue>& bq) : 1.57 +#if ANDROID_VERSION >= 19 1.58 + ConsumerBase(bq, true), 1.59 +#else 1.60 + ConsumerBase(bq), 1.61 +#endif 1.62 + mDisplayType(disp), 1.63 + mCurrentBufferSlot(-1), 1.64 + mCurrentBuffer(0), 1.65 + lastHandle(0) 1.66 +{ 1.67 + mName = "FramebufferSurface"; 1.68 + 1.69 +#if ANDROID_VERSION >= 19 1.70 + sp<IGraphicBufferConsumer> consumer = mConsumer; 1.71 +#else 1.72 + sp<BufferQueue> consumer = mBufferQueue; 1.73 + consumer->setSynchronousMode(true); 1.74 +#endif 1.75 + consumer->setConsumerName(mName); 1.76 + consumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB | 1.77 + GRALLOC_USAGE_HW_RENDER | 1.78 + GRALLOC_USAGE_HW_COMPOSER); 1.79 + consumer->setDefaultBufferFormat(format); 1.80 + consumer->setDefaultBufferSize(width, height); 1.81 + consumer->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS); 1.82 +} 1.83 + 1.84 +status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) { 1.85 + Mutex::Autolock lock(mMutex); 1.86 + 1.87 + BufferQueue::BufferItem item; 1.88 +#if ANDROID_VERSION >= 19 1.89 + status_t err = acquireBufferLocked(&item, 0); 1.90 +#else 1.91 + status_t err = acquireBufferLocked(&item); 1.92 +#endif 1.93 + if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 1.94 + outBuffer = mCurrentBuffer; 1.95 + return NO_ERROR; 1.96 + } else if (err != NO_ERROR) { 1.97 + ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err); 1.98 + return err; 1.99 + } 1.100 + 1.101 + // If the BufferQueue has freed and reallocated a buffer in mCurrentSlot 1.102 + // then we may have acquired the slot we already own. If we had released 1.103 + // our current buffer before we call acquireBuffer then that release call 1.104 + // would have returned STALE_BUFFER_SLOT, and we would have called 1.105 + // freeBufferLocked on that slot. Because the buffer slot has already 1.106 + // been overwritten with the new buffer all we have to do is skip the 1.107 + // releaseBuffer call and we should be in the same state we'd be in if we 1.108 + // had released the old buffer first. 1.109 + if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT && 1.110 + item.mBuf != mCurrentBufferSlot) { 1.111 + // Release the previous buffer. 1.112 +#if ANDROID_VERSION >= 19 1.113 + err = releaseBufferLocked(mCurrentBufferSlot, mCurrentBuffer, 1.114 + EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); 1.115 +#else 1.116 + err = releaseBufferLocked(mCurrentBufferSlot, EGL_NO_DISPLAY, 1.117 + EGL_NO_SYNC_KHR); 1.118 +#endif 1.119 + if (err != NO_ERROR && err != BufferQueue::STALE_BUFFER_SLOT) { 1.120 + ALOGE("error releasing buffer: %s (%d)", strerror(-err), err); 1.121 + return err; 1.122 + } 1.123 + } 1.124 + mCurrentBufferSlot = item.mBuf; 1.125 + mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer; 1.126 + outFence = item.mFence; 1.127 + outBuffer = mCurrentBuffer; 1.128 + return NO_ERROR; 1.129 +} 1.130 + 1.131 +// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl. 1.132 +void FramebufferSurface::onFrameAvailable() { 1.133 + sp<GraphicBuffer> buf; 1.134 + sp<Fence> acquireFence; 1.135 + status_t err = nextBuffer(buf, acquireFence); 1.136 + if (err != NO_ERROR) { 1.137 + ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)", 1.138 + strerror(-err), err); 1.139 + return; 1.140 + } 1.141 + if (acquireFence.get() && acquireFence->isValid()) 1.142 + mPrevFBAcquireFence = new Fence(acquireFence->dup()); 1.143 + else 1.144 + mPrevFBAcquireFence = Fence::NO_FENCE; 1.145 + 1.146 + lastHandle = buf->handle; 1.147 +} 1.148 + 1.149 +void FramebufferSurface::freeBufferLocked(int slotIndex) { 1.150 + ConsumerBase::freeBufferLocked(slotIndex); 1.151 + if (slotIndex == mCurrentBufferSlot) { 1.152 + mCurrentBufferSlot = BufferQueue::INVALID_BUFFER_SLOT; 1.153 + } 1.154 +} 1.155 + 1.156 +status_t FramebufferSurface::setReleaseFenceFd(int fenceFd) { 1.157 + status_t err = NO_ERROR; 1.158 + if (fenceFd >= 0) { 1.159 + sp<Fence> fence(new Fence(fenceFd)); 1.160 + if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) { 1.161 +#if ANDROID_VERSION >= 19 1.162 + status_t err = addReleaseFence(mCurrentBufferSlot, mCurrentBuffer, fence); 1.163 +#else 1.164 + status_t err = addReleaseFence(mCurrentBufferSlot, fence); 1.165 +#endif 1.166 + ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)", 1.167 + strerror(-err), err); 1.168 + } 1.169 + } 1.170 + return err; 1.171 +} 1.172 + 1.173 +int FramebufferSurface::GetPrevFBAcquireFd() { 1.174 + return mPrevFBAcquireFence->dup(); 1.175 +} 1.176 + 1.177 +status_t FramebufferSurface::setUpdateRectangle(const Rect& r) 1.178 +{ 1.179 + return INVALID_OPERATION; 1.180 +} 1.181 + 1.182 +status_t FramebufferSurface::compositionComplete() 1.183 +{ 1.184 + return NO_ERROR; 1.185 +} 1.186 + 1.187 +void FramebufferSurface::dump(String8& result) { 1.188 + ConsumerBase::dump(result); 1.189 +} 1.190 + 1.191 +void FramebufferSurface::dump(String8& result, const char* prefix) { 1.192 + ConsumerBase::dump(result); 1.193 +} 1.194 + 1.195 +// ---------------------------------------------------------------------------- 1.196 +}; // namespace android 1.197 +// ----------------------------------------------------------------------------