1bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden/*
2bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden * Copyright (C) 2012 The Android Open Source Project
3bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden *
4bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden * Licensed under the Apache License, Version 2.0 (the "License");
5bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden * you may not use this file except in compliance with the License.
6bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden * You may obtain a copy of the License at
7bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden *
8bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden *      http://www.apache.org/licenses/LICENSE-2.0
9bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden *
10bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden * Unless required by applicable law or agreed to in writing, software
11bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden * distributed under the License is distributed on an "AS IS" BASIS,
12bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden * See the License for the specific language governing permissions and
14bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden * limitations under the License.
15bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden */
16bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
17bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis//#define LOG_NDEBUG 0
19bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
20bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden#include "SurfaceFlingerConsumer.h"
21bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
22ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h>
23ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
24bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden#include <utils/Errors.h>
25399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall#include <utils/NativeHandle.h>
26399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall#include <utils/Trace.h>
27bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
28bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFaddennamespace android {
29bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
30bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden// ---------------------------------------------------------------------------
31bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
3241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFaddenstatus_t SurfaceFlingerConsumer::updateTexImage(BufferRejecter* rejecter,
3341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        const DispSync& dispSync)
34bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden{
35bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    ATRACE_CALL();
36bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    ALOGV("updateTexImage");
37bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    Mutex::Autolock lock(mMutex);
38bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
39bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mAbandoned) {
402adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        ALOGE("updateTexImage: GLConsumer is abandoned!");
41bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        return NO_INIT;
42bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    }
43bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
44bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Make sure the EGL state is the same as in previous calls.
45bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = checkAndUpdateEglStateLocked();
46bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
47bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        return err;
48bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    }
49bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
50bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    BufferQueue::BufferItem item;
51bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
52bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Acquire the next buffer.
53bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // In asynchronous mode the list is guaranteed to be one buffer
54bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // deep, while in synchronous mode we use the oldest buffer.
5541d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    err = acquireBufferLocked(&item, computeExpectedPresent(dispSync));
56bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
57bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
58bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden            err = NO_ERROR;
591585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        } else if (err == BufferQueue::PRESENT_LATER) {
601585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // return the error, without logging
61bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        } else {
62bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden            ALOGE("updateTexImage: acquire failed: %s (%d)",
63bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden                strerror(-err), err);
64bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        }
65bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        return err;
66bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    }
67bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
68bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
69bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // We call the rejecter here, in case the caller has a reason to
70bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // not accept this buffer.  This is used by SurfaceFlinger to
71bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // reject buffers which have the wrong size
72bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    int buf = item.mBuf;
73bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (rejecter && rejecter->reject(mSlots[buf].mGraphicBuffer, item)) {
7498d3d6ec1250248574f2e8d72e5c934fecbcd734Lajos Molnar        releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, EGL_NO_SYNC_KHR);
75bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        return NO_ERROR;
76bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    }
77bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
78bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Release the previous buffer.
79ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian    err = updateAndReleaseLocked(item);
80bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
81bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        return err;
82bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    }
83bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
84ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    if (!SyncFeatures::getInstance().useNativeFenceSync()) {
8597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        // Bind the new buffer to the GL texture.
8697eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        //
8797eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        // Older devices require the "implicit" synchronization provided
8897eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        // by glEGLImageTargetTexture2DOES, which this method calls.  Newer
8997eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        // devices will either call this in Layer::onDraw, or (if it's not
9097eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        // a GL-composited layer) not at all.
9197eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        err = bindTextureImageLocked();
9297eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    }
9397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden
9497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    return err;
9597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden}
9697eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden
9797eba8904c2f221c42a9473407223a4c3a213f75Andy McFaddenstatus_t SurfaceFlingerConsumer::bindTextureImage()
9897eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden{
9997eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    Mutex::Autolock lock(mMutex);
10097eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden
10197eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    return bindTextureImageLocked();
102bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden}
103bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
104c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopianstatus_t SurfaceFlingerConsumer::acquireBufferLocked(
105c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        BufferQueue::BufferItem *item, nsecs_t presentWhen) {
106c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    status_t result = GLConsumer::acquireBufferLocked(item, presentWhen);
107c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (result == NO_ERROR) {
108c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        mTransformToDisplayInverse = item->mTransformToDisplayInverse;
109c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
110c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    return result;
111c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian}
112c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
113c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopianbool SurfaceFlingerConsumer::getTransformToDisplayInverse() const {
114c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    return mTransformToDisplayInverse;
115c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian}
116c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
117399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallsp<NativeHandle> SurfaceFlingerConsumer::getSidebandStream() const {
118399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    return mConsumer->getSidebandStream();
119399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
120399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
1211585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden// We need to determine the time when a buffer acquired now will be
1221585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden// displayed.  This can be calculated:
1231585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden//   time when previous buffer's actual-present fence was signaled
1241585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden//    + current display refresh rate * HWC latency
1251585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden//    + a little extra padding
1261585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden//
1271585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden// Buffer producers are expected to set their desired presentation time
1281585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden// based on choreographer time stamps, which (coming from vsync events)
1291585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden// will be slightly later then the actual-present timing.  If we get a
1301585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden// desired-present time that is unintentionally a hair after the next
1311585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden// vsync, we'll hold the frame when we really want to display it.  We
13241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden// need to take the offset between actual-present and reported-vsync
13341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden// into account.
13441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden//
13541d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden// If the system is configured without a DispSync phase offset for the app,
13641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden// we also want to throw in a bit of padding to avoid edge cases where we
13741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden// just barely miss.  We want to do it here, not in every app.  A major
13841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden// source of trouble is the app's use of the display's ideal refresh time
13941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden// (via Display.getRefreshRate()), which could be off of the actual refresh
14041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden// by a few percent, with the error multiplied by the number of frames
14141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden// between now and when the buffer should be displayed.
14241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden//
14341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden// If the refresh reported to the app has a phase offset, we shouldn't need
14441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden// to tweak anything here.
14541d67d7ab4da1c393497a620a116a854b3c618e7Andy McFaddennsecs_t SurfaceFlingerConsumer::computeExpectedPresent(const DispSync& dispSync)
1461585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden{
1471585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden    // The HWC doesn't currently have a way to report additional latency.
14841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    // Assume that whatever we submit now will appear right after the flip.
14941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    // For a smart panel this might be 1.  This is expressed in frames,
15041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    // rather than time, because we expect to have a constant frame delay
15141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    // regardless of the refresh rate.
15241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    const uint32_t hwcLatency = 0;
15341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
15441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    // Ask DispSync when the next refresh will be (CLOCK_MONOTONIC).
15541d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    const nsecs_t nextRefresh = dispSync.computeNextRefresh(hwcLatency);
15641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
15741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    // The DispSync time is already adjusted for the difference between
15841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    // vsync and reported-vsync (PRESENT_TIME_OFFSET_FROM_VSYNC_NS), so
15941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    // we don't need to factor that in here.  Pad a little to avoid
16041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    // weird effects if apps might be requesting times right on the edge.
16141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    nsecs_t extraPadding = 0;
16241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    if (VSYNC_EVENT_PHASE_OFFSET_NS == 0) {
16341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        extraPadding = 1000000;        // 1ms (6% of 60Hz)
16441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    }
1651585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
16641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    return nextRefresh + extraPadding;
1671585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden}
1681585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
169399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid SurfaceFlingerConsumer::setContentsChangedListener(
170399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        const wp<ContentsChangedListener>& listener) {
171399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    setFrameAvailableListener(listener);
172399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    Mutex::Autolock lock(mMutex);
173399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mContentsChangedListener = listener;
174399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
175399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
176399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid SurfaceFlingerConsumer::onSidebandStreamChanged() {
177399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    sp<ContentsChangedListener> listener;
178399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    {   // scope for the lock
179399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        Mutex::Autolock lock(mMutex);
180399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        ALOG_ASSERT(mFrameAvailableListener.unsafe_get() == mContentsChangedListener.unsafe_get());
181399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        listener = mContentsChangedListener.promote();
182399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
183399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
184399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (listener != NULL) {
185399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        listener->onSidebandStreamChanged();
186399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
187399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
188399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
189bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden// ---------------------------------------------------------------------------
190bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden}; // namespace android
191bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden
192