FramebufferSurface.cpp revision 47650f4f66a49e1815ad08ca4fb12a661d133abc
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> 3284493cd420d3d53a16ae7c745ed38afffb4e67f5Dan Stoza#include <gui/BufferItem.h> 33392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h> 3484493cd420d3d53a16ae7c745ed38afffb4e67f5Dan Stoza#include <gui/Surface.h> 353e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <ui/GraphicBuffer.h> 363e87601170141229d661df93e2f59e1ced73474bMathias Agopian 3733ceeb32582739dd74e404593d9ddf8adf5100bbMathias Agopian#include "FramebufferSurface.h" 3833ceeb32582739dd74e404593d9ddf8adf5100bbMathias Agopian#include "HWComposer.h" 393e87601170141229d661df93e2f59e1ced73474bMathias Agopian 40cdbaecb54152ce98789823420d426077d72aa1e7Jamie Gennis#ifndef NUM_FRAMEBUFFER_SURFACE_BUFFERS 41cdbaecb54152ce98789823420d426077d72aa1e7Jamie Gennis#define NUM_FRAMEBUFFER_SURFACE_BUFFERS (2) 42cdbaecb54152ce98789823420d426077d72aa1e7Jamie Gennis#endif 43cdbaecb54152ce98789823420d426077d72aa1e7Jamie Gennis 443e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 453e87601170141229d661df93e2f59e1ced73474bMathias Agopiannamespace android { 463e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 473e87601170141229d661df93e2f59e1ced73474bMathias Agopian 483e87601170141229d661df93e2f59e1ced73474bMathias Agopian/* 493e87601170141229d661df93e2f59e1ced73474bMathias Agopian * This implements the (main) framebuffer management. This class is used 503e87601170141229d661df93e2f59e1ced73474bMathias Agopian * mostly by SurfaceFlinger, but also by command line GL application. 513e87601170141229d661df93e2f59e1ced73474bMathias Agopian * 523e87601170141229d661df93e2f59e1ced73474bMathias Agopian */ 533e87601170141229d661df93e2f59e1ced73474bMathias Agopian 54db89edc94bd2a78226b407f9f7261e202e7fa325Mathias AgopianFramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp, 55db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian const sp<IGraphicBufferConsumer>& consumer) : 56db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian ConsumerBase(consumer), 57f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian mDisplayType(disp), 581a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBufferSlot(-1), 59b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mCurrentBuffer(0), 60b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mHwc(hwc) 613e87601170141229d661df93e2f59e1ced73474bMathias Agopian{ 62b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mName = "FramebufferSurface"; 63db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setConsumerName(mName); 64db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB | 65f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian GRALLOC_USAGE_HW_RENDER | 66f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian GRALLOC_USAGE_HW_COMPOSER); 67db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setDefaultBufferFormat(mHwc.getFormat(disp)); 68db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setDefaultBufferSize(mHwc.getWidth(disp), mHwc.getHeight(disp)); 69db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS); 7099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall} 7199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall 727cd85979e81cd632c37852f7ca716089dc52e899Jesse Hallstatus_t FramebufferSurface::beginFrame(bool /*mustRecompose*/) { 73028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall return NO_ERROR; 74028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall} 75028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall 7692dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzynstatus_t FramebufferSurface::prepareFrame(CompositionType /*compositionType*/) { 7738efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall return NO_ERROR; 7838efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall} 7938efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall 8099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hallstatus_t FramebufferSurface::advanceFrame() { 8199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall // Once we remove FB HAL support, we can call nextBuffer() from here 8299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall // instead of using onFrameAvailable(). No real benefit, except it'll be 8399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall // more like VirtualDisplaySurface. 8499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall return NO_ERROR; 8599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall} 8699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall 87da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianstatus_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) { 881a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis Mutex::Autolock lock(mMutex); 893e87601170141229d661df93e2f59e1ced73474bMathias Agopian 9084493cd420d3d53a16ae7c745ed38afffb4e67f5Dan Stoza BufferItem item; 911585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden status_t err = acquireBufferLocked(&item, 0); 921a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 93da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian outBuffer = mCurrentBuffer; 941a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return NO_ERROR; 951a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } else if (err != NO_ERROR) { 961a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err); 971a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return err; 981a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 993e87601170141229d661df93e2f59e1ced73474bMathias Agopian 1001a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // If the BufferQueue has freed and reallocated a buffer in mCurrentSlot 1011a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // then we may have acquired the slot we already own. If we had released 1021a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // our current buffer before we call acquireBuffer then that release call 1031a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // would have returned STALE_BUFFER_SLOT, and we would have called 1041a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // freeBufferLocked on that slot. Because the buffer slot has already 1051a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // been overwritten with the new buffer all we have to do is skip the 1061a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // releaseBuffer call and we should be in the same state we'd be in if we 1071a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // had released the old buffer first. 1081a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT && 10947650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos item.mSlot != mCurrentBufferSlot) { 1101a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // Release the previous buffer. 111c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar err = releaseBufferLocked(mCurrentBufferSlot, mCurrentBuffer, 112c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); 113ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (err < NO_ERROR) { 1141a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ALOGE("error releasing buffer: %s (%d)", strerror(-err), err); 1151a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return err; 1163e87601170141229d661df93e2f59e1ced73474bMathias Agopian } 1171a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 11847650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos mCurrentBufferSlot = item.mSlot; 1191a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer; 120da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian outFence = item.mFence; 121da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian outBuffer = mCurrentBuffer; 1221a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return NO_ERROR; 1233e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1243e87601170141229d661df93e2f59e1ced73474bMathias Agopian 125b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl. 1268dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stozavoid FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) { 1271a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis sp<GraphicBuffer> buf; 128da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian sp<Fence> acquireFence; 129da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian status_t err = nextBuffer(buf, acquireFence); 1301a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err != NO_ERROR) { 131da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)", 1321a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis strerror(-err), err); 1331a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return; 1341a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 135f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian err = mHwc.fbPost(mDisplayType, acquireFence, buf); 1361a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err != NO_ERROR) { 1371a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ALOGE("error posting framebuffer: %d", err); 1381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 1391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis} 1401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 1411a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid FramebufferSurface::freeBufferLocked(int slotIndex) { 1421a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ConsumerBase::freeBufferLocked(slotIndex); 1431a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (slotIndex == mCurrentBufferSlot) { 1441a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBufferSlot = BufferQueue::INVALID_BUFFER_SLOT; 1451a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 1461a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis} 1471a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 148851cfe834295224cd64bdd499872b95b19c4de8cJesse Hallvoid FramebufferSurface::onFrameCommitted() { 149851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall sp<Fence> fence = mHwc.getAndResetReleaseFence(mDisplayType); 15013f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall if (fence->isValid() && 15113f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) { 152c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = addReleaseFence(mCurrentBufferSlot, 153c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mCurrentBuffer, fence); 15413f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)", 15513f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall strerror(-err), err); 156da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian } 157da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian} 158da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 1593e87601170141229d661df93e2f59e1ced73474bMathias Agopianstatus_t FramebufferSurface::compositionComplete() 1603e87601170141229d661df93e2f59e1ced73474bMathias Agopian{ 161b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden return mHwc.fbCompositionComplete(); 1623e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1633e87601170141229d661df93e2f59e1ced73474bMathias Agopian 164f10c46ef855b6410b20ebd8b1351d4d78d8eca8eDan Stozavoid FramebufferSurface::dumpAsString(String8& result) const { 1651a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ConsumerBase::dump(result); 1663e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1673e87601170141229d661df93e2f59e1ced73474bMathias Agopian 16874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid FramebufferSurface::dumpLocked(String8& result, const char* prefix) const 1697adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall{ 1707adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mHwc.fbDump(result); 17174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian ConsumerBase::dumpLocked(result, prefix); 1727adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall} 1737adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall 1743e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 1753e87601170141229d661df93e2f59e1ced73474bMathias Agopian}; // namespace android 1763e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 177