FramebufferSurface.cpp revision c5d7b7d323bba8772a9005f7d300ad983a04733a
13e87601170141229d661df93e2f59e1ced73474bMathias Agopian/* 23e87601170141229d661df93e2f59e1ced73474bMathias Agopian ** 31a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ** Copyright 2012 The Android Open Source Project 43e87601170141229d661df93e2f59e1ced73474bMathias Agopian ** 53e87601170141229d661df93e2f59e1ced73474bMathias Agopian ** Licensed under the Apache License Version 2.0(the "License"); 63e87601170141229d661df93e2f59e1ced73474bMathias Agopian ** you may not use this file except in compliance with the License. 73e87601170141229d661df93e2f59e1ced73474bMathias Agopian ** You may obtain a copy of the License at 83e87601170141229d661df93e2f59e1ced73474bMathias Agopian ** 93e87601170141229d661df93e2f59e1ced73474bMathias Agopian ** http://www.apache.org/licenses/LICENSE-2.0 103e87601170141229d661df93e2f59e1ced73474bMathias Agopian ** 113e87601170141229d661df93e2f59e1ced73474bMathias Agopian ** Unless required by applicable law or agreed to in writing software 123e87601170141229d661df93e2f59e1ced73474bMathias Agopian ** distributed under the License is distributed on an "AS IS" BASIS 133e87601170141229d661df93e2f59e1ced73474bMathias Agopian ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. 143e87601170141229d661df93e2f59e1ced73474bMathias Agopian ** See the License for the specific language governing permissions and 153e87601170141229d661df93e2f59e1ced73474bMathias Agopian ** limitations under the License. 163e87601170141229d661df93e2f59e1ced73474bMathias Agopian */ 173e87601170141229d661df93e2f59e1ced73474bMathias Agopian 183e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <stdlib.h> 193e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <stdio.h> 203e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <string.h> 213e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <errno.h> 223e87601170141229d661df93e2f59e1ced73474bMathias Agopian 233e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <cutils/log.h> 243e87601170141229d661df93e2f59e1ced73474bMathias Agopian 253e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <utils/String8.h> 263e87601170141229d661df93e2f59e1ced73474bMathias Agopian 273e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <ui/Rect.h> 283e87601170141229d661df93e2f59e1ced73474bMathias Agopian 293e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <EGL/egl.h> 303e87601170141229d661df93e2f59e1ced73474bMathias Agopian 313e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <hardware/hardware.h> 32e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h> 33392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h> 343e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <ui/GraphicBuffer.h> 353e87601170141229d661df93e2f59e1ced73474bMathias Agopian 3633ceeb32582739dd74e404593d9ddf8adf5100bbMathias Agopian#include "FramebufferSurface.h" 3733ceeb32582739dd74e404593d9ddf8adf5100bbMathias Agopian#include "HWComposer.h" 383e87601170141229d661df93e2f59e1ced73474bMathias Agopian 39cdbaecb54152ce98789823420d426077d72aa1e7Jamie Gennis#ifndef NUM_FRAMEBUFFER_SURFACE_BUFFERS 40cdbaecb54152ce98789823420d426077d72aa1e7Jamie Gennis#define NUM_FRAMEBUFFER_SURFACE_BUFFERS (2) 41cdbaecb54152ce98789823420d426077d72aa1e7Jamie Gennis#endif 42cdbaecb54152ce98789823420d426077d72aa1e7Jamie Gennis 433e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 443e87601170141229d661df93e2f59e1ced73474bMathias Agopiannamespace android { 453e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 463e87601170141229d661df93e2f59e1ced73474bMathias Agopian 473e87601170141229d661df93e2f59e1ced73474bMathias Agopian/* 483e87601170141229d661df93e2f59e1ced73474bMathias Agopian * This implements the (main) framebuffer management. This class is used 493e87601170141229d661df93e2f59e1ced73474bMathias Agopian * mostly by SurfaceFlinger, but also by command line GL application. 503e87601170141229d661df93e2f59e1ced73474bMathias Agopian * 513e87601170141229d661df93e2f59e1ced73474bMathias Agopian */ 523e87601170141229d661df93e2f59e1ced73474bMathias Agopian 53f5a33928349bebc8eebc9f466618997e98c24e68Mathias AgopianFramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp) : 5472f096fb1ad0a0deadbfac5f88627461905d38e8Jamie Gennis ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())), 55f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian mDisplayType(disp), 561a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBufferSlot(-1), 57b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mCurrentBuffer(0), 58b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mHwc(hwc) 593e87601170141229d661df93e2f59e1ced73474bMathias Agopian{ 60b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mName = "FramebufferSurface"; 61b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mBufferQueue->setConsumerName(mName); 62b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_FB | 63f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian GRALLOC_USAGE_HW_RENDER | 64f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian GRALLOC_USAGE_HW_COMPOSER); 65f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian mBufferQueue->setDefaultBufferFormat(mHwc.getFormat(disp)); 66f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian mBufferQueue->setDefaultBufferSize(mHwc.getWidth(disp), mHwc.getHeight(disp)); 67b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mBufferQueue->setSynchronousMode(true); 68cdbaecb54152ce98789823420d426077d72aa1e7Jamie Gennis mBufferQueue->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS); 691a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis} 701a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 7199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hallsp<IGraphicBufferProducer> FramebufferSurface::getIGraphicBufferProducer() const { 7299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall return getBufferQueue(); 7399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall} 7499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall 7599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hallstatus_t FramebufferSurface::advanceFrame() { 7699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall // Once we remove FB HAL support, we can call nextBuffer() from here 7799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall // instead of using onFrameAvailable(). No real benefit, except it'll be 7899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall // more like VirtualDisplaySurface. 7999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall return NO_ERROR; 8099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall} 8199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall 82da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianstatus_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) { 831a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis Mutex::Autolock lock(mMutex); 843e87601170141229d661df93e2f59e1ced73474bMathias Agopian 851a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis BufferQueue::BufferItem item; 861a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis status_t err = acquireBufferLocked(&item); 871a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 88da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian outBuffer = mCurrentBuffer; 891a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return NO_ERROR; 901a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } else if (err != NO_ERROR) { 911a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err); 921a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return err; 931a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 943e87601170141229d661df93e2f59e1ced73474bMathias Agopian 951a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // If the BufferQueue has freed and reallocated a buffer in mCurrentSlot 961a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // then we may have acquired the slot we already own. If we had released 971a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // our current buffer before we call acquireBuffer then that release call 981a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // would have returned STALE_BUFFER_SLOT, and we would have called 991a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // freeBufferLocked on that slot. Because the buffer slot has already 1001a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // been overwritten with the new buffer all we have to do is skip the 1011a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // releaseBuffer call and we should be in the same state we'd be in if we 1021a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // had released the old buffer first. 1031a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT && 1041a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis item.mBuf != mCurrentBufferSlot) { 1051a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // Release the previous buffer. 106c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar err = releaseBufferLocked(mCurrentBufferSlot, mCurrentBuffer, 107c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); 1081a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err != NO_ERROR && err != BufferQueue::STALE_BUFFER_SLOT) { 1091a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ALOGE("error releasing buffer: %s (%d)", strerror(-err), err); 1101a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return err; 1113e87601170141229d661df93e2f59e1ced73474bMathias Agopian } 1121a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 1131a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBufferSlot = item.mBuf; 1141a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer; 115da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian outFence = item.mFence; 116da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian outBuffer = mCurrentBuffer; 1171a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return NO_ERROR; 1183e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1193e87601170141229d661df93e2f59e1ced73474bMathias Agopian 120b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl. 1211a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid FramebufferSurface::onFrameAvailable() { 1221a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis sp<GraphicBuffer> buf; 123da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian sp<Fence> acquireFence; 124da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian status_t err = nextBuffer(buf, acquireFence); 1251a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err != NO_ERROR) { 126da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)", 1271a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis strerror(-err), err); 1281a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return; 1291a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 130f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian err = mHwc.fbPost(mDisplayType, acquireFence, buf); 1311a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err != NO_ERROR) { 1321a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ALOGE("error posting framebuffer: %d", err); 1331a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 1341a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis} 1351a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 1361a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid FramebufferSurface::freeBufferLocked(int slotIndex) { 1371a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ConsumerBase::freeBufferLocked(slotIndex); 1381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (slotIndex == mCurrentBufferSlot) { 1391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBufferSlot = BufferQueue::INVALID_BUFFER_SLOT; 1401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 1411a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis} 1421a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 143851cfe834295224cd64bdd499872b95b19c4de8cJesse Hallvoid FramebufferSurface::onFrameCommitted() { 144851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall sp<Fence> fence = mHwc.getAndResetReleaseFence(mDisplayType); 14513f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall if (fence->isValid() && 14613f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) { 147c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = addReleaseFence(mCurrentBufferSlot, 148c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mCurrentBuffer, fence); 14913f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)", 15013f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall strerror(-err), err); 151da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian } 152da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian} 153da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 1543e87601170141229d661df93e2f59e1ced73474bMathias Agopianstatus_t FramebufferSurface::compositionComplete() 1553e87601170141229d661df93e2f59e1ced73474bMathias Agopian{ 156b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden return mHwc.fbCompositionComplete(); 1573e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1583e87601170141229d661df93e2f59e1ced73474bMathias Agopian 15999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// Since DisplaySurface and ConsumerBase both have a method with this 16099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// signature, results will vary based on the static pointer type the caller is 16199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// using: 16299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// void dump(FrameBufferSurface* fbs, String8& s) { 16399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// // calls FramebufferSurface::dump() 16499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// fbs->dump(s); 16599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// 16699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// // calls ConsumerBase::dump() since it is non-virtual 16799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// static_cast<ConsumerBase*>(fbs)->dump(s); 16899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// 16999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// // calls FramebufferSurface::dump() since it is virtual 17099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// static_cast<DisplaySurface*>(fbs)->dump(s); 17199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// } 17299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// To make sure that all of these end up doing the same thing, we just redirect 17399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// to ConsumerBase::dump() here. It will take the internal lock, and then call 17499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// virtual dumpLocked(), which is where the real work happens. 17599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hallvoid FramebufferSurface::dump(String8& result) const { 1761a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ConsumerBase::dump(result); 1773e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1783e87601170141229d661df93e2f59e1ced73474bMathias Agopian 17974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid FramebufferSurface::dumpLocked(String8& result, const char* prefix) const 1807adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall{ 1817adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mHwc.fbDump(result); 18274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian ConsumerBase::dumpLocked(result, prefix); 1837adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall} 1847adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall 1853e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 1863e87601170141229d661df93e2f59e1ced73474bMathias Agopian}; // namespace android 1873e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 188