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