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> 323e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <gui/SurfaceTextureClient.h> 333e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <ui/GraphicBuffer.h> 343e87601170141229d661df93e2f59e1ced73474bMathias Agopian 353e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include "DisplayHardware/FramebufferSurface.h" 36f33e4b6f13bc3ee2d2a4e1abd1ada171c70d3492Mathias Agopian#include "DisplayHardware/GraphicBufferAlloc.h" 37b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden#include "DisplayHardware/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 71da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianstatus_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) { 721a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis Mutex::Autolock lock(mMutex); 733e87601170141229d661df93e2f59e1ced73474bMathias Agopian 741a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis BufferQueue::BufferItem item; 751a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis status_t err = acquireBufferLocked(&item); 761a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 77da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian outBuffer = mCurrentBuffer; 781a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return NO_ERROR; 791a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } else if (err != NO_ERROR) { 801a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err); 811a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return err; 821a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 833e87601170141229d661df93e2f59e1ced73474bMathias Agopian 841a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // If the BufferQueue has freed and reallocated a buffer in mCurrentSlot 851a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // then we may have acquired the slot we already own. If we had released 861a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // our current buffer before we call acquireBuffer then that release call 871a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // would have returned STALE_BUFFER_SLOT, and we would have called 881a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // freeBufferLocked on that slot. Because the buffer slot has already 891a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // been overwritten with the new buffer all we have to do is skip the 901a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // releaseBuffer call and we should be in the same state we'd be in if we 911a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // had released the old buffer first. 921a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT && 931a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis item.mBuf != mCurrentBufferSlot) { 941a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // Release the previous buffer. 951a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis err = releaseBufferLocked(mCurrentBufferSlot, EGL_NO_DISPLAY, 96b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis EGL_NO_SYNC_KHR); 971a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err != NO_ERROR && err != BufferQueue::STALE_BUFFER_SLOT) { 981a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ALOGE("error releasing buffer: %s (%d)", strerror(-err), err); 991a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return err; 1003e87601170141229d661df93e2f59e1ced73474bMathias Agopian } 1011a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 1021a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBufferSlot = item.mBuf; 1031a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer; 104da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian outFence = item.mFence; 105da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian outBuffer = mCurrentBuffer; 1061a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return NO_ERROR; 1073e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1083e87601170141229d661df93e2f59e1ced73474bMathias Agopian 109b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl. 1101a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid FramebufferSurface::onFrameAvailable() { 1111a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis sp<GraphicBuffer> buf; 112da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian sp<Fence> acquireFence; 113da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian status_t err = nextBuffer(buf, acquireFence); 1141a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err != NO_ERROR) { 115da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)", 1161a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis strerror(-err), err); 1171a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return; 1181a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 119f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian err = mHwc.fbPost(mDisplayType, acquireFence, buf); 1201a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err != NO_ERROR) { 1211a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ALOGE("error posting framebuffer: %d", err); 1221a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 1231a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis} 1241a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 1251a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid FramebufferSurface::freeBufferLocked(int slotIndex) { 1261a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ConsumerBase::freeBufferLocked(slotIndex); 1271a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (slotIndex == mCurrentBufferSlot) { 1281a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBufferSlot = BufferQueue::INVALID_BUFFER_SLOT; 1291a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 1301a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis} 1311a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 132da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianstatus_t FramebufferSurface::setReleaseFenceFd(int fenceFd) { 133da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian status_t err = NO_ERROR; 134da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian if (fenceFd >= 0) { 135da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian sp<Fence> fence(new Fence(fenceFd)); 136da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) { 137da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian status_t err = addReleaseFence(mCurrentBufferSlot, fence); 138da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)", 139da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian strerror(-err), err); 140da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian } 141da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian } 142da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian return err; 143da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian} 144da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 1453e87601170141229d661df93e2f59e1ced73474bMathias Agopianstatus_t FramebufferSurface::setUpdateRectangle(const Rect& r) 1463e87601170141229d661df93e2f59e1ced73474bMathias Agopian{ 1471a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return INVALID_OPERATION; 1483e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1493e87601170141229d661df93e2f59e1ced73474bMathias Agopian 1503e87601170141229d661df93e2f59e1ced73474bMathias Agopianstatus_t FramebufferSurface::compositionComplete() 1513e87601170141229d661df93e2f59e1ced73474bMathias Agopian{ 152b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden return mHwc.fbCompositionComplete(); 1533e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1543e87601170141229d661df93e2f59e1ced73474bMathias Agopian 1553e87601170141229d661df93e2f59e1ced73474bMathias Agopianvoid FramebufferSurface::dump(String8& result) { 156b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mHwc.fbDump(result); 1571a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ConsumerBase::dump(result); 1583e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1593e87601170141229d661df93e2f59e1ced73474bMathias Agopian 1603e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 1613e87601170141229d661df93e2f59e1ced73474bMathias Agopian}; // namespace android 1623e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 163