FramebufferSurface.cpp revision ad678e18b66f495efa78dc3b9ab99b579945c9e2
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) : 54595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian ConsumerBase(new BufferQueue(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)); 67cdbaecb54152ce98789823420d426077d72aa1e7Jamie Gennis mBufferQueue->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS); 681a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis} 691a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 7099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hallsp<IGraphicBufferProducer> FramebufferSurface::getIGraphicBufferProducer() const { 7199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall return getBufferQueue(); 7299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall} 7399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall 7438efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hallstatus_t FramebufferSurface::prepareFrame(CompositionType compositionType) { 7538efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall return NO_ERROR; 7638efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall} 7738efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall 7899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hallstatus_t FramebufferSurface::advanceFrame() { 7999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall // Once we remove FB HAL support, we can call nextBuffer() from here 8099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall // instead of using onFrameAvailable(). No real benefit, except it'll be 8199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall // more like VirtualDisplaySurface. 8299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall return NO_ERROR; 8399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall} 8499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall 85da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianstatus_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) { 861a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis Mutex::Autolock lock(mMutex); 873e87601170141229d661df93e2f59e1ced73474bMathias Agopian 881a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis BufferQueue::BufferItem item; 891585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden status_t err = acquireBufferLocked(&item, 0); 901a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 91da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian outBuffer = mCurrentBuffer; 921a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return NO_ERROR; 931a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } else if (err != NO_ERROR) { 941a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err); 951a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return err; 961a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 973e87601170141229d661df93e2f59e1ced73474bMathias Agopian 981a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // If the BufferQueue has freed and reallocated a buffer in mCurrentSlot 991a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // then we may have acquired the slot we already own. If we had released 1001a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // our current buffer before we call acquireBuffer then that release call 1011a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // would have returned STALE_BUFFER_SLOT, and we would have called 1021a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // freeBufferLocked on that slot. Because the buffer slot has already 1031a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // been overwritten with the new buffer all we have to do is skip the 1041a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // releaseBuffer call and we should be in the same state we'd be in if we 1051a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // had released the old buffer first. 1061a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT && 1071a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis item.mBuf != mCurrentBufferSlot) { 1081a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // Release the previous buffer. 109c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar err = releaseBufferLocked(mCurrentBufferSlot, mCurrentBuffer, 110c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); 111ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (err < NO_ERROR) { 1121a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ALOGE("error releasing buffer: %s (%d)", strerror(-err), err); 1131a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return err; 1143e87601170141229d661df93e2f59e1ced73474bMathias Agopian } 1151a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 1161a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBufferSlot = item.mBuf; 1171a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer; 118da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian outFence = item.mFence; 119da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian outBuffer = mCurrentBuffer; 1201a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return NO_ERROR; 1213e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1223e87601170141229d661df93e2f59e1ced73474bMathias Agopian 123b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl. 1241a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid FramebufferSurface::onFrameAvailable() { 1251a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis sp<GraphicBuffer> buf; 126da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian sp<Fence> acquireFence; 127da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian status_t err = nextBuffer(buf, acquireFence); 1281a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err != NO_ERROR) { 129da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)", 1301a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis strerror(-err), err); 1311a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return; 1321a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 133f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian err = mHwc.fbPost(mDisplayType, acquireFence, buf); 1341a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err != NO_ERROR) { 1351a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ALOGE("error posting framebuffer: %d", err); 1361a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 1371a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis} 1381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 1391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid FramebufferSurface::freeBufferLocked(int slotIndex) { 1401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ConsumerBase::freeBufferLocked(slotIndex); 1411a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (slotIndex == mCurrentBufferSlot) { 1421a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBufferSlot = BufferQueue::INVALID_BUFFER_SLOT; 1431a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 1441a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis} 1451a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 146851cfe834295224cd64bdd499872b95b19c4de8cJesse Hallvoid FramebufferSurface::onFrameCommitted() { 147851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall sp<Fence> fence = mHwc.getAndResetReleaseFence(mDisplayType); 14813f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall if (fence->isValid() && 14913f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) { 150c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = addReleaseFence(mCurrentBufferSlot, 151c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mCurrentBuffer, fence); 15213f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)", 15313f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall strerror(-err), err); 154da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian } 155da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian} 156da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 1573e87601170141229d661df93e2f59e1ced73474bMathias Agopianstatus_t FramebufferSurface::compositionComplete() 1583e87601170141229d661df93e2f59e1ced73474bMathias Agopian{ 159b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden return mHwc.fbCompositionComplete(); 1603e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1613e87601170141229d661df93e2f59e1ced73474bMathias Agopian 16299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// Since DisplaySurface and ConsumerBase both have a method with this 16399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// signature, results will vary based on the static pointer type the caller is 16499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// using: 16599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// void dump(FrameBufferSurface* fbs, String8& s) { 16699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// // calls FramebufferSurface::dump() 16799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// fbs->dump(s); 16899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// 16999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// // calls ConsumerBase::dump() since it is non-virtual 17099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// static_cast<ConsumerBase*>(fbs)->dump(s); 17199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// 17299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// // calls FramebufferSurface::dump() since it is virtual 17399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// static_cast<DisplaySurface*>(fbs)->dump(s); 17499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// } 17599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// To make sure that all of these end up doing the same thing, we just redirect 17699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// to ConsumerBase::dump() here. It will take the internal lock, and then call 17799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// virtual dumpLocked(), which is where the real work happens. 17899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hallvoid FramebufferSurface::dump(String8& result) const { 1791a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ConsumerBase::dump(result); 1803e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1813e87601170141229d661df93e2f59e1ced73474bMathias Agopian 18274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid FramebufferSurface::dumpLocked(String8& result, const char* prefix) const 1837adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall{ 1847adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mHwc.fbDump(result); 18574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian ConsumerBase::dumpLocked(result, prefix); 1867adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall} 1877adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall 1883e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 1893e87601170141229d661df93e2f59e1ced73474bMathias Agopian}; // namespace android 1903e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 191