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