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 189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza// #define LOG_NDEBUG 0 199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#undef LOG_TAG 209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#define LOG_TAG "FramebufferSurface" 219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 22a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <errno.h> 233e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <stdio.h> 24a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <stdlib.h> 253e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <string.h> 263e87601170141229d661df93e2f59e1ced73474bMathias Agopian 273e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <utils/String8.h> 287823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h> 293e87601170141229d661df93e2f59e1ced73474bMathias Agopian 303e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <hardware/hardware.h> 3184493cd420d3d53a16ae7c745ed38afffb4e67f5Dan Stoza#include <gui/BufferItem.h> 32a9347647eca3101c014be902b713772de3977d87Mathias Agopian#include <gui/BufferQueue.h> 3384493cd420d3d53a16ae7c745ed38afffb4e67f5Dan Stoza#include <gui/Surface.h> 34a9347647eca3101c014be902b713772de3977d87Mathias Agopian 3519987a8cb2ca05e45876946b1eab66cc9d1f9a77Courtney Goeltzenleuchter#include <ui/DebugUtils.h> 363e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <ui/GraphicBuffer.h> 37a9347647eca3101c014be902b713772de3977d87Mathias Agopian#include <ui/Rect.h> 383e87601170141229d661df93e2f59e1ced73474bMathias Agopian 3933ceeb32582739dd74e404593d9ddf8adf5100bbMathias Agopian#include "FramebufferSurface.h" 4033ceeb32582739dd74e404593d9ddf8adf5100bbMathias Agopian#include "HWComposer.h" 411971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard#include "../SurfaceFlinger.h" 42cdbaecb54152ce98789823420d426077d72aa1e7Jamie Gennis 433e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 443e87601170141229d661df93e2f59e1ced73474bMathias Agopiannamespace android { 453e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 463e87601170141229d661df93e2f59e1ced73474bMathias Agopian 4734beb7a0ff0494b0c5ad81104171f8a49e599163Peiyong Linusing ui::Dataspace; 4834beb7a0ff0494b0c5ad81104171f8a49e599163Peiyong Lin 493e87601170141229d661df93e2f59e1ced73474bMathias Agopian/* 503e87601170141229d661df93e2f59e1ced73474bMathias Agopian * This implements the (main) framebuffer management. This class is used 513e87601170141229d661df93e2f59e1ced73474bMathias Agopian * mostly by SurfaceFlinger, but also by command line GL application. 523e87601170141229d661df93e2f59e1ced73474bMathias Agopian * 533e87601170141229d661df93e2f59e1ced73474bMathias Agopian */ 543e87601170141229d661df93e2f59e1ced73474bMathias Agopian 55db89edc94bd2a78226b407f9f7261e202e7fa325Mathias AgopianFramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp, 56db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian const sp<IGraphicBufferConsumer>& consumer) : 57db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian ConsumerBase(consumer), 58f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian mDisplayType(disp), 591a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBufferSlot(-1), 609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mCurrentBuffer(), 619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mCurrentFence(Fence::NO_FENCE), 629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc(hwc), 639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHasPendingRelease(false), 649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mPreviousBufferSlot(BufferQueue::INVALID_BUFFER_SLOT), 659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mPreviousBuffer() 663e87601170141229d661df93e2f59e1ced73474bMathias Agopian{ 679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Creating for display %d", disp); 689d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard 69b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mName = "FramebufferSurface"; 70db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setConsumerName(mName); 71db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB | 72f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian GRALLOC_USAGE_HW_RENDER | 73f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian GRALLOC_USAGE_HW_COMPOSER); 749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc.getActiveConfig(disp); 759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mConsumer->setDefaultBufferSize(activeConfig->getWidth(), 769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza activeConfig->getHeight()); 771971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard mConsumer->setMaxAcquiredBufferCount( 781971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard SurfaceFlinger::maxFrameBufferAcquiredBuffers - 1); 7999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall} 8099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall 812ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Piquevoid FramebufferSurface::resizeBuffers(const uint32_t width, const uint32_t height) { 822ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique mConsumer->setDefaultBufferSize(width, height); 832ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique} 842ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique 857cd85979e81cd632c37852f7ca716089dc52e899Jesse Hallstatus_t FramebufferSurface::beginFrame(bool /*mustRecompose*/) { 86028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall return NO_ERROR; 87028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall} 88028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall 8992dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzynstatus_t FramebufferSurface::prepareFrame(CompositionType /*compositionType*/) { 9038efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall return NO_ERROR; 9138efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall} 9238efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall 9399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hallstatus_t FramebufferSurface::advanceFrame() { 9406d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wu uint32_t slot = 0; 959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<GraphicBuffer> buf; 969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<Fence> acquireFence(Fence::NO_FENCE); 9734beb7a0ff0494b0c5ad81104171f8a49e599163Peiyong Lin Dataspace dataspace = Dataspace::UNKNOWN; 9806d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wu status_t result = nextBuffer(slot, buf, acquireFence, dataspace); 9919987a8cb2ca05e45876946b1eab66cc9d1f9a77Courtney Goeltzenleuchter mDataSpace = dataspace; 1009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (result != NO_ERROR) { 1019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE("error latching next FramebufferSurface buffer: %s (%d)", 1029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza strerror(-result), result); 1039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 1049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza return result; 10599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall} 10699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall 10706d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wustatus_t FramebufferSurface::nextBuffer(uint32_t& outSlot, 10806d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wu sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence, 10934beb7a0ff0494b0c5ad81104171f8a49e599163Peiyong Lin Dataspace& outDataspace) { 1101a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis Mutex::Autolock lock(mMutex); 1113e87601170141229d661df93e2f59e1ced73474bMathias Agopian 11284493cd420d3d53a16ae7c745ed38afffb4e67f5Dan Stoza BufferItem item; 1131585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden status_t err = acquireBufferLocked(&item, 0); 1141a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 115aaff73f92a2fcadda8c765eb9b02f2849418a873Chia-I Wu mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer, 11606d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wu &outSlot, &outBuffer); 1171a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return NO_ERROR; 1181a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } else if (err != NO_ERROR) { 1191a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err); 1201a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis return err; 1211a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 1223e87601170141229d661df93e2f59e1ced73474bMathias Agopian 1231a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // If the BufferQueue has freed and reallocated a buffer in mCurrentSlot 1241a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // then we may have acquired the slot we already own. If we had released 1251a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // our current buffer before we call acquireBuffer then that release call 1261a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // would have returned STALE_BUFFER_SLOT, and we would have called 1271a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // freeBufferLocked on that slot. Because the buffer slot has already 1281a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // been overwritten with the new buffer all we have to do is skip the 1291a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // releaseBuffer call and we should be in the same state we'd be in if we 1301a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis // had released the old buffer first. 1311a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT && 13247650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos item.mSlot != mCurrentBufferSlot) { 1339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHasPendingRelease = true; 1349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mPreviousBufferSlot = mCurrentBufferSlot; 1359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mPreviousBuffer = mCurrentBuffer; 1361a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 13747650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos mCurrentBufferSlot = item.mSlot; 1381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer; 1399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mCurrentFence = item.mFence; 1409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 141da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian outFence = item.mFence; 142aaff73f92a2fcadda8c765eb9b02f2849418a873Chia-I Wu mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer, 14306d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wu &outSlot, &outBuffer); 14434beb7a0ff0494b0c5ad81104171f8a49e599163Peiyong Lin outDataspace = static_cast<Dataspace>(item.mDataSpace); 14579d272442ce13418c3ea81c95d7fea0159b4b481Courtney Goeltzenleuchter status_t result = 14679d272442ce13418c3ea81c95d7fea0159b4b481Courtney Goeltzenleuchter mHwc.setClientTarget(mDisplayType, outSlot, outFence, outBuffer, outDataspace); 14779d272442ce13418c3ea81c95d7fea0159b4b481Courtney Goeltzenleuchter if (result != NO_ERROR) { 14879d272442ce13418c3ea81c95d7fea0159b4b481Courtney Goeltzenleuchter ALOGE("error posting framebuffer: %d", result); 149cd939aa6622430482d2c79bb9deefb67d3ee4611Courtney Goeltzenleuchter return result; 15079d272442ce13418c3ea81c95d7fea0159b4b481Courtney Goeltzenleuchter } 151281e8113d0ce20c702e847caf971663021eb65e3Courtney Goeltzenleuchter 1526461806da8d8f0677ce337700153e5a972c36593Courtney Goeltzenleuchter return NO_ERROR; 1533e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1543e87601170141229d661df93e2f59e1ced73474bMathias Agopian 1551a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisvoid FramebufferSurface::freeBufferLocked(int slotIndex) { 1561a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ConsumerBase::freeBufferLocked(slotIndex); 1571a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (slotIndex == mCurrentBufferSlot) { 1581a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis mCurrentBufferSlot = BufferQueue::INVALID_BUFFER_SLOT; 1591a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis } 1601a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis} 1611a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 162851cfe834295224cd64bdd499872b95b19c4de8cJesse Hallvoid FramebufferSurface::onFrameCommitted() { 1639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (mHasPendingRelease) { 16411d0fc38ad8d2e5bb5bc0a282336cabe28dbf9d6Fabien Sanglard sp<Fence> fence = mHwc.getPresentFence(mDisplayType); 1659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (fence->isValid()) { 1669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza status_t result = addReleaseFence(mPreviousBufferSlot, 1679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mPreviousBuffer, fence); 1689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE_IF(result != NO_ERROR, "onFrameCommitted: failed to add the" 1699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza " fence: %s (%d)", strerror(-result), result); 1709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 1711e24ccebeeb6798afce2730a120abcf9927960faChia-I Wu status_t result = releaseBufferLocked(mPreviousBufferSlot, mPreviousBuffer); 1729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE_IF(result != NO_ERROR, "onFrameCommitted: error releasing buffer:" 1739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza " %s (%d)", strerror(-result), result); 1749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mPreviousBuffer.clear(); 1769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHasPendingRelease = false; 1779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 1789d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard} 1799d96de49673cb6c916bfb797aad4f4e024ea73caFabien Sanglard 180f10c46ef855b6410b20ebd8b1351d4d78d8eca8eDan Stozavoid FramebufferSurface::dumpAsString(String8& result) const { 18119987a8cb2ca05e45876946b1eab66cc9d1f9a77Courtney Goeltzenleuchter Mutex::Autolock lock(mMutex); 1821e04361db1b65d3998edbf820078ccfaed477cb6Chia-I Wu result.appendFormat(" FramebufferSurface: dataspace: %s(%d)\n", 18334beb7a0ff0494b0c5ad81104171f8a49e599163Peiyong Lin dataspaceDetails(static_cast<android_dataspace>(mDataSpace)).c_str(), 18434beb7a0ff0494b0c5ad81104171f8a49e599163Peiyong Lin mDataSpace); 1851e04361db1b65d3998edbf820078ccfaed477cb6Chia-I Wu ConsumerBase::dumpLocked(result, " "); 1863e87601170141229d661df93e2f59e1ced73474bMathias Agopian} 1873e87601170141229d661df93e2f59e1ced73474bMathias Agopian 18874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid FramebufferSurface::dumpLocked(String8& result, const char* prefix) const 1897adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall{ 19074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian ConsumerBase::dumpLocked(result, prefix); 1917adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall} 1927adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall 1939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozaconst sp<Fence>& FramebufferSurface::getClientTargetAcquireFence() const { 1949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza return mCurrentFence; 1959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza} 1969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1973e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 1983e87601170141229d661df93e2f59e1ced73474bMathias Agopian}; // namespace android 1993e87601170141229d661df93e2f59e1ced73474bMathias Agopian// ---------------------------------------------------------------------------- 200