blob: c8bb068fa90f6823976c1d99da6a8753316e5803 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
Melody Hsue4ef87f2024-03-26 23:54:45 +000018
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080019#pragma clang diagnostic push
20#pragma clang diagnostic ignored "-Wconversion"
21
Dan Stoza9e56aa02015-11-02 13:00:03 -080022//#define LOG_NDEBUG 0
23#undef LOG_TAG
24#define LOG_TAG "Layer"
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080025#define ATRACE_TAG ATRACE_TAG_GRAPHICS
26
[1;3C2b9fc252021-02-04 16:16:50 -080027#include <android-base/properties.h>
Yiwei Zhang5434a782018-12-05 18:06:32 -080028#include <android-base/stringprintf.h>
Vishnu Nair0f085c62019-08-30 08:49:12 -070029#include <binder/IPCThreadState.h>
Vishnu Nairbe0ad902024-06-27 23:38:43 +000030#include <common/trace.h>
Patrick Williamsbb25f802022-08-30 23:02:34 +000031#include <compositionengine/CompositionEngine.h>
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080032#include <compositionengine/Display.h>
Lloyd Piquea83776c2019-01-29 18:42:32 -080033#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080034#include <compositionengine/OutputLayer.h>
35#include <compositionengine/impl/OutputLayerCompositionState.h>
Mathias Agopiana67932f2011-04-20 14:20:59 -070036#include <cutils/compiler.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070037#include <cutils/native_handle.h>
Mathias Agopiana67932f2011-04-20 14:20:59 -070038#include <cutils/properties.h>
Dominik Laskowskif5d0ea52021-09-26 17:27:01 -070039#include <ftl/enum.h>
Dominik Laskowski298b08e2022-02-15 13:45:02 -080040#include <ftl/fake_guard.h>
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080041#include <gui/BufferItem.h>
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080042#include <gui/Surface.h>
Alec Mourie60041e2019-06-14 18:59:51 -070043#include <math.h>
chaviw250bcbb2020-08-05 11:17:54 -070044#include <private/android_filesystem_config.h>
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080045#include <renderengine/RenderEngine.h>
Alec Mourie60041e2019-06-14 18:59:51 -070046#include <stdint.h>
47#include <stdlib.h>
48#include <sys/types.h>
Alec Mouridda07d92022-04-25 22:39:25 +000049#include <system/graphics-base-v1.0.h>
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080050#include <ui/DebugUtils.h>
Vishnu Nairfed7c122023-03-18 01:54:43 +000051#include <ui/FloatRect.h>
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080052#include <ui/GraphicBuffer.h>
Sally Qif6918d42023-08-07 15:28:30 -070053#include <ui/HdrRenderTypeUtils.h>
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080054#include <ui/PixelFormat.h>
Vishnu Nairfed7c122023-03-18 01:54:43 +000055#include <ui/Rect.h>
56#include <ui/Transform.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080057#include <utils/Errors.h>
58#include <utils/Log.h>
Jesse Hall399184a2014-03-03 15:42:54 -080059#include <utils/NativeHandle.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080060#include <utils/StopWatch.h>
61
Alec Mourie60041e2019-06-14 18:59:51 -070062#include <algorithm>
Vishnu Nair71fcf912022-10-18 09:14:20 -070063#include <optional>
Alec Mourie60041e2019-06-14 18:59:51 -070064
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070065#include "DisplayDevice.h"
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080066#include "DisplayHardware/HWComposer.h"
Ady Abraham22c7b5c2020-09-22 19:33:40 -070067#include "FrameTimeline.h"
Mikael Pessa90092f42019-08-26 17:22:04 -070068#include "FrameTracer/FrameTracer.h"
Vishnu Naircb8be502022-10-12 19:03:23 +000069#include "FrontEnd/LayerCreationArgs.h"
Vishnu Nair07e2a482022-10-18 19:18:16 +000070#include "FrontEnd/LayerHandle.h"
Melody Hsue4ef87f2024-03-26 23:54:45 +000071#include "Layer.h"
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080072#include "LayerProtoHelper.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080073#include "SurfaceFlinger.h"
Yiwei Zhang7e666a52018-11-15 13:33:42 -080074#include "TimeStats/TimeStats.h"
Melody Hsue4ef87f2024-03-26 23:54:45 +000075#include "TransactionCallbackInvoker.h"
Robert Carr3e2a2992021-06-11 13:42:55 -070076#include "TunnelModeEnabledReporter.h"
Alec Mouri9892aac2023-12-11 21:16:59 +000077#include "Utils/FenceUtils.h"
Mathias Agopian1b031492012-06-20 17:51:20 -070078
David Sodman41fdfc92017-11-06 16:09:56 -080079#define DEBUG_RESIZE 0
Patrick Williamsbb25f802022-08-30 23:02:34 +000080#define EARLY_RELEASE_ENABLED false
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080081
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080082namespace android {
Alec Mouri9892aac2023-12-11 21:16:59 +000083using namespace std::chrono_literals;
Marin Shalamanov1876e2e2020-12-04 13:23:59 +010084namespace {
85constexpr int kDumpTableRowLength = 159;
Patrick Williamsbb25f802022-08-30 23:02:34 +000086
Prabir Pradhanda0f62c2022-07-22 19:53:04 +000087const ui::Transform kIdentityTransform;
Patrick Williamsbb25f802022-08-30 23:02:34 +000088
Patrick Williamsbb25f802022-08-30 23:02:34 +000089TimeStats::SetFrameRateVote frameRateToSetFrameRateVotePayload(Layer::FrameRate frameRate) {
90 using FrameRateCompatibility = TimeStats::SetFrameRateVote::FrameRateCompatibility;
91 using Seamlessness = TimeStats::SetFrameRateVote::Seamlessness;
92 const auto frameRateCompatibility = [frameRate] {
Rachel Leece6e0042023-06-27 11:22:54 -070093 switch (frameRate.vote.type) {
Patrick Williamsbb25f802022-08-30 23:02:34 +000094 case Layer::FrameRateCompatibility::Default:
95 return FrameRateCompatibility::Default;
96 case Layer::FrameRateCompatibility::ExactOrMultiple:
97 return FrameRateCompatibility::ExactOrMultiple;
98 default:
99 return FrameRateCompatibility::Undefined;
100 }
101 }();
102
103 const auto seamlessness = [frameRate] {
Rachel Leece6e0042023-06-27 11:22:54 -0700104 switch (frameRate.vote.seamlessness) {
Patrick Williamsbb25f802022-08-30 23:02:34 +0000105 case scheduler::Seamlessness::OnlySeamless:
106 return Seamlessness::ShouldBeSeamless;
107 case scheduler::Seamlessness::SeamedAndSeamless:
108 return Seamlessness::NotRequired;
109 default:
110 return Seamlessness::Undefined;
111 }
112 }();
113
Rachel Leece6e0042023-06-27 11:22:54 -0700114 return TimeStats::SetFrameRateVote{.frameRate = frameRate.vote.rate.getValue(),
Patrick Williamsbb25f802022-08-30 23:02:34 +0000115 .frameRateCompatibility = frameRateCompatibility,
116 .seamlessness = seamlessness};
117}
118
Marin Shalamanov1876e2e2020-12-04 13:23:59 +0100119} // namespace
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800120
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700121using namespace ftl::flag_operators;
122
Yiwei Zhang5434a782018-12-05 18:06:32 -0800123using base::StringAppendF;
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000124using frontend::LayerSnapshot;
125using frontend::RoundedCornerState;
Huihong Luod3d8f8e2022-03-08 14:48:46 -0800126using gui::GameMode;
127using gui::LayerMetadata;
chaviw3277faf2021-05-19 16:45:23 -0500128using gui::WindowInfo;
Vishnu Nair494a2e42023-11-10 17:21:19 -0800129using ui::Size;
Yiwei Zhang5434a782018-12-05 18:06:32 -0800130
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700131using PresentState = frametimeline::SurfaceFrame::PresentState;
132
Kean Mariotti4ba343c2023-04-19 13:31:02 +0000133Layer::Layer(const surfaceflinger::LayerCreationArgs& args)
Vishnu Naircb8be502022-10-12 19:03:23 +0000134 : sequence(args.sequence),
Ady Abrahamd11bade2022-08-01 16:18:03 -0700135 mFlinger(sp<SurfaceFlinger>::fromExisting(args.flinger)),
Arthur Hung23e07502021-10-15 11:58:19 +0000136 mName(base::StringPrintf("%s#%d", args.name.c_str(), sequence)),
Huihong Luod3d8f8e2022-03-08 14:48:46 -0800137 mWindowType(static_cast<WindowInfo::Type>(
Vishnu Nairdc83d4b2024-08-15 16:29:20 +0000138 args.metadata.getInt32(gui::METADATA_WINDOW_TYPE, 0))) {
Patrick Williamsbb25f802022-08-30 23:02:34 +0000139 ALOGV("Creating Layer %s", getDebugName());
140
Robert Carr6a160312021-05-17 12:08:20 -0700141 mDrawingState.crop.makeInvalid();
Robert Carr6a160312021-05-17 12:08:20 -0700142 mDrawingState.sequence = 0;
Robert Carr6a160312021-05-17 12:08:20 -0700143 mDrawingState.transform.set(0, 0);
144 mDrawingState.frameNumber = 0;
Alec Mouri21d94322023-10-17 19:51:39 +0000145 mDrawingState.previousFrameNumber = 0;
Vishnu Nair63221212023-04-06 15:17:37 -0700146 mDrawingState.barrierFrameNumber = 0;
147 mDrawingState.producerId = 0;
148 mDrawingState.barrierProducerId = 0;
Robert Carr6a160312021-05-17 12:08:20 -0700149 mDrawingState.bufferTransform = 0;
150 mDrawingState.transformToDisplayInverse = false;
Robert Carr6a160312021-05-17 12:08:20 -0700151 mDrawingState.acquireFence = sp<Fence>::make(-1);
152 mDrawingState.acquireFenceTime = std::make_shared<FenceTime>(mDrawingState.acquireFence);
Alec Mouri74c7ae12023-03-26 02:57:47 +0000153 mDrawingState.dataspace = ui::Dataspace::V0_SRGB;
Robert Carr6a160312021-05-17 12:08:20 -0700154 mDrawingState.metadata = args.metadata;
Robert Carr6a160312021-05-17 12:08:20 -0700155 mDrawingState.frameTimelineInfo = {};
156 mDrawingState.postTime = -1;
Leon Scroggins III1af0fb62023-03-02 14:21:44 -0500157 mFrameTracker.setDisplayRefreshPeriod(
158 args.flinger->mScheduler->getPacesetterVsyncPeriod().ns());
Robert Carr2e102c92018-10-23 12:11:15 -0700159
Vishnu Naircb8be502022-10-12 19:03:23 +0000160 mOwnerUid = args.ownerUid;
161 mOwnerPid = args.ownerPid;
Tony Huangf3621102023-09-04 17:14:22 +0800162 mOwnerAppId = mOwnerUid % PER_USER_RANGE;
Patrick Williamsbb25f802022-08-30 23:02:34 +0000163
Patrick Williamsbb25f802022-08-30 23:02:34 +0000164 mPotentialCursor = args.flags & ISurfaceComposerClient::eCursorWindow;
Vishnu Nairdc83d4b2024-08-15 16:29:20 +0000165 mLayerFEs.emplace_back(frontend::LayerHierarchy::TraversalPath{static_cast<uint32_t>(sequence)},
166 args.flinger->getFactory().createLayerFE(mName, this));
Dominik Laskowski75848362019-11-11 17:57:20 -0800167}
168
169void Layer::onFirstRef() {
170 mFlinger->onLayerFirstRef(this);
Dan Stoza436ccf32018-06-21 12:10:12 -0700171}
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700172
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700173Layer::~Layer() {
Patrick Williams70093fd2022-12-12 16:51:52 +0000174 LOG_ALWAYS_FATAL_IF(std::this_thread::get_id() != mFlinger->mMainThreadId,
175 "Layer destructor called off the main thread.");
176
Patrick Williamsbb25f802022-08-30 23:02:34 +0000177 if (mBufferInfo.mBuffer != nullptr) {
178 callReleaseBufferCallback(mDrawingState.releaseBufferListener,
179 mBufferInfo.mBuffer->getBuffer(), mBufferInfo.mFrameNumber,
liulijuneb489f62022-10-17 22:02:14 +0800180 mBufferInfo.mFence);
Patrick Williamsbb25f802022-08-30 23:02:34 +0000181 }
Patrick Williamsbb25f802022-08-30 23:02:34 +0000182 const int32_t layerId = getSequence();
183 mFlinger->mTimeStats->onDestroy(layerId);
184 mFlinger->mFrameTracer->onDestroy(layerId);
185
Jorim Jaggi10c985e2018-10-23 11:17:45 +0000186 mFrameTracker.logAndResetStats(mName);
chaviw74d90ad2019-04-26 14:45:26 -0700187 mFlinger->onLayerDestroyed(this);
Robert Carr3e2a2992021-06-11 13:42:55 -0700188
189 if (mDrawingState.sidebandStream != nullptr) {
190 mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount();
191 }
Chavi Weingarten076acac2023-01-19 17:20:43 +0000192 if (hasTrustedPresentationListener()) {
193 mFlinger->mNumTrustedPresentationListeners--;
Vishnu Nair781d7252023-01-30 18:16:01 +0000194 updateTrustedPresentationState(nullptr, nullptr, -1 /* time_in_ms */, true /* leaveState*/);
Chavi Weingarten076acac2023-01-19 17:20:43 +0000195 }
Mathias Agopian96f08192010-06-02 23:28:45 -0700196}
197
Mathias Agopian13127d82013-03-05 17:47:11 -0800198// ---------------------------------------------------------------------------
Mathias Agopian13127d82013-03-05 17:47:11 -0800199// set-up
200// ---------------------------------------------------------------------------
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700201sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800202 Mutex::Autolock _l(mLock);
Robert Carrc0df3122019-04-11 13:18:21 -0700203 if (mGetHandleCalled) {
204 ALOGE("Get handle called twice" );
205 return nullptr;
206 }
207 mGetHandleCalled = true;
Vishnu Nair787aa782023-03-17 13:46:46 -0700208 mHandleAlive = true;
Vishnu Nair07e2a482022-10-18 19:18:16 +0000209 return sp<LayerHandle>::make(mFlinger, sp<Layer>::fromExisting(this));
Mathias Agopian13127d82013-03-05 17:47:11 -0800210}
211
212// ---------------------------------------------------------------------------
213// h/w composer set-up
214// ---------------------------------------------------------------------------
215
Chavi Weingarten076acac2023-01-19 17:20:43 +0000216// No early returns.
Vishnu Nair781d7252023-01-30 18:16:01 +0000217void Layer::updateTrustedPresentationState(const DisplayDevice* display,
218 const frontend::LayerSnapshot* snapshot,
219 int64_t time_in_ms, bool leaveState) {
Chavi Weingarten076acac2023-01-19 17:20:43 +0000220 if (!hasTrustedPresentationListener()) {
221 return;
222 }
223 const bool lastState = mLastComputedTrustedPresentationState;
224 mLastComputedTrustedPresentationState = false;
225
226 if (!leaveState) {
Vishnu Nair3cc15a42023-06-30 06:20:22 +0000227 const auto outputLayer = findOutputLayerForDisplay(display, snapshot->path);
Chavi Weingarten545da0e2023-02-09 14:55:57 +0000228 if (outputLayer != nullptr) {
229 if (outputLayer->getState().coveredRegionExcludingDisplayOverlays) {
230 Region coveredRegion =
231 *outputLayer->getState().coveredRegionExcludingDisplayOverlays;
232 mLastComputedTrustedPresentationState =
233 computeTrustedPresentationState(snapshot->geomLayerBounds,
234 snapshot->sourceBounds(), coveredRegion,
235 snapshot->transformedBounds,
236 snapshot->alpha,
237 snapshot->geomLayerTransform,
238 mTrustedPresentationThresholds);
239 } else {
240 ALOGE("CoveredRegionExcludingDisplayOverlays was not set for %s. Don't compute "
241 "TrustedPresentationState",
242 getDebugName());
243 }
Chavi Weingarten076acac2023-01-19 17:20:43 +0000244 }
245 }
246 const bool newState = mLastComputedTrustedPresentationState;
247 if (lastState && !newState) {
248 // We were in the trusted presentation state, but now we left it,
249 // emit the callback if needed
250 if (mLastReportedTrustedPresentationState) {
251 mLastReportedTrustedPresentationState = false;
252 mTrustedPresentationListener.invoke(false);
253 }
254 // Reset the timer
255 mEnteredTrustedPresentationStateTime = -1;
256 } else if (!lastState && newState) {
257 // We were not in the trusted presentation state, but we entered it, begin the timer
258 // and make sure this gets called at least once more!
259 mEnteredTrustedPresentationStateTime = time_in_ms;
260 mFlinger->forceFutureUpdate(mTrustedPresentationThresholds.stabilityRequirementMs * 1.5);
261 }
262
263 // Has the timer elapsed, but we are still in the state? Emit a callback if needed
264 if (!mLastReportedTrustedPresentationState && newState &&
265 (time_in_ms - mEnteredTrustedPresentationStateTime >
266 mTrustedPresentationThresholds.stabilityRequirementMs)) {
267 mLastReportedTrustedPresentationState = true;
268 mTrustedPresentationListener.invoke(true);
269 }
270}
271
272/**
273 * See SurfaceComposerClient.h: setTrustedPresentationCallback for discussion
274 * of how the parameters and thresholds are interpreted. The general spirit is
275 * to produce an upper bound on the amount of the buffer which was presented.
276 */
277bool Layer::computeTrustedPresentationState(const FloatRect& bounds, const FloatRect& sourceBounds,
278 const Region& coveredRegion,
279 const FloatRect& screenBounds, float alpha,
280 const ui::Transform& effectiveTransform,
281 const TrustedPresentationThresholds& thresholds) {
282 if (alpha < thresholds.minAlpha) {
283 return false;
284 }
285 if (sourceBounds.getWidth() == 0 || sourceBounds.getHeight() == 0) {
286 return false;
287 }
288 if (screenBounds.getWidth() == 0 || screenBounds.getHeight() == 0) {
289 return false;
290 }
291
292 const float sx = effectiveTransform.dsdx();
293 const float sy = effectiveTransform.dsdy();
294 float fractionRendered = std::min(sx * sy, 1.0f);
295
296 float boundsOverSourceW = bounds.getWidth() / (float)sourceBounds.getWidth();
297 float boundsOverSourceH = bounds.getHeight() / (float)sourceBounds.getHeight();
298 fractionRendered *= boundsOverSourceW * boundsOverSourceH;
299
Chavi Weingarten545da0e2023-02-09 14:55:57 +0000300 Region tJunctionFreeRegion = Region::createTJunctionFreeRegion(coveredRegion);
301 // Compute the size of all the rects since they may be disconnected.
302 float coveredSize = 0;
303 for (auto rect = tJunctionFreeRegion.begin(); rect < tJunctionFreeRegion.end(); rect++) {
304 float size = rect->width() * rect->height();
305 coveredSize += size;
306 }
307
308 fractionRendered *= (1 - (coveredSize / (screenBounds.getWidth() * screenBounds.getHeight())));
Chavi Weingarten076acac2023-01-19 17:20:43 +0000309
310 if (fractionRendered < thresholds.minFractionRendered) {
311 return false;
312 }
313
314 return true;
315}
316
Vishnu Nair60356342018-11-13 13:00:45 -0800317Rect Layer::getCroppedBufferSize(const State& s) const {
318 Rect size = getBufferSize(s);
319 Rect crop = getCrop(s);
320 if (!crop.isEmpty() && size.isValid()) {
321 size.intersect(crop, &size);
322 } else if (!crop.isEmpty()) {
323 size = crop;
Robert Carr1f0a16a2016-10-24 16:27:39 -0700324 }
Vishnu Nair60356342018-11-13 13:00:45 -0800325 return size;
Mathias Agopian13127d82013-03-05 17:47:11 -0800326}
327
Lloyd Piquea83776c2019-01-29 18:42:32 -0800328const char* Layer::getDebugName() const {
Dominik Laskowski87a07e42019-10-10 20:38:02 -0700329 return mName.c_str();
David Sodman4b7c4bc2017-11-17 12:13:59 -0800330}
331
Mathias Agopian13127d82013-03-05 17:47:11 -0800332// ---------------------------------------------------------------------------
333// drawing...
334// ---------------------------------------------------------------------------
335
Leon Scroggins III2e1aa182021-12-01 17:33:12 -0500336aidl::android::hardware::graphics::composer3::Composition Layer::getCompositionType(
337 const DisplayDevice& display) const {
Dominik Laskowskib7251f42020-04-20 17:42:59 -0700338 const auto outputLayer = findOutputLayerForDisplay(&display);
Vishnu Nair3cc15a42023-06-30 06:20:22 +0000339 return getCompositionType(outputLayer);
340}
341
342aidl::android::hardware::graphics::composer3::Composition Layer::getCompositionType(
343 const compositionengine::OutputLayer* outputLayer) const {
Alec Mouri6b9e9912020-01-21 10:50:24 -0800344 if (outputLayer == nullptr) {
Leon Scroggins III2e1aa182021-12-01 17:33:12 -0500345 return aidl::android::hardware::graphics::composer3::Composition::INVALID;
Alec Mouri6b9e9912020-01-21 10:50:24 -0800346 }
347 if (outputLayer->getState().hwc) {
348 return (*outputLayer->getState().hwc).hwcCompositionType;
349 } else {
Leon Scroggins III2e1aa182021-12-01 17:33:12 -0500350 return aidl::android::hardware::graphics::composer3::Composition::CLIENT;
Alec Mouri6b9e9912020-01-21 10:50:24 -0800351 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800352}
353
Mathias Agopian13127d82013-03-05 17:47:11 -0800354// ----------------------------------------------------------------------------
Mathias Agopian13127d82013-03-05 17:47:11 -0800355// transaction
356// ----------------------------------------------------------------------------
Ady Abraham83729882018-12-07 12:26:48 -0800357
Vishnu Naira156f482023-02-22 00:23:38 +0000358uint32_t Layer::doTransaction(uint32_t flags) {
Vishnu Nairbe0ad902024-06-27 23:38:43 +0000359 SFTRACE_CALL();
Marissa Wall61c58622018-07-18 10:12:20 -0700360
Alec Mourib416efd2018-09-06 21:01:59 +0000361 const State& s(getDrawingState());
Marissa Wall61c58622018-07-18 10:12:20 -0700362
Robert Carr6a160312021-05-17 12:08:20 -0700363 if (s.sequence != mLastCommittedTxSequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800364 // invalidate and recompute the visible regions if needed
Arthur Hung9ed43392022-05-27 06:31:57 +0000365 mLastCommittedTxSequence = s.sequence;
Mathias Agopian13127d82013-03-05 17:47:11 -0800366 flags |= eVisibleRegion;
Mathias Agopian13127d82013-03-05 17:47:11 -0800367 }
368
Arthur Hung9ed43392022-05-27 06:31:57 +0000369 if (!mPotentialCursor && (flags & Layer::eVisibleRegion)) {
370 mFlinger->mUpdateInputInfo = true;
371 }
372
Vishnu Nairc1d19d72023-08-10 12:35:11 -0700373 commitTransaction();
Robert Carra1257842020-01-31 13:48:28 -0800374
Mathias Agopian13127d82013-03-05 17:47:11 -0800375 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800376}
377
Vishnu Nairc1d19d72023-08-10 12:35:11 -0700378void Layer::commitTransaction() {
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000379 // Set the present state for all bufferlessSurfaceFramesTX to Presented. The
380 // bufferSurfaceFrameTX will be presented in latchBuffer.
381 for (auto& [token, surfaceFrame] : mDrawingState.bufferlessSurfaceFramesTX) {
382 if (surfaceFrame->getPresentState() != PresentState::Presented) {
383 // With applyPendingStates, we could end up having presented surfaceframes from previous
384 // states
Vishnu Nair7fe69ed2023-02-13 10:13:26 -0800385 surfaceFrame->setPresentState(PresentState::Presented, mLastLatchTime);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000386 mFlinger->mFrameTimeline->addSurfaceFrame(surfaceFrame);
387 }
388 }
Robert Carr6a160312021-05-17 12:08:20 -0700389 mDrawingState.bufferlessSurfaceFramesTX.clear();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700390}
391
Dominik Laskowski9e168db2021-05-27 16:05:12 -0700392uint32_t Layer::clearTransactionFlags(uint32_t mask) {
393 const auto flags = mTransactionFlags & mask;
394 mTransactionFlags &= ~mask;
395 return flags;
Mathias Agopian13127d82013-03-05 17:47:11 -0800396}
397
Dominik Laskowski9e168db2021-05-27 16:05:12 -0700398void Layer::setTransactionFlags(uint32_t mask) {
399 mTransactionFlags |= mask;
Mathias Agopian13127d82013-03-05 17:47:11 -0800400}
401
chaviw25714502021-02-11 10:01:08 -0800402bool Layer::setCrop(const Rect& crop) {
Vishnu Nairea04b6f2022-08-19 21:28:17 +0000403 if (mDrawingState.crop == crop) return false;
Robert Carr6a160312021-05-17 12:08:20 -0700404 mDrawingState.sequence++;
Robert Carr6a160312021-05-17 12:08:20 -0700405 mDrawingState.crop = crop;
Robert Carr7bf247e2017-05-18 14:02:49 -0700406
Sally Qi81d95e62022-03-21 19:41:33 -0700407 setTransactionFlags(eTransactionNeeded);
408 return true;
409}
410
Ady Abrahamaae5ed52020-06-26 09:32:43 -0700411bool Layer::isLayerFocusedBasedOnPriority(int32_t priority) {
412 return priority == PRIORITY_FOCUSED_WITH_MODE || priority == PRIORITY_FOCUSED_WITHOUT_MODE;
413};
414
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000415void Layer::setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info,
Vishnu Nair39a74a92024-07-29 19:01:50 +0000416 nsecs_t postTime, gui::GameMode gameMode) {
Robert Carr6a160312021-05-17 12:08:20 -0700417 mDrawingState.postTime = postTime;
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000418
419 // Check if one of the bufferlessSurfaceFramesTX contains the same vsyncId. This can happen if
420 // there are two transactions with the same token, the first one without a buffer and the
421 // second one with a buffer. We promote the bufferlessSurfaceFrame to a bufferSurfaceFrameTX
422 // in that case.
Robert Carr6a160312021-05-17 12:08:20 -0700423 auto it = mDrawingState.bufferlessSurfaceFramesTX.find(info.vsyncId);
424 if (it != mDrawingState.bufferlessSurfaceFramesTX.end()) {
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000425 // Promote the bufferlessSurfaceFrame to a bufferSurfaceFrameTX
Robert Carr6a160312021-05-17 12:08:20 -0700426 mDrawingState.bufferSurfaceFrameTX = it->second;
427 mDrawingState.bufferlessSurfaceFramesTX.erase(it);
428 mDrawingState.bufferSurfaceFrameTX->promoteToBuffer();
429 mDrawingState.bufferSurfaceFrameTX->setActualQueueTime(postTime);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000430 } else {
Robert Carr6a160312021-05-17 12:08:20 -0700431 mDrawingState.bufferSurfaceFrameTX =
Vishnu Nair39a74a92024-07-29 19:01:50 +0000432 createSurfaceFrameForBuffer(info, postTime, mTransactionName, gameMode);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000433 }
Ady Abraham5a3e3562023-06-07 10:32:08 -0700434
Vishnu Nair39a74a92024-07-29 19:01:50 +0000435 setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName, gameMode);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000436}
437
438void Layer::setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo& info,
Vishnu Nair39a74a92024-07-29 19:01:50 +0000439 nsecs_t postTime,
440 gui::GameMode gameMode) {
Robert Carr6a160312021-05-17 12:08:20 -0700441 mDrawingState.frameTimelineInfo = info;
442 mDrawingState.postTime = postTime;
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700443 setTransactionFlags(eTransactionNeeded);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000444
Robert Carr6a160312021-05-17 12:08:20 -0700445 if (const auto& bufferSurfaceFrameTX = mDrawingState.bufferSurfaceFrameTX;
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000446 bufferSurfaceFrameTX != nullptr) {
447 if (bufferSurfaceFrameTX->getToken() == info.vsyncId) {
448 // BufferSurfaceFrame takes precedence over BufferlessSurfaceFrame. If the same token is
449 // being used for BufferSurfaceFrame, don't create a new one.
450 return;
451 }
452 }
453 // For Transactions without a buffer, we create only one SurfaceFrame per vsyncId. If multiple
454 // transactions use the same vsyncId, we just treat them as one SurfaceFrame (unless they are
455 // targeting different vsyncs).
Robert Carr6a160312021-05-17 12:08:20 -0700456 auto it = mDrawingState.bufferlessSurfaceFramesTX.find(info.vsyncId);
457 if (it == mDrawingState.bufferlessSurfaceFramesTX.end()) {
Vishnu Nair39a74a92024-07-29 19:01:50 +0000458 auto surfaceFrame = createSurfaceFrameForTransaction(info, postTime, gameMode);
Robert Carr6a160312021-05-17 12:08:20 -0700459 mDrawingState.bufferlessSurfaceFramesTX[info.vsyncId] = surfaceFrame;
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000460 } else {
461 if (it->second->getPresentState() == PresentState::Presented) {
462 // If the SurfaceFrame was already presented, its safe to overwrite it since it must
463 // have been from previous vsync.
Vishnu Nair39a74a92024-07-29 19:01:50 +0000464 it->second = createSurfaceFrameForTransaction(info, postTime, gameMode);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000465 }
466 }
Ady Abraham5a3e3562023-06-07 10:32:08 -0700467
Vishnu Nair39a74a92024-07-29 19:01:50 +0000468 setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName, gameMode);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000469}
470
471void Layer::addSurfaceFrameDroppedForBuffer(
Ady Abraham5a3e3562023-06-07 10:32:08 -0700472 std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame, nsecs_t dropTime) {
473 surfaceFrame->setDropTime(dropTime);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000474 surfaceFrame->setPresentState(PresentState::Dropped);
475 mFlinger->mFrameTimeline->addSurfaceFrame(surfaceFrame);
476}
477
478void Layer::addSurfaceFramePresentedForBuffer(
479 std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame, nsecs_t acquireFenceTime,
480 nsecs_t currentLatchTime) {
481 surfaceFrame->setAcquireFenceTime(acquireFenceTime);
482 surfaceFrame->setPresentState(PresentState::Presented, mLastLatchTime);
483 mFlinger->mFrameTimeline->addSurfaceFrame(surfaceFrame);
Vishnu Naira156f482023-02-22 00:23:38 +0000484 updateLastLatchTime(currentLatchTime);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000485}
486
487std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForTransaction(
Vishnu Nair39a74a92024-07-29 19:01:50 +0000488 const FrameTimelineInfo& info, nsecs_t postTime, gui::GameMode gameMode) {
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000489 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800490 mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid,
491 getSequence(), mName,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000492 mTransactionName,
Vishnu Nair39a74a92024-07-29 19:01:50 +0000493 /*isBuffer*/ false, gameMode);
Rachel Leeed511ef2021-10-11 15:09:51 -0700494 surfaceFrame->setActualStartTime(info.startTimeNanos);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000495 // For Transactions, the post time is considered to be both queue and acquire fence time.
496 surfaceFrame->setActualQueueTime(postTime);
497 surfaceFrame->setAcquireFenceTime(postTime);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800498 const auto fps = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
499 if (fps) {
Alec Mouri819f6302021-02-12 15:37:21 -0800500 surfaceFrame->setRenderRate(*fps);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800501 }
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000502 return surfaceFrame;
503}
504
505std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForBuffer(
Vishnu Nair39a74a92024-07-29 19:01:50 +0000506 const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName,
507 gui::GameMode gameMode) {
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000508 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800509 mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000510 getSequence(), mName, debugName,
Vishnu Nair39a74a92024-07-29 19:01:50 +0000511 /*isBuffer*/ true, gameMode);
Rachel Leeed511ef2021-10-11 15:09:51 -0700512 surfaceFrame->setActualStartTime(info.startTimeNanos);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000513 // For buffers, acquire fence time will set during latch.
514 surfaceFrame->setActualQueueTime(queueTime);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800515 const auto fps = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
516 if (fps) {
Alec Mouri819f6302021-02-12 15:37:21 -0800517 surfaceFrame->setRenderRate(*fps);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800518 }
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000519 return surfaceFrame;
Ady Abraham74e17562020-08-24 18:18:19 -0700520}
521
Ady Abraham5a3e3562023-06-07 10:32:08 -0700522void Layer::setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, nsecs_t postTime,
Vishnu Nair39a74a92024-07-29 19:01:50 +0000523 std::string debugName, gui::GameMode gameMode) {
Ady Abraham5a3e3562023-06-07 10:32:08 -0700524 if (info.skippedFrameVsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) {
525 return;
526 }
527
528 FrameTimelineInfo skippedFrameTimelineInfo = info;
529 skippedFrameTimelineInfo.vsyncId = info.skippedFrameVsyncId;
530
531 auto surfaceFrame =
532 mFlinger->mFrameTimeline->createSurfaceFrameForToken(skippedFrameTimelineInfo,
533 mOwnerPid, mOwnerUid,
534 getSequence(), mName, debugName,
Vishnu Nair39a74a92024-07-29 19:01:50 +0000535 /*isBuffer*/ false, gameMode);
Ady Abraham5a3e3562023-06-07 10:32:08 -0700536 surfaceFrame->setActualStartTime(skippedFrameTimelineInfo.skippedFrameStartTimeNanos);
537 // For Transactions, the post time is considered to be both queue and acquire fence time.
538 surfaceFrame->setActualQueueTime(postTime);
539 surfaceFrame->setAcquireFenceTime(postTime);
540 const auto fps = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
541 if (fps) {
542 surfaceFrame->setRenderRate(*fps);
543 }
Ady Abraham5a3e3562023-06-07 10:32:08 -0700544 addSurfaceFrameDroppedForBuffer(surfaceFrame, postTime);
545}
546
Vishnu Nair47b7bb42023-09-29 16:27:33 -0700547bool Layer::setFrameRateForLayerTree(FrameRate frameRate, const scheduler::LayerProps& layerProps,
548 nsecs_t now) {
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000549 if (mDrawingState.frameRateForLayerTree == frameRate) {
550 return false;
551 }
552
553 mDrawingState.frameRateForLayerTree = frameRate;
554 mFlinger->mScheduler
Vishnu Nair47b7bb42023-09-29 16:27:33 -0700555 ->recordLayerHistory(sequence, layerProps, now, now,
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000556 scheduler::LayerHistory::LayerUpdateType::SetFrameRate);
Ady Abrahama850c182021-08-04 13:04:37 -0700557 return true;
Steven Thomas3172e202020-01-06 19:25:30 -0800558}
559
Ady Abraham59fd8ff2021-04-15 20:13:30 -0700560Layer::FrameRate Layer::getFrameRateForLayerTree() const {
561 return getDrawingState().frameRateForLayerTree;
562}
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800563
Mathias Agopian13127d82013-03-05 17:47:11 -0800564// ----------------------------------------------------------------------------
565// debugging
566// ----------------------------------------------------------------------------
567
Yiwei Zhang5434a782018-12-05 18:06:32 -0800568void Layer::miniDumpHeader(std::string& result) {
Marin Shalamanov1876e2e2020-12-04 13:23:59 +0100569 result.append(kDumpTableRowLength, '-');
570 result.append("\n");
Dan Stozae22aec72016-08-01 13:20:59 -0700571 result.append(" Layer name\n");
572 result.append(" Z | ");
Ady Abraham8f1ee7f2019-04-05 10:32:50 -0700573 result.append(" Window Type | ");
Dan Stozae22aec72016-08-01 13:20:59 -0700574 result.append(" Comp Type | ");
Yichi Chen6ca35192018-05-29 12:20:43 +0800575 result.append(" Transform | ");
Dan Stozae22aec72016-08-01 13:20:59 -0700576 result.append(" Disp Frame (LTRB) | ");
Ady Abrahambe23e6a2020-05-04 14:51:16 -0700577 result.append(" Source Crop (LTRB) | ");
Marin Shalamanov1876e2e2020-12-04 13:23:59 +0100578 result.append(" Frame Rate (Explicit) (Seamlessness) [Focused]\n");
579 result.append(kDumpTableRowLength, '-');
580 result.append("\n");
Ady Abrahambe23e6a2020-05-04 14:51:16 -0700581}
582
Vishnu Nair3cc15a42023-06-30 06:20:22 +0000583void Layer::miniDump(std::string& result, const frontend::LayerSnapshot& snapshot,
584 const DisplayDevice& display) const {
585 const auto outputLayer = findOutputLayerForDisplay(&display, snapshot.path);
586 if (!outputLayer) {
587 return;
588 }
589
590 StringAppendF(&result, " %s\n", snapshot.debugName.c_str());
591 StringAppendF(&result, " %10zu | ", snapshot.globalZ);
592 StringAppendF(&result, " %10d | ",
593 snapshot.layerMetadata.getInt32(gui::METADATA_WINDOW_TYPE, 0));
594 StringAppendF(&result, "%10s | ", toString(getCompositionType(outputLayer)).c_str());
595 const auto& outputLayerState = outputLayer->getState();
596 StringAppendF(&result, "%10s | ", toString(outputLayerState.bufferTransform).c_str());
597 const Rect& frame = outputLayerState.displayFrame;
598 StringAppendF(&result, "%4d %4d %4d %4d | ", frame.left, frame.top, frame.right, frame.bottom);
599 const FloatRect& crop = outputLayerState.sourceCrop;
600 StringAppendF(&result, "%6.1f %6.1f %6.1f %6.1f | ", crop.left, crop.top, crop.right,
601 crop.bottom);
602 const auto frameRate = snapshot.frameRate;
Ady Abraham77d406d2023-11-22 15:00:23 -0800603 std::string frameRateStr;
604 if (frameRate.vote.rate.isValid()) {
605 StringAppendF(&frameRateStr, "%.2f", frameRate.vote.rate.getValue());
606 }
Rachel Leece6e0042023-06-27 11:22:54 -0700607 if (frameRate.vote.rate.isValid() || frameRate.vote.type != FrameRateCompatibility::Default) {
Ady Abraham77d406d2023-11-22 15:00:23 -0800608 StringAppendF(&result, "%6s %15s %17s", frameRateStr.c_str(),
Rachel Leece6e0042023-06-27 11:22:54 -0700609 ftl::enum_string(frameRate.vote.type).c_str(),
610 ftl::enum_string(frameRate.vote.seamlessness).c_str());
Ady Abraham77d406d2023-11-22 15:00:23 -0800611 } else if (frameRate.category != FrameRateCategory::Default) {
612 StringAppendF(&result, "%6s %15s %17s", frameRateStr.c_str(),
613 (std::string("Cat::") + ftl::enum_string(frameRate.category)).c_str(),
614 ftl::enum_string(frameRate.vote.seamlessness).c_str());
Vishnu Nair3cc15a42023-06-30 06:20:22 +0000615 } else {
616 result.append(41, ' ');
617 }
618
619 const auto focused = isLayerFocusedBasedOnPriority(snapshot.frameRateSelectionPriority);
620 StringAppendF(&result, " [%s]\n", focused ? "*" : " ");
621
622 result.append(kDumpTableRowLength, '-');
623 result.append("\n");
624}
625
Yiwei Zhang5434a782018-12-05 18:06:32 -0800626void Layer::dumpFrameStats(std::string& result) const {
Svetoslavd85084b2014-03-20 10:28:31 -0700627 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -0800628}
629
Svetoslavd85084b2014-03-20 10:28:31 -0700630void Layer::clearFrameStats() {
631 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -0800632}
633
Jamie Gennis6547ff42013-07-16 20:12:42 -0700634void Layer::logFrameStats() {
635 mFrameTracker.logAndResetStats(mName);
636}
637
Svetoslavd85084b2014-03-20 10:28:31 -0700638void Layer::getFrameStats(FrameStats* outStats) const {
639 mFrameTracker.getStats(outStats);
640}
641
Brian Anderson5ea5e592016-12-01 16:54:33 -0800642void Layer::onDisconnect() {
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800643 const int32_t layerId = getSequence();
644 mFlinger->mTimeStats->onDestroy(layerId);
645 mFlinger->mFrameTracer->onDestroy(layerId);
Brian Anderson5ea5e592016-12-01 16:54:33 -0800646}
647
Kean Mariotti4ba343c2023-04-19 13:31:02 +0000648void Layer::writeCompositionStateToProto(perfetto::protos::LayerProto* layerProto,
649 ui::LayerStack layerStack) {
Vishnu Nairea6ff812023-02-27 17:41:39 +0000650 ftl::FakeGuard guard(mFlinger->mStateLock); // Called from the main thread.
Vishnu Nair2f65e972023-04-04 16:36:28 +0000651 ftl::FakeGuard mainThreadGuard(kMainThreadContext);
Vishnu Nairea6ff812023-02-27 17:41:39 +0000652
653 // Only populate for the primary display.
Vishnu Nair2f65e972023-04-04 16:36:28 +0000654 if (const auto display = mFlinger->getDisplayFromLayerStack(layerStack)) {
Vishnu Nairea6ff812023-02-27 17:41:39 +0000655 const auto compositionType = getCompositionType(*display);
Kean Mariotti4ba343c2023-04-19 13:31:02 +0000656 layerProto->set_hwc_composition_type(
657 static_cast<perfetto::protos::HwcCompositionType>(compositionType));
Vishnu Nair2f65e972023-04-04 16:36:28 +0000658 LayerProtoHelper::writeToProto(getVisibleRegion(display),
Vishnu Nairea6ff812023-02-27 17:41:39 +0000659 [&]() { return layerProto->mutable_visible_region(); });
660 }
661}
662
Lloyd Pique37c2c9b2018-12-04 17:25:10 -0800663compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(
Dominik Laskowskib7251f42020-04-20 17:42:59 -0700664 const DisplayDevice* display) const {
665 if (!display) return nullptr;
Vishnu Naird47bcee2023-02-24 18:08:51 +0000666 sp<LayerFE> layerFE;
667 frontend::LayerHierarchy::TraversalPath path{.id = static_cast<uint32_t>(sequence)};
668 for (auto& [p, layer] : mLayerFEs) {
669 if (p == path) {
670 layerFE = layer;
671 }
672 }
673
674 if (!layerFE) return nullptr;
675 return display->getCompositionDisplay()->getOutputLayerForLayer(layerFE);
Lloyd Pique37c2c9b2018-12-04 17:25:10 -0800676}
677
Vishnu Nair3cc15a42023-06-30 06:20:22 +0000678compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(
679 const DisplayDevice* display, const frontend::LayerHierarchy::TraversalPath& path) const {
680 if (!display) return nullptr;
681 sp<LayerFE> layerFE;
682 for (auto& [p, layer] : mLayerFEs) {
683 if (p == path) {
684 layerFE = layer;
685 }
686 }
687
688 if (!layerFE) return nullptr;
689 return display->getCompositionDisplay()->getOutputLayerForLayer(layerFE);
690}
691
Dominik Laskowskib7251f42020-04-20 17:42:59 -0700692Region Layer::getVisibleRegion(const DisplayDevice* display) const {
693 const auto outputLayer = findOutputLayerForDisplay(display);
694 return outputLayer ? outputLayer->getState().visibleRegion : Region();
Lloyd Piquea2468662019-03-07 21:31:06 -0800695}
696
Patrick Williamsbb25f802022-08-30 23:02:34 +0000697void Layer::callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener,
698 const sp<GraphicBuffer>& buffer, uint64_t framenumber,
liulijuneb489f62022-10-17 22:02:14 +0800699 const sp<Fence>& releaseFence) {
Patrick Williams7c9fa272024-08-30 12:38:43 +0000700 if (!listener && !mBufferReleaseChannel) {
Patrick Williamsbb25f802022-08-30 23:02:34 +0000701 return;
702 }
Patrick Williams7c9fa272024-08-30 12:38:43 +0000703
Vishnu Nairbe0ad902024-06-27 23:38:43 +0000704 SFTRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64, getDebugName(), framenumber);
Patrick Williams7c9fa272024-08-30 12:38:43 +0000705
706 ReleaseCallbackId callbackId{buffer->getId(), framenumber};
707 const sp<Fence>& fence = releaseFence ? releaseFence : Fence::NO_FENCE;
liulijuneb489f62022-10-17 22:02:14 +0800708 uint32_t currentMaxAcquiredBufferCount =
709 mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid);
Patrick Williams7c9fa272024-08-30 12:38:43 +0000710
711 if (listener) {
712 listener->onReleaseBuffer(callbackId, fence, currentMaxAcquiredBufferCount);
713 }
714
715 if (mBufferReleaseChannel) {
716 mBufferReleaseChannel->writeReleaseFence(callbackId, fence, currentMaxAcquiredBufferCount);
717 }
Patrick Williamsbb25f802022-08-30 23:02:34 +0000718}
719
Melody Hsu793f8362024-01-08 20:00:35 +0000720sp<CallbackHandle> Layer::findCallbackHandle() {
Patrick Williamsbb25f802022-08-30 23:02:34 +0000721 // If we are displayed on multiple displays in a single composition cycle then we would
722 // need to do careful tracking to enable the use of the mLastClientCompositionFence.
723 // For example we can only use it if all the displays are client comp, and we need
724 // to merge all the client comp fences. We could do this, but for now we just
725 // disable the optimization when a layer is composed on multiple displays.
726 if (mClearClientCompositionFenceOnLayerDisplayed) {
727 mLastClientCompositionFence = nullptr;
728 } else {
729 mClearClientCompositionFenceOnLayerDisplayed = true;
730 }
731
732 // The previous release fence notifies the client that SurfaceFlinger is done with the previous
733 // buffer that was presented on this layer. The first transaction that came in this frame that
734 // replaced the previous buffer on this layer needs this release fence, because the fence will
735 // let the client know when that previous buffer is removed from the screen.
736 //
737 // Every other transaction on this layer does not need a release fence because no other
738 // Transactions that were set on this layer this frame are going to have their preceding buffer
739 // removed from the display this frame.
740 //
741 // For example, if we have 3 transactions this frame. The first transaction doesn't contain a
742 // buffer so it doesn't need a previous release fence because the layer still needs the previous
743 // buffer. The second transaction contains a buffer so it needs a previous release fence because
744 // the previous buffer will be released this frame. The third transaction also contains a
745 // buffer. It replaces the buffer in the second transaction. The buffer in the second
746 // transaction will now no longer be presented so it is released immediately and the third
747 // transaction doesn't need a previous release fence.
748 sp<CallbackHandle> ch;
749 for (auto& handle : mDrawingState.callbackHandles) {
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700750 if (handle->releasePreviousBuffer && mPreviousReleaseBufferEndpoint == handle->listener) {
Patrick Williamsbb25f802022-08-30 23:02:34 +0000751 ch = handle;
752 break;
753 }
754 }
Melody Hsu793f8362024-01-08 20:00:35 +0000755 return ch;
756}
757
758void Layer::prepareReleaseCallbacks(ftl::Future<FenceResult> futureFenceResult,
759 ui::LayerStack layerStack) {
760 sp<CallbackHandle> ch = findCallbackHandle();
761
762 if (ch != nullptr) {
763 ch->previousReleaseCallbackId = mPreviousReleaseCallbackId;
764 ch->previousReleaseFences.emplace_back(std::move(futureFenceResult));
765 ch->name = mName;
766 } else {
Melody Hsue4ef87f2024-03-26 23:54:45 +0000767 // If we didn't get a release callback yet (e.g. some scenarios when capturing
768 // screenshots asynchronously) then make sure we don't drop the fence.
769 // Older fences for the same layer stack can be dropped when a new fence arrives.
770 // An assumption here is that RenderEngine performs work sequentially, so an
771 // incoming fence will not fire before an existing fence.
772 mAdditionalPreviousReleaseFences.emplace_or_replace(layerStack,
773 std::move(futureFenceResult));
Melody Hsu793f8362024-01-08 20:00:35 +0000774 }
775
776 if (mBufferInfo.mBuffer) {
777 mPreviouslyPresentedLayerStacks.push_back(layerStack);
778 }
779
780 if (mDrawingState.frameNumber > 0) {
781 mDrawingState.previousFrameNumber = mDrawingState.frameNumber;
782 }
783}
784
785void Layer::onLayerDisplayed(ftl::SharedFuture<FenceResult> futureFenceResult,
786 ui::LayerStack layerStack,
787 std::function<FenceResult(FenceResult)>&& continuation) {
788 sp<CallbackHandle> ch = findCallbackHandle();
Alec Mouri9892aac2023-12-11 21:16:59 +0000789
790 if (!FlagManager::getInstance().screenshot_fence_preservation() && continuation) {
791 futureFenceResult = ftl::Future(futureFenceResult).then(std::move(continuation)).share();
792 }
793
Patrick Williamsbb25f802022-08-30 23:02:34 +0000794 if (ch != nullptr) {
795 ch->previousReleaseCallbackId = mPreviousReleaseCallbackId;
Melody Hsu793f8362024-01-08 20:00:35 +0000796 ch->previousSharedReleaseFences.emplace_back(std::move(futureFenceResult));
Patrick Williamsbb25f802022-08-30 23:02:34 +0000797 ch->name = mName;
Alec Mouri9892aac2023-12-11 21:16:59 +0000798 } else if (FlagManager::getInstance().screenshot_fence_preservation()) {
799 // If we didn't get a release callback yet, e.g. some scenarios when capturing screenshots
800 // asynchronously, then make sure we don't drop the fence.
Melody Hsu793f8362024-01-08 20:00:35 +0000801 mPreviousReleaseFenceAndContinuations.emplace_back(std::move(futureFenceResult),
802 std::move(continuation));
Alec Mouri9892aac2023-12-11 21:16:59 +0000803 std::vector<FenceAndContinuation> mergedFences;
804 sp<Fence> prevFence = nullptr;
805 // For a layer that's frequently screenshotted, try to merge fences to make sure we don't
806 // grow unbounded.
Melody Hsu793f8362024-01-08 20:00:35 +0000807 for (const auto& futureAndContinuation : mPreviousReleaseFenceAndContinuations) {
808 auto result = futureAndContinuation.future.wait_for(0s);
Alec Mouri9892aac2023-12-11 21:16:59 +0000809 if (result != std::future_status::ready) {
Melody Hsu793f8362024-01-08 20:00:35 +0000810 mergedFences.emplace_back(futureAndContinuation);
Alec Mouri9892aac2023-12-11 21:16:59 +0000811 continue;
812 }
813
Melody Hsu793f8362024-01-08 20:00:35 +0000814 mergeFence(getDebugName(),
815 futureAndContinuation.chain().get().value_or(Fence::NO_FENCE), prevFence);
Alec Mouri9892aac2023-12-11 21:16:59 +0000816 }
817 if (prevFence != nullptr) {
818 mergedFences.emplace_back(ftl::yield(FenceResult(std::move(prevFence))).share());
819 }
820
Melody Hsu793f8362024-01-08 20:00:35 +0000821 mPreviousReleaseFenceAndContinuations.swap(mergedFences);
Patrick Williamsbb25f802022-08-30 23:02:34 +0000822 }
Alec Mouri9892aac2023-12-11 21:16:59 +0000823
Vishnu Nair316b7f42023-10-13 23:44:46 +0000824 if (mBufferInfo.mBuffer) {
825 mPreviouslyPresentedLayerStacks.push_back(layerStack);
826 }
Alec Mouri21d94322023-10-17 19:51:39 +0000827
828 if (mDrawingState.frameNumber > 0) {
829 mDrawingState.previousFrameNumber = mDrawingState.frameNumber;
830 }
Patrick Williamsbb25f802022-08-30 23:02:34 +0000831}
832
Patrick Williamsbb25f802022-08-30 23:02:34 +0000833void Layer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
834 for (const auto& handle : mDrawingState.callbackHandles) {
Patrick Williams7c9fa272024-08-30 12:38:43 +0000835 handle->bufferReleaseChannel = mBufferReleaseChannel;
Melody Hsu9af30702024-04-17 18:23:43 +0000836 handle->transformHint = mTransformHint;
Patrick Williamsbb25f802022-08-30 23:02:34 +0000837 handle->dequeueReadyTime = dequeueReadyTime;
838 handle->currentMaxAcquiredBufferCount =
839 mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid);
Vishnu Nairbe0ad902024-06-27 23:38:43 +0000840 SFTRACE_FORMAT_INSTANT("releasePendingBuffer %s - %" PRIu64, getDebugName(),
841 handle->previousReleaseCallbackId.framenumber);
Patrick Williamsbb25f802022-08-30 23:02:34 +0000842 }
843
844 for (auto& handle : mDrawingState.callbackHandles) {
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700845 if (handle->releasePreviousBuffer && mPreviousReleaseBufferEndpoint == handle->listener) {
Patrick Williamsbb25f802022-08-30 23:02:34 +0000846 handle->previousReleaseCallbackId = mPreviousReleaseCallbackId;
847 break;
848 }
849 }
850
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200851 mFlinger->getTransactionCallbackInvoker().addCallbackHandles(mDrawingState.callbackHandles);
Patrick Williamsbb25f802022-08-30 23:02:34 +0000852 mDrawingState.callbackHandles = {};
853}
854
Patrick Williamsbb25f802022-08-30 23:02:34 +0000855bool Layer::setTransform(uint32_t transform) {
856 if (mDrawingState.bufferTransform == transform) return false;
857 mDrawingState.bufferTransform = transform;
Patrick Williamsbb25f802022-08-30 23:02:34 +0000858 setTransactionFlags(eTransactionNeeded);
859 return true;
860}
861
862bool Layer::setTransformToDisplayInverse(bool transformToDisplayInverse) {
863 if (mDrawingState.transformToDisplayInverse == transformToDisplayInverse) return false;
864 mDrawingState.sequence++;
865 mDrawingState.transformToDisplayInverse = transformToDisplayInverse;
Patrick Williamsbb25f802022-08-30 23:02:34 +0000866 setTransactionFlags(eTransactionNeeded);
867 return true;
868}
869
870bool Layer::setBufferCrop(const Rect& bufferCrop) {
871 if (mDrawingState.bufferCrop == bufferCrop) return false;
872
873 mDrawingState.sequence++;
874 mDrawingState.bufferCrop = bufferCrop;
875
Patrick Williamsbb25f802022-08-30 23:02:34 +0000876 setTransactionFlags(eTransactionNeeded);
877 return true;
878}
879
Dorin Drimuse5374e52023-08-02 17:52:43 +0000880void Layer::releasePreviousBuffer() {
881 mReleasePreviousBuffer = true;
882 if (!mBufferInfo.mBuffer ||
883 (!mDrawingState.buffer->hasSameBuffer(*mBufferInfo.mBuffer) ||
884 mDrawingState.frameNumber != mBufferInfo.mFrameNumber)) {
885 // If mDrawingState has a buffer, and we are about to update again
886 // before swapping to drawing state, then the first buffer will be
887 // dropped and we should decrement the pending buffer count and
888 // call any release buffer callbacks if set.
889 callReleaseBufferCallback(mDrawingState.releaseBufferListener,
890 mDrawingState.buffer->getBuffer(), mDrawingState.frameNumber,
891 mDrawingState.acquireFence);
Dominic Lemire95c4ecc2024-07-09 12:06:18 -0700892 const int32_t layerId = getSequence();
893 mFlinger->mTimeStats->removeTimeRecord(layerId, mDrawingState.frameNumber);
Dorin Drimuse5374e52023-08-02 17:52:43 +0000894 decrementPendingBufferCount();
895 if (mDrawingState.bufferSurfaceFrameTX != nullptr &&
896 mDrawingState.bufferSurfaceFrameTX->getPresentState() != PresentState::Presented) {
897 addSurfaceFrameDroppedForBuffer(mDrawingState.bufferSurfaceFrameTX, systemTime());
898 mDrawingState.bufferSurfaceFrameTX.reset();
899 }
900 } else if (EARLY_RELEASE_ENABLED && mLastClientCompositionFence != nullptr) {
901 callReleaseBufferCallback(mDrawingState.releaseBufferListener,
902 mDrawingState.buffer->getBuffer(), mDrawingState.frameNumber,
903 mLastClientCompositionFence);
904 mLastClientCompositionFence = nullptr;
905 }
906}
907
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700908void Layer::resetDrawingStateBufferInfo() {
909 mDrawingState.producerId = 0;
910 mDrawingState.frameNumber = 0;
Alec Mouri21d94322023-10-17 19:51:39 +0000911 mDrawingState.previousFrameNumber = 0;
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700912 mDrawingState.releaseBufferListener = nullptr;
913 mDrawingState.buffer = nullptr;
914 mDrawingState.acquireFence = sp<Fence>::make(-1);
915 mDrawingState.acquireFenceTime = std::make_unique<FenceTime>(mDrawingState.acquireFence);
916 mCallbackHandleAcquireTimeOrFence = mDrawingState.acquireFenceTime->getSignalTime();
917 mDrawingState.releaseBufferEndpoint = nullptr;
918}
919
Patrick Williamsbb25f802022-08-30 23:02:34 +0000920bool Layer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer,
921 const BufferData& bufferData, nsecs_t postTime, nsecs_t desiredPresentTime,
Vishnu Nair39a74a92024-07-29 19:01:50 +0000922 bool isAutoTimestamp, const FrameTimelineInfo& info, gui::GameMode gameMode) {
Vishnu Nairbe0ad902024-06-27 23:38:43 +0000923 SFTRACE_FORMAT("setBuffer %s - hasBuffer=%s", getDebugName(), (buffer ? "true" : "false"));
Patrick Williamsbb25f802022-08-30 23:02:34 +0000924
925 const bool frameNumberChanged =
926 bufferData.flags.test(BufferData::BufferDataChange::frameNumberChanged);
927 const uint64_t frameNumber =
928 frameNumberChanged ? bufferData.frameNumber : mDrawingState.frameNumber + 1;
Vishnu Nairbe0ad902024-06-27 23:38:43 +0000929 SFTRACE_FORMAT_INSTANT("setBuffer %s - %" PRIu64, getDebugName(), frameNumber);
Patrick Williamsbb25f802022-08-30 23:02:34 +0000930
931 if (mDrawingState.buffer) {
Dorin Drimuse5374e52023-08-02 17:52:43 +0000932 releasePreviousBuffer();
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700933 } else if (buffer) {
Vishnu Nairc09c0232023-03-02 03:22:35 +0000934 // if we are latching a buffer for the first time then clear the mLastLatchTime since
935 // we don't want to incorrectly classify a frame if we miss the desired present time.
936 updateLastLatchTime(0);
Patrick Williamsbb25f802022-08-30 23:02:34 +0000937 }
938
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700939 mDrawingState.desiredPresentTime = desiredPresentTime;
940 mDrawingState.isAutoTimestamp = isAutoTimestamp;
941 mDrawingState.latchedVsyncId = info.vsyncId;
Ady Abraham55269162023-05-09 11:26:06 -0700942 mDrawingState.useVsyncIdForRefreshRateSelection = info.useForRefreshRateSelection;
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700943 if (!buffer) {
944 resetDrawingStateBufferInfo();
945 setTransactionFlags(eTransactionNeeded);
946 mDrawingState.bufferSurfaceFrameTX = nullptr;
Vishnu Nair39a74a92024-07-29 19:01:50 +0000947 setFrameTimelineVsyncForBufferlessTransaction(info, postTime, gameMode);
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700948 return true;
Dorin Drimuse5374e52023-08-02 17:52:43 +0000949 } else {
950 // release sideband stream if it exists and a non null buffer is being set
951 if (mDrawingState.sidebandStream != nullptr) {
Vishnu Nair39a74a92024-07-29 19:01:50 +0000952 setSidebandStream(nullptr, info, postTime, gameMode);
Dorin Drimuse5374e52023-08-02 17:52:43 +0000953 }
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700954 }
955
Vishnu Naird1f74982023-06-15 20:16:51 -0700956 if ((mDrawingState.producerId > bufferData.producerId) ||
957 ((mDrawingState.producerId == bufferData.producerId) &&
958 (mDrawingState.frameNumber > frameNumber))) {
959 ALOGE("Out of order buffers detected for %s producedId=%d frameNumber=%" PRIu64
960 " -> producedId=%d frameNumber=%" PRIu64,
961 getDebugName(), mDrawingState.producerId, mDrawingState.frameNumber,
962 bufferData.producerId, frameNumber);
963 TransactionTraceWriter::getInstance().invoke("out_of_order_buffers_", /*overwrite=*/false);
964 }
965
liulijuneb489f62022-10-17 22:02:14 +0800966 mDrawingState.producerId = bufferData.producerId;
Vishnu Nair63221212023-04-06 15:17:37 -0700967 mDrawingState.barrierProducerId =
968 std::max(mDrawingState.producerId, mDrawingState.barrierProducerId);
Patrick Williamsbb25f802022-08-30 23:02:34 +0000969 mDrawingState.frameNumber = frameNumber;
Vishnu Nair63221212023-04-06 15:17:37 -0700970 mDrawingState.barrierFrameNumber =
971 std::max(mDrawingState.frameNumber, mDrawingState.barrierFrameNumber);
972
Patrick Williamsbb25f802022-08-30 23:02:34 +0000973 mDrawingState.releaseBufferListener = bufferData.releaseBufferListener;
974 mDrawingState.buffer = std::move(buffer);
Patrick Williamsbb25f802022-08-30 23:02:34 +0000975 mDrawingState.acquireFence = bufferData.flags.test(BufferData::BufferDataChange::fenceChanged)
976 ? bufferData.acquireFence
977 : Fence::NO_FENCE;
978 mDrawingState.acquireFenceTime = std::make_unique<FenceTime>(mDrawingState.acquireFence);
979 if (mDrawingState.acquireFenceTime->getSignalTime() == Fence::SIGNAL_TIME_PENDING) {
980 // We latched this buffer unsiganled, so we need to pass the acquire fence
981 // on the callback instead of just the acquire time, since it's unknown at
982 // this point.
983 mCallbackHandleAcquireTimeOrFence = mDrawingState.acquireFence;
984 } else {
985 mCallbackHandleAcquireTimeOrFence = mDrawingState.acquireFenceTime->getSignalTime();
986 }
Patrick Williamsbb25f802022-08-30 23:02:34 +0000987 setTransactionFlags(eTransactionNeeded);
988
989 const int32_t layerId = getSequence();
990 mFlinger->mTimeStats->setPostTime(layerId, mDrawingState.frameNumber, getName().c_str(),
Vishnu Nair39a74a92024-07-29 19:01:50 +0000991 mOwnerUid, postTime, gameMode);
Patrick Williamsbb25f802022-08-30 23:02:34 +0000992
Vishnu Nair39a74a92024-07-29 19:01:50 +0000993 setFrameTimelineVsyncForBufferTransaction(info, postTime, gameMode);
Patrick Williamsbb25f802022-08-30 23:02:34 +0000994
Nergi Rahardi39f510f2024-05-23 15:16:54 +0900995 if (bufferData.dequeueTime > 0) {
Patrick Williamsbb25f802022-08-30 23:02:34 +0000996 const uint64_t bufferId = mDrawingState.buffer->getId();
997 mFlinger->mFrameTracer->traceNewLayer(layerId, getName().c_str());
Nergi Rahardi39f510f2024-05-23 15:16:54 +0900998 mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber,
999 bufferData.dequeueTime,
Patrick Williamsbb25f802022-08-30 23:02:34 +00001000 FrameTracer::FrameEvent::DEQUEUE);
1001 mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, postTime,
1002 FrameTracer::FrameEvent::QUEUE);
1003 }
1004
1005 mDrawingState.releaseBufferEndpoint = bufferData.releaseBufferEndpoint;
Arthur Hungc70bee22023-06-02 01:35:52 +00001006
1007 // If the layer had been updated a TextureView, this would make sure the present time could be
1008 // same to TextureView update when it's a small dirty, and get the correct heuristic rate.
Jerry Chang36678002023-11-29 16:56:17 +00001009 if (mFlinger->mScheduler->supportSmallDirtyDetection(mOwnerAppId)) {
Arthur Hungc70bee22023-06-02 01:35:52 +00001010 if (mDrawingState.useVsyncIdForRefreshRateSelection) {
1011 mUsedVsyncIdForRefreshRateSelection = true;
1012 }
1013 }
Patrick Williamsbb25f802022-08-30 23:02:34 +00001014 return true;
1015}
1016
Vishnu Nairef68d6d2023-02-28 06:18:27 +00001017void Layer::setDesiredPresentTime(nsecs_t desiredPresentTime, bool isAutoTimestamp) {
1018 mDrawingState.desiredPresentTime = desiredPresentTime;
1019 mDrawingState.isAutoTimestamp = isAutoTimestamp;
1020}
1021
Vishnu Nair47b7bb42023-09-29 16:27:33 -07001022void Layer::recordLayerHistoryBufferUpdate(const scheduler::LayerProps& layerProps, nsecs_t now) {
Vishnu Nairbe0ad902024-06-27 23:38:43 +00001023 SFTRACE_CALL();
Vishnu Nairef68d6d2023-02-28 06:18:27 +00001024 const nsecs_t presentTime = [&] {
Ady Abraham55269162023-05-09 11:26:06 -07001025 if (!mDrawingState.isAutoTimestamp) {
Vishnu Nairbe0ad902024-06-27 23:38:43 +00001026 SFTRACE_FORMAT_INSTANT("desiredPresentTime");
Ady Abraham55269162023-05-09 11:26:06 -07001027 return mDrawingState.desiredPresentTime;
1028 }
Vishnu Nairef68d6d2023-02-28 06:18:27 +00001029
Ady Abraham55269162023-05-09 11:26:06 -07001030 if (mDrawingState.useVsyncIdForRefreshRateSelection) {
1031 const auto prediction =
1032 mFlinger->mFrameTimeline->getTokenManager()->getPredictionsForToken(
1033 mDrawingState.latchedVsyncId);
1034 if (prediction.has_value()) {
Vishnu Nairbe0ad902024-06-27 23:38:43 +00001035 SFTRACE_FORMAT_INSTANT("predictedPresentTime");
Arthur Hungc70bee22023-06-02 01:35:52 +00001036 mMaxTimeForUseVsyncId = prediction->presentTime +
1037 scheduler::LayerHistory::kMaxPeriodForHistory.count();
Ady Abraham55269162023-05-09 11:26:06 -07001038 return prediction->presentTime;
1039 }
1040 }
Vishnu Nairef68d6d2023-02-28 06:18:27 +00001041
Jerry Chang36678002023-11-29 16:56:17 +00001042 if (!mFlinger->mScheduler->supportSmallDirtyDetection(mOwnerAppId)) {
Arthur Hungc70bee22023-06-02 01:35:52 +00001043 return static_cast<nsecs_t>(0);
1044 }
1045
1046 // If the layer is not an application and didn't set an explicit rate or desiredPresentTime,
1047 // return "0" to tell the layer history that it will use the max refresh rate without
1048 // calculating the adaptive rate.
1049 if (mWindowType != WindowInfo::Type::APPLICATION &&
1050 mWindowType != WindowInfo::Type::BASE_APPLICATION) {
1051 return static_cast<nsecs_t>(0);
1052 }
1053
1054 // Return the valid present time only when the layer potentially updated a TextureView so
1055 // LayerHistory could heuristically calculate the rate if the UI is continually updating.
1056 if (mUsedVsyncIdForRefreshRateSelection) {
1057 const auto prediction =
1058 mFlinger->mFrameTimeline->getTokenManager()->getPredictionsForToken(
1059 mDrawingState.latchedVsyncId);
1060 if (prediction.has_value()) {
1061 if (mMaxTimeForUseVsyncId >= prediction->presentTime) {
1062 return prediction->presentTime;
1063 }
1064 mUsedVsyncIdForRefreshRateSelection = false;
1065 }
1066 }
1067
Vishnu Nairef68d6d2023-02-28 06:18:27 +00001068 return static_cast<nsecs_t>(0);
1069 }();
Ady Abraham55269162023-05-09 11:26:06 -07001070
Vishnu Nair2665ca92024-07-09 22:08:15 +00001071 if (SFTRACE_ENABLED() && presentTime > 0) {
Ady Abraham55269162023-05-09 11:26:06 -07001072 const auto presentIn = TimePoint::fromNs(presentTime) - TimePoint::now();
Vishnu Nairbe0ad902024-06-27 23:38:43 +00001073 SFTRACE_FORMAT_INSTANT("presentIn %s", to_string(presentIn).c_str());
Ady Abraham55269162023-05-09 11:26:06 -07001074 }
1075
Vishnu Nair47b7bb42023-09-29 16:27:33 -07001076 mFlinger->mScheduler->recordLayerHistory(sequence, layerProps, presentTime, now,
Vishnu Nairef68d6d2023-02-28 06:18:27 +00001077 scheduler::LayerHistory::LayerUpdateType::Buffer);
1078}
1079
Vishnu Nair47b7bb42023-09-29 16:27:33 -07001080void Layer::recordLayerHistoryAnimationTx(const scheduler::LayerProps& layerProps, nsecs_t now) {
Vishnu Nairef68d6d2023-02-28 06:18:27 +00001081 const nsecs_t presentTime =
1082 mDrawingState.isAutoTimestamp ? 0 : mDrawingState.desiredPresentTime;
Vishnu Nair47b7bb42023-09-29 16:27:33 -07001083 mFlinger->mScheduler->recordLayerHistory(sequence, layerProps, presentTime, now,
Vishnu Nairef68d6d2023-02-28 06:18:27 +00001084 scheduler::LayerHistory::LayerUpdateType::AnimationTX);
1085}
1086
Patrick Williamsbb25f802022-08-30 23:02:34 +00001087bool Layer::setDataspace(ui::Dataspace dataspace) {
Patrick Williamsbb25f802022-08-30 23:02:34 +00001088 if (mDrawingState.dataspace == dataspace) return false;
1089 mDrawingState.dataspace = dataspace;
Patrick Williamsbb25f802022-08-30 23:02:34 +00001090 setTransactionFlags(eTransactionNeeded);
1091 return true;
1092}
1093
John Reck68796592023-01-25 13:47:12 -05001094bool Layer::setExtendedRangeBrightness(float currentBufferRatio, float desiredRatio) {
Sally Qi963049b2023-03-23 14:06:21 -07001095 if (mDrawingState.currentHdrSdrRatio == currentBufferRatio &&
1096 mDrawingState.desiredHdrSdrRatio == desiredRatio)
John Reck68796592023-01-25 13:47:12 -05001097 return false;
Sally Qi963049b2023-03-23 14:06:21 -07001098 mDrawingState.currentHdrSdrRatio = currentBufferRatio;
1099 mDrawingState.desiredHdrSdrRatio = desiredRatio;
John Reck68796592023-01-25 13:47:12 -05001100 setTransactionFlags(eTransactionNeeded);
1101 return true;
1102}
1103
Alec Mouri1b0d4e12024-02-12 22:27:19 +00001104bool Layer::setDesiredHdrHeadroom(float desiredRatio) {
1105 if (mDrawingState.desiredHdrSdrRatio == desiredRatio) return false;
1106 mDrawingState.desiredHdrSdrRatio = desiredRatio;
Patrick Williamsbb25f802022-08-30 23:02:34 +00001107 setTransactionFlags(eTransactionNeeded);
1108 return true;
1109}
1110
Dorin Drimuse5374e52023-08-02 17:52:43 +00001111bool Layer::setSidebandStream(const sp<NativeHandle>& sidebandStream, const FrameTimelineInfo& info,
Vishnu Nair39a74a92024-07-29 19:01:50 +00001112 nsecs_t postTime, gui::GameMode gameMode) {
Patrick Williamsbb25f802022-08-30 23:02:34 +00001113 if (mDrawingState.sidebandStream == sidebandStream) return false;
1114
1115 if (mDrawingState.sidebandStream != nullptr && sidebandStream == nullptr) {
1116 mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount();
1117 } else if (sidebandStream != nullptr) {
1118 mFlinger->mTunnelModeEnabledReporter->incrementTunnelModeCount();
1119 }
1120
1121 mDrawingState.sidebandStream = sidebandStream;
Dorin Drimuse5374e52023-08-02 17:52:43 +00001122 if (sidebandStream != nullptr && mDrawingState.buffer != nullptr) {
1123 releasePreviousBuffer();
1124 resetDrawingStateBufferInfo();
1125 mDrawingState.bufferSurfaceFrameTX = nullptr;
Vishnu Nair39a74a92024-07-29 19:01:50 +00001126 setFrameTimelineVsyncForBufferlessTransaction(info, postTime, gameMode);
Dorin Drimuse5374e52023-08-02 17:52:43 +00001127 }
Patrick Williamsbb25f802022-08-30 23:02:34 +00001128 setTransactionFlags(eTransactionNeeded);
1129 if (!mSidebandStreamChanged.exchange(true)) {
1130 // mSidebandStreamChanged was false
1131 mFlinger->onLayerUpdate();
1132 }
1133 return true;
1134}
1135
Vishnu Nair3af0ec02023-02-10 04:13:48 +00001136bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles,
1137 bool willPresent) {
Patrick Williamsbb25f802022-08-30 23:02:34 +00001138 // If there is no handle, we will not send a callback so reset mReleasePreviousBuffer and return
1139 if (handles.empty()) {
1140 mReleasePreviousBuffer = false;
1141 return false;
1142 }
1143
Pascal Muetschard81cef292023-02-06 12:18:52 +01001144 std::deque<sp<CallbackHandle>> remainingHandles;
Patrick Williamsbb25f802022-08-30 23:02:34 +00001145 for (const auto& handle : handles) {
1146 // If this transaction set a buffer on this layer, release its previous buffer
1147 handle->releasePreviousBuffer = mReleasePreviousBuffer;
1148
1149 // If this layer will be presented in this frame
1150 if (willPresent) {
1151 // If this transaction set an acquire fence on this layer, set its acquire time
1152 handle->acquireTimeOrFence = mCallbackHandleAcquireTimeOrFence;
1153 handle->frameNumber = mDrawingState.frameNumber;
Alec Mouri21d94322023-10-17 19:51:39 +00001154 handle->previousFrameNumber = mDrawingState.previousFrameNumber;
Melody Hsu793f8362024-01-08 20:00:35 +00001155 if (FlagManager::getInstance().ce_fence_promise() &&
Alec Mouri9892aac2023-12-11 21:16:59 +00001156 mPreviousReleaseBufferEndpoint == handle->listener) {
Melody Hsue4ef87f2024-03-26 23:54:45 +00001157 // Add fence from previous screenshot now so that it can be dispatched to the
Alec Mouri9892aac2023-12-11 21:16:59 +00001158 // client.
Melody Hsue4ef87f2024-03-26 23:54:45 +00001159 for (auto& [_, future] : mAdditionalPreviousReleaseFences) {
1160 handle->previousReleaseFences.emplace_back(std::move(future));
Alec Mouri9892aac2023-12-11 21:16:59 +00001161 }
1162 mAdditionalPreviousReleaseFences.clear();
Melody Hsu793f8362024-01-08 20:00:35 +00001163 } else if (FlagManager::getInstance().screenshot_fence_preservation() &&
1164 mPreviousReleaseBufferEndpoint == handle->listener) {
1165 // Add fences from previous screenshots now so that they can be dispatched to the
1166 // client.
1167 for (const auto& futureAndContinution : mPreviousReleaseFenceAndContinuations) {
1168 handle->previousSharedReleaseFences.emplace_back(futureAndContinution.chain());
1169 }
1170 mPreviousReleaseFenceAndContinuations.clear();
Alec Mouri9892aac2023-12-11 21:16:59 +00001171 }
Patrick Williamsbb25f802022-08-30 23:02:34 +00001172 // Store so latched time and release fence can be set
1173 mDrawingState.callbackHandles.push_back(handle);
1174
1175 } else { // If this layer will NOT need to be relatched and presented this frame
Pascal Muetschard81cef292023-02-06 12:18:52 +01001176 // Queue this handle to be notified below.
1177 remainingHandles.push_back(handle);
Patrick Williamsbb25f802022-08-30 23:02:34 +00001178 }
1179 }
1180
Pascal Muetschard81cef292023-02-06 12:18:52 +01001181 if (!remainingHandles.empty()) {
1182 // Notify the transaction completed threads these handles are done. These are only the
1183 // handles that were not added to the mDrawingState, which will be notified later.
Pascal Mütschardd56514e2024-05-24 17:37:13 +02001184 mFlinger->getTransactionCallbackInvoker().addCallbackHandles(remainingHandles);
Pascal Muetschard81cef292023-02-06 12:18:52 +01001185 }
1186
Patrick Williamsbb25f802022-08-30 23:02:34 +00001187 mReleasePreviousBuffer = false;
1188 mCallbackHandleAcquireTimeOrFence = -1;
1189
1190 return willPresent;
1191}
1192
1193Rect Layer::getBufferSize(const State& /*s*/) const {
1194 // for buffer state layers we use the display frame size as the buffer size.
1195
1196 if (mBufferInfo.mBuffer == nullptr) {
1197 return Rect::INVALID_RECT;
1198 }
1199
1200 uint32_t bufWidth = mBufferInfo.mBuffer->getWidth();
1201 uint32_t bufHeight = mBufferInfo.mBuffer->getHeight();
1202
1203 // Undo any transformations on the buffer and return the result.
1204 if (mBufferInfo.mTransform & ui::Transform::ROT_90) {
1205 std::swap(bufWidth, bufHeight);
1206 }
1207
1208 if (getTransformToDisplayInverse()) {
Leon Scroggins III85d4b222023-05-09 13:58:18 -04001209 uint32_t invTransform = SurfaceFlinger::getActiveDisplayRotationFlags();
Patrick Williamsbb25f802022-08-30 23:02:34 +00001210 if (invTransform & ui::Transform::ROT_90) {
1211 std::swap(bufWidth, bufHeight);
1212 }
1213 }
1214
1215 return Rect(0, 0, static_cast<int32_t>(bufWidth), static_cast<int32_t>(bufHeight));
1216}
1217
Patrick Williamsbb25f802022-08-30 23:02:34 +00001218bool Layer::fenceHasSignaled() const {
1219 if (SurfaceFlinger::enableLatchUnsignaledConfig != LatchUnsignaledConfig::Disabled) {
1220 return true;
1221 }
1222
1223 const bool fenceSignaled =
1224 getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled;
1225 if (!fenceSignaled) {
1226 mFlinger->mTimeStats->incrementLatchSkipped(getSequence(),
1227 TimeStats::LatchSkipReason::LateAcquire);
1228 }
1229
1230 return fenceSignaled;
1231}
1232
Vishnu Nair3af0ec02023-02-10 04:13:48 +00001233void Layer::onPreComposition(nsecs_t refreshStartTime) {
Patrick Williamsbb25f802022-08-30 23:02:34 +00001234 for (const auto& handle : mDrawingState.callbackHandles) {
1235 handle->refreshStartTime = refreshStartTime;
1236 }
Patrick Williamsbb25f802022-08-30 23:02:34 +00001237}
1238
Patrick Williamsbb25f802022-08-30 23:02:34 +00001239bool Layer::latchSidebandStream(bool& recomputeVisibleRegions) {
Patrick Williamsbb25f802022-08-30 23:02:34 +00001240 if (mSidebandStreamChanged.exchange(false)) {
1241 const State& s(getDrawingState());
1242 // mSidebandStreamChanged was true
1243 mSidebandStream = s.sidebandStream;
Patrick Williamsbb25f802022-08-30 23:02:34 +00001244 if (mSidebandStream != nullptr) {
1245 setTransactionFlags(eTransactionNeeded);
1246 mFlinger->setTransactionFlags(eTraversalNeeded);
1247 }
1248 recomputeVisibleRegions = true;
Patrick Williamsbb25f802022-08-30 23:02:34 +00001249 return true;
1250 }
1251 return false;
1252}
1253
Vishnu Naird47bcee2023-02-24 18:08:51 +00001254void Layer::updateTexImage(nsecs_t latchTime, bool bgColorOnly) {
Patrick Williamsbb25f802022-08-30 23:02:34 +00001255 const State& s(getDrawingState());
1256
1257 if (!s.buffer) {
Vishnu Nair7ee4f462023-04-19 09:54:09 -07001258 if (bgColorOnly || mBufferInfo.mBuffer) {
Patrick Williamsbb25f802022-08-30 23:02:34 +00001259 for (auto& handle : mDrawingState.callbackHandles) {
1260 handle->latchTime = latchTime;
1261 }
1262 }
1263 return;
1264 }
1265
1266 for (auto& handle : mDrawingState.callbackHandles) {
1267 if (handle->frameNumber == mDrawingState.frameNumber) {
1268 handle->latchTime = latchTime;
1269 }
1270 }
1271
1272 const int32_t layerId = getSequence();
1273 const uint64_t bufferId = mDrawingState.buffer->getId();
1274 const uint64_t frameNumber = mDrawingState.frameNumber;
1275 const auto acquireFence = std::make_shared<FenceTime>(mDrawingState.acquireFence);
1276 mFlinger->mTimeStats->setAcquireFence(layerId, frameNumber, acquireFence);
1277 mFlinger->mTimeStats->setLatchTime(layerId, frameNumber, latchTime);
1278
1279 mFlinger->mFrameTracer->traceFence(layerId, bufferId, frameNumber, acquireFence,
1280 FrameTracer::FrameEvent::ACQUIRE_FENCE);
1281 mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, latchTime,
1282 FrameTracer::FrameEvent::LATCH);
1283
1284 auto& bufferSurfaceFrame = mDrawingState.bufferSurfaceFrameTX;
1285 if (bufferSurfaceFrame != nullptr &&
1286 bufferSurfaceFrame->getPresentState() != PresentState::Presented) {
1287 // Update only if the bufferSurfaceFrame wasn't already presented. A Presented
1288 // bufferSurfaceFrame could be seen here if a pending state was applied successfully and we
1289 // are processing the next state.
1290 addSurfaceFramePresentedForBuffer(bufferSurfaceFrame,
1291 mDrawingState.acquireFenceTime->getSignalTime(),
1292 latchTime);
1293 mDrawingState.bufferSurfaceFrameTX.reset();
1294 }
1295
1296 std::deque<sp<CallbackHandle>> remainingHandles;
1297 mFlinger->getTransactionCallbackInvoker()
1298 .addOnCommitCallbackHandles(mDrawingState.callbackHandles, remainingHandles);
1299 mDrawingState.callbackHandles = remainingHandles;
Patrick Williamsbb25f802022-08-30 23:02:34 +00001300}
1301
1302void Layer::gatherBufferInfo() {
Vishnu Nair7ee4f462023-04-19 09:54:09 -07001303 mPreviousReleaseCallbackId = {getCurrentBufferId(), mBufferInfo.mFrameNumber};
1304 mPreviousReleaseBufferEndpoint = mBufferInfo.mReleaseBufferEndpoint;
1305 if (!mDrawingState.buffer) {
1306 mBufferInfo = {};
1307 return;
1308 }
1309
1310 if ((!mBufferInfo.mBuffer || !mDrawingState.buffer->hasSameBuffer(*mBufferInfo.mBuffer))) {
Patrick Williamsbb25f802022-08-30 23:02:34 +00001311 decrementPendingBufferCount();
1312 }
1313
Patrick Williamsbb25f802022-08-30 23:02:34 +00001314 mBufferInfo.mBuffer = mDrawingState.buffer;
Vishnu Nair7ee4f462023-04-19 09:54:09 -07001315 mBufferInfo.mReleaseBufferEndpoint = mDrawingState.releaseBufferEndpoint;
Patrick Williamsbb25f802022-08-30 23:02:34 +00001316 mBufferInfo.mFence = mDrawingState.acquireFence;
1317 mBufferInfo.mFrameNumber = mDrawingState.frameNumber;
1318 mBufferInfo.mPixelFormat =
1319 !mBufferInfo.mBuffer ? PIXEL_FORMAT_NONE : mBufferInfo.mBuffer->getPixelFormat();
1320 mBufferInfo.mFrameLatencyNeeded = true;
1321 mBufferInfo.mDesiredPresentTime = mDrawingState.desiredPresentTime;
1322 mBufferInfo.mFenceTime = std::make_shared<FenceTime>(mDrawingState.acquireFence);
Patrick Williamsbb25f802022-08-30 23:02:34 +00001323 mBufferInfo.mTransform = mDrawingState.bufferTransform;
1324 auto lastDataspace = mBufferInfo.mDataspace;
1325 mBufferInfo.mDataspace = translateDataspace(mDrawingState.dataspace);
Alec Mouri74c7ae12023-03-26 02:57:47 +00001326 if (mBufferInfo.mBuffer != nullptr) {
1327 auto& mapper = GraphicBufferMapper::get();
1328 // TODO: We should measure if it's faster to do a blind write if we're on newer api levels
1329 // and don't need to possibly remaps buffers.
1330 ui::Dataspace dataspace = ui::Dataspace::UNKNOWN;
1331 status_t err = OK;
1332 {
Vishnu Nairbe0ad902024-06-27 23:38:43 +00001333 SFTRACE_NAME("getDataspace");
Alec Mouri74c7ae12023-03-26 02:57:47 +00001334 err = mapper.getDataspace(mBufferInfo.mBuffer->getBuffer()->handle, &dataspace);
1335 }
1336 if (err != OK || dataspace != mBufferInfo.mDataspace) {
1337 {
Vishnu Nairbe0ad902024-06-27 23:38:43 +00001338 SFTRACE_NAME("setDataspace");
Alec Mouri74c7ae12023-03-26 02:57:47 +00001339 err = mapper.setDataspace(mBufferInfo.mBuffer->getBuffer()->handle,
1340 static_cast<ui::Dataspace>(mBufferInfo.mDataspace));
1341 }
1342
1343 // Some GPU drivers may cache gralloc metadata which means before we composite we need
1344 // to upsert RenderEngine's caches. Put in a special workaround to be backwards
1345 // compatible with old vendors, with a ticking clock.
1346 static const int32_t kVendorVersion =
Alec Mouri8a06fb72023-11-16 22:07:13 +00001347 base::GetIntProperty("ro.board.api_level", __ANDROID_API_FUTURE__);
Alec Mouri74c7ae12023-03-26 02:57:47 +00001348 if (const auto format =
1349 static_cast<aidl::android::hardware::graphics::common::PixelFormat>(
1350 mBufferInfo.mBuffer->getPixelFormat());
1351 err == OK && kVendorVersion < __ANDROID_API_U__ &&
1352 (format ==
1353 aidl::android::hardware::graphics::common::PixelFormat::
1354 IMPLEMENTATION_DEFINED ||
1355 format == aidl::android::hardware::graphics::common::PixelFormat::YCBCR_420_888 ||
1356 format == aidl::android::hardware::graphics::common::PixelFormat::YV12 ||
1357 format == aidl::android::hardware::graphics::common::PixelFormat::YCBCR_P010)) {
1358 mBufferInfo.mBuffer->remapBuffer();
1359 }
1360 }
1361 }
Patrick Williamsbb25f802022-08-30 23:02:34 +00001362 if (lastDataspace != mBufferInfo.mDataspace) {
John Reck68796592023-01-25 13:47:12 -05001363 mFlinger->mHdrLayerInfoChanged = true;
1364 }
Sally Qi963049b2023-03-23 14:06:21 -07001365 if (mBufferInfo.mDesiredHdrSdrRatio != mDrawingState.desiredHdrSdrRatio) {
1366 mBufferInfo.mDesiredHdrSdrRatio = mDrawingState.desiredHdrSdrRatio;
John Reck68796592023-01-25 13:47:12 -05001367 mFlinger->mHdrLayerInfoChanged = true;
Patrick Williamsbb25f802022-08-30 23:02:34 +00001368 }
1369 mBufferInfo.mCrop = computeBufferCrop(mDrawingState);
Patrick Williamsbb25f802022-08-30 23:02:34 +00001370 mBufferInfo.mTransformToDisplayInverse = mDrawingState.transformToDisplayInverse;
Patrick Williamsbb25f802022-08-30 23:02:34 +00001371}
1372
1373Rect Layer::computeBufferCrop(const State& s) {
1374 if (s.buffer && !s.bufferCrop.isEmpty()) {
1375 Rect bufferCrop;
1376 s.buffer->getBounds().intersect(s.bufferCrop, &bufferCrop);
1377 return bufferCrop;
1378 } else if (s.buffer) {
1379 return s.buffer->getBounds();
1380 } else {
1381 return s.bufferCrop;
1382 }
1383}
1384
Patrick Williamsbb25f802022-08-30 23:02:34 +00001385void Layer::decrementPendingBufferCount() {
1386 int32_t pendingBuffers = --mPendingBufferTransactions;
1387 tracePendingBufferCount(pendingBuffers);
1388}
1389
1390void Layer::tracePendingBufferCount(int32_t pendingBuffers) {
Vishnu Nairbe0ad902024-06-27 23:38:43 +00001391 SFTRACE_INT(mBlastTransactionName.c_str(), pendingBuffers);
Patrick Williamsbb25f802022-08-30 23:02:34 +00001392}
1393
Vishnu Nair3af0ec02023-02-10 04:13:48 +00001394sp<LayerFE> Layer::getCompositionEngineLayerFE(
1395 const frontend::LayerHierarchy::TraversalPath& path) {
1396 for (auto& [p, layerFE] : mLayerFEs) {
1397 if (p == path) {
1398 return layerFE;
1399 }
1400 }
Lloyd Pique70ddc672024-04-30 18:20:40 -07001401 auto layerFE = mFlinger->getFactory().createLayerFE(mName, this);
Vishnu Nair3af0ec02023-02-10 04:13:48 +00001402 mLayerFEs.emplace_back(path, layerFE);
1403 return layerFE;
1404}
1405
Leon Scroggins III5b581492023-10-31 14:29:41 -04001406void Layer::onCompositionPresented(const DisplayDevice* display,
1407 const std::shared_ptr<FenceTime>& glDoneFence,
1408 const std::shared_ptr<FenceTime>& presentFence,
Vishnu Nair39a74a92024-07-29 19:01:50 +00001409 const CompositorTiming& compositorTiming,
1410 gui::GameMode gameMode) {
Patrick Williamsbb25f802022-08-30 23:02:34 +00001411 // mFrameLatencyNeeded is true when a new frame was latched for the
1412 // composition.
1413 if (!mBufferInfo.mFrameLatencyNeeded) return;
1414
1415 for (const auto& handle : mDrawingState.callbackHandles) {
1416 handle->gpuCompositionDoneFence = glDoneFence;
1417 handle->compositorTiming = compositorTiming;
1418 }
1419
1420 // Update mFrameTracker.
1421 nsecs_t desiredPresentTime = mBufferInfo.mDesiredPresentTime;
1422 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1423
1424 const int32_t layerId = getSequence();
1425 mFlinger->mTimeStats->setDesiredTime(layerId, mCurrentFrameNumber, desiredPresentTime);
1426
1427 const auto outputLayer = findOutputLayerForDisplay(display);
1428 if (outputLayer && outputLayer->requiresClientComposition()) {
1429 nsecs_t clientCompositionTimestamp = outputLayer->getState().clientCompositionTimestamp;
1430 mFlinger->mFrameTracer->traceTimestamp(layerId, getCurrentBufferId(), mCurrentFrameNumber,
1431 clientCompositionTimestamp,
1432 FrameTracer::FrameEvent::FALLBACK_COMPOSITION);
1433 // Update the SurfaceFrames in the drawing state
1434 if (mDrawingState.bufferSurfaceFrameTX) {
1435 mDrawingState.bufferSurfaceFrameTX->setGpuComposition();
1436 }
1437 for (auto& [token, surfaceFrame] : mDrawingState.bufferlessSurfaceFramesTX) {
1438 surfaceFrame->setGpuComposition();
1439 }
1440 }
1441
1442 std::shared_ptr<FenceTime> frameReadyFence = mBufferInfo.mFenceTime;
1443 if (frameReadyFence->isValid()) {
1444 mFrameTracker.setFrameReadyFence(std::move(frameReadyFence));
1445 } else {
1446 // There was no fence for this frame, so assume that it was ready
1447 // to be presented at the desired present time.
1448 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1449 }
1450
1451 if (display) {
Dominik Laskowskife749dc2024-07-26 10:09:31 -04001452 const auto activeMode = display->refreshRateSelector().getActiveMode();
1453 const Fps refreshRate = activeMode.fps;
Patrick Williamsbb25f802022-08-30 23:02:34 +00001454 const std::optional<Fps> renderRate =
1455 mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
1456
Alec Mouri7c1d8b52023-08-29 20:14:46 +00001457 const auto vote = frameRateToSetFrameRateVotePayload(getFrameRateForLayerTree());
Patrick Williamsbb25f802022-08-30 23:02:34 +00001458
1459 if (presentFence->isValid()) {
1460 mFlinger->mTimeStats->setPresentFence(layerId, mCurrentFrameNumber, presentFence,
1461 refreshRate, renderRate, vote, gameMode);
1462 mFlinger->mFrameTracer->traceFence(layerId, getCurrentBufferId(), mCurrentFrameNumber,
1463 presentFence,
1464 FrameTracer::FrameEvent::PRESENT_FENCE);
1465 mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
1466 } else if (const auto displayId = PhysicalDisplayId::tryCast(display->getId());
1467 displayId && mFlinger->getHwComposer().isConnected(*displayId)) {
Dominik Laskowskidc2bb802022-09-28 16:02:59 -04001468 // The HWC doesn't support present fences, so use the present timestamp instead.
1469 const nsecs_t presentTimestamp =
1470 mFlinger->getHwComposer().getPresentTimestamp(*displayId);
1471
1472 const nsecs_t now = systemTime(CLOCK_MONOTONIC);
Dominik Laskowskife749dc2024-07-26 10:09:31 -04001473 const nsecs_t vsyncPeriod =
1474 mFlinger->getHwComposer()
1475 .getDisplayVsyncPeriod(*displayId)
1476 .value_opt()
1477 .value_or(activeMode.modePtr->getVsyncRate().getPeriodNsecs());
1478
Dominik Laskowskidc2bb802022-09-28 16:02:59 -04001479 const nsecs_t actualPresentTime = now - ((now - presentTimestamp) % vsyncPeriod);
1480
Patrick Williamsbb25f802022-08-30 23:02:34 +00001481 mFlinger->mTimeStats->setPresentTime(layerId, mCurrentFrameNumber, actualPresentTime,
1482 refreshRate, renderRate, vote, gameMode);
1483 mFlinger->mFrameTracer->traceTimestamp(layerId, getCurrentBufferId(),
1484 mCurrentFrameNumber, actualPresentTime,
1485 FrameTracer::FrameEvent::PRESENT_FENCE);
1486 mFrameTracker.setActualPresentTime(actualPresentTime);
1487 }
1488 }
1489
1490 mFrameTracker.advanceFrame();
1491 mBufferInfo.mFrameLatencyNeeded = false;
1492}
1493
Vishnu Nair7ee4f462023-04-19 09:54:09 -07001494bool Layer::willReleaseBufferOnLatch() const {
1495 return !mDrawingState.buffer && mBufferInfo.mBuffer;
1496}
1497
Vishnu Naird47bcee2023-02-24 18:08:51 +00001498bool Layer::latchBufferImpl(bool& recomputeVisibleRegions, nsecs_t latchTime, bool bgColorOnly) {
Vishnu Nairbe0ad902024-06-27 23:38:43 +00001499 SFTRACE_FORMAT_INSTANT("latchBuffer %s - %" PRIu64, getDebugName(),
1500 getDrawingState().frameNumber);
Patrick Williamsbb25f802022-08-30 23:02:34 +00001501
1502 bool refreshRequired = latchSidebandStream(recomputeVisibleRegions);
1503
1504 if (refreshRequired) {
1505 return refreshRequired;
1506 }
1507
1508 // If the head buffer's acquire fence hasn't signaled yet, return and
1509 // try again later
1510 if (!fenceHasSignaled()) {
Vishnu Nairbe0ad902024-06-27 23:38:43 +00001511 SFTRACE_NAME("!fenceHasSignaled()");
Patrick Williamsbb25f802022-08-30 23:02:34 +00001512 mFlinger->onLayerUpdate();
1513 return false;
1514 }
Vishnu Naird47bcee2023-02-24 18:08:51 +00001515 updateTexImage(latchTime, bgColorOnly);
Patrick Williamsbb25f802022-08-30 23:02:34 +00001516
1517 // Capture the old state of the layer for comparisons later
1518 BufferInfo oldBufferInfo = mBufferInfo;
Patrick Williamsbb25f802022-08-30 23:02:34 +00001519 mPreviousFrameNumber = mCurrentFrameNumber;
1520 mCurrentFrameNumber = mDrawingState.frameNumber;
1521 gatherBufferInfo();
1522
Vishnu Nair7ee4f462023-04-19 09:54:09 -07001523 if (mBufferInfo.mBuffer) {
1524 // We latched a buffer that will be presented soon. Clear the previously presented layer
1525 // stack list.
1526 mPreviouslyPresentedLayerStacks.clear();
1527 }
1528
1529 if (mDrawingState.buffer == nullptr) {
1530 const bool bufferReleased = oldBufferInfo.mBuffer != nullptr;
1531 recomputeVisibleRegions = bufferReleased;
1532 return bufferReleased;
1533 }
1534
Patrick Williamsbb25f802022-08-30 23:02:34 +00001535 if (oldBufferInfo.mBuffer == nullptr) {
1536 // the first time we receive a buffer, we need to trigger a
1537 // geometry invalidation.
1538 recomputeVisibleRegions = true;
1539 }
1540
1541 if ((mBufferInfo.mCrop != oldBufferInfo.mCrop) ||
1542 (mBufferInfo.mTransform != oldBufferInfo.mTransform) ||
Patrick Williamsbb25f802022-08-30 23:02:34 +00001543 (mBufferInfo.mTransformToDisplayInverse != oldBufferInfo.mTransformToDisplayInverse)) {
1544 recomputeVisibleRegions = true;
1545 }
1546
1547 if (oldBufferInfo.mBuffer != nullptr) {
1548 uint32_t bufWidth = mBufferInfo.mBuffer->getWidth();
1549 uint32_t bufHeight = mBufferInfo.mBuffer->getHeight();
1550 if (bufWidth != oldBufferInfo.mBuffer->getWidth() ||
1551 bufHeight != oldBufferInfo.mBuffer->getHeight()) {
1552 recomputeVisibleRegions = true;
1553 }
1554 }
Patrick Williamsbb25f802022-08-30 23:02:34 +00001555 return true;
1556}
1557
Patrick Williamsbb25f802022-08-30 23:02:34 +00001558bool Layer::isProtected() const {
1559 return (mBufferInfo.mBuffer != nullptr) &&
1560 (mBufferInfo.mBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
1561}
1562
Patrick Williamsbb25f802022-08-30 23:02:34 +00001563bool Layer::getTransformToDisplayInverse() const {
1564 return mBufferInfo.mTransformToDisplayInverse;
1565}
1566
1567Rect Layer::getBufferCrop() const {
1568 // this is the crop rectangle that applies to the buffer
1569 // itself (as opposed to the window)
1570 if (!mBufferInfo.mCrop.isEmpty()) {
1571 // if the buffer crop is defined, we use that
1572 return mBufferInfo.mCrop;
1573 } else if (mBufferInfo.mBuffer != nullptr) {
1574 // otherwise we use the whole buffer
1575 return mBufferInfo.mBuffer->getBounds();
1576 } else {
1577 // if we don't have a buffer yet, we use an empty/invalid crop
1578 return Rect();
1579 }
1580}
1581
1582uint32_t Layer::getBufferTransform() const {
1583 return mBufferInfo.mTransform;
1584}
1585
Patrick Williamsbb25f802022-08-30 23:02:34 +00001586ui::Dataspace Layer::translateDataspace(ui::Dataspace dataspace) {
1587 ui::Dataspace updatedDataspace = dataspace;
1588 // translate legacy dataspaces to modern dataspaces
1589 switch (dataspace) {
Alec Mouri74c7ae12023-03-26 02:57:47 +00001590 // Treat unknown dataspaces as V0_sRGB
1591 case ui::Dataspace::UNKNOWN:
Patrick Williamsbb25f802022-08-30 23:02:34 +00001592 case ui::Dataspace::SRGB:
1593 updatedDataspace = ui::Dataspace::V0_SRGB;
1594 break;
1595 case ui::Dataspace::SRGB_LINEAR:
1596 updatedDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1597 break;
1598 case ui::Dataspace::JFIF:
1599 updatedDataspace = ui::Dataspace::V0_JFIF;
1600 break;
1601 case ui::Dataspace::BT601_625:
1602 updatedDataspace = ui::Dataspace::V0_BT601_625;
1603 break;
1604 case ui::Dataspace::BT601_525:
1605 updatedDataspace = ui::Dataspace::V0_BT601_525;
1606 break;
1607 case ui::Dataspace::BT709:
1608 updatedDataspace = ui::Dataspace::V0_BT709;
1609 break;
1610 default:
1611 break;
1612 }
1613
1614 return updatedDataspace;
1615}
1616
1617sp<GraphicBuffer> Layer::getBuffer() const {
1618 return mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer() : nullptr;
1619}
1620
Chavi Weingarten328a8312023-01-26 21:17:52 +00001621bool Layer::setTrustedPresentationInfo(TrustedPresentationThresholds const& thresholds,
Chavi Weingarten076acac2023-01-19 17:20:43 +00001622 TrustedPresentationListener const& listener) {
1623 bool hadTrustedPresentationListener = hasTrustedPresentationListener();
1624 mTrustedPresentationListener = listener;
1625 mTrustedPresentationThresholds = thresholds;
1626 bool haveTrustedPresentationListener = hasTrustedPresentationListener();
1627 if (!hadTrustedPresentationListener && haveTrustedPresentationListener) {
1628 mFlinger->mNumTrustedPresentationListeners++;
1629 } else if (hadTrustedPresentationListener && !haveTrustedPresentationListener) {
1630 mFlinger->mNumTrustedPresentationListeners--;
1631 }
Chavi Weingarten328a8312023-01-26 21:17:52 +00001632
1633 // Reset trusted presentation states to ensure we start the time again.
1634 mEnteredTrustedPresentationStateTime = -1;
1635 mLastReportedTrustedPresentationState = false;
1636 mLastComputedTrustedPresentationState = false;
1637
1638 // If there's a new trusted presentation listener, the code needs to go through the composite
1639 // path to ensure it recomutes the current state and invokes the TrustedPresentationListener if
1640 // we're already in the requested state.
1641 return haveTrustedPresentationListener;
Chavi Weingarten076acac2023-01-19 17:20:43 +00001642}
1643
Patrick Williams7c9fa272024-08-30 12:38:43 +00001644void Layer::setBufferReleaseChannel(
1645 const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint>& channel) {
1646 mBufferReleaseChannel = channel;
1647}
1648
Vishnu Naira156f482023-02-22 00:23:38 +00001649void Layer::updateLastLatchTime(nsecs_t latchTime) {
1650 mLastLatchTime = latchTime;
1651}
1652
Vishnu Nairdc83d4b2024-08-15 16:29:20 +00001653void Layer::setIsSmallDirty(frontend::LayerSnapshot* snapshot) {
Jerry Chang36678002023-11-29 16:56:17 +00001654 if (!mFlinger->mScheduler->supportSmallDirtyDetection(mOwnerAppId)) {
Vishnu Nairdc83d4b2024-08-15 16:29:20 +00001655 snapshot->isSmallDirty = false;
Arthur Hungc70bee22023-06-02 01:35:52 +00001656 return;
1657 }
1658
1659 if (mWindowType != WindowInfo::Type::APPLICATION &&
1660 mWindowType != WindowInfo::Type::BASE_APPLICATION) {
Vishnu Nairdc83d4b2024-08-15 16:29:20 +00001661 snapshot->isSmallDirty = false;
Arthur Hungc70bee22023-06-02 01:35:52 +00001662 return;
1663 }
Arthur Hung69f95222023-10-04 07:39:02 +00001664
Vishnu Nairdc83d4b2024-08-15 16:29:20 +00001665 Rect bounds = snapshot->surfaceDamage.getBounds();
Arthur Hungc70bee22023-06-02 01:35:52 +00001666 if (!bounds.isValid()) {
Vishnu Nairdc83d4b2024-08-15 16:29:20 +00001667 snapshot->isSmallDirty = false;
Arthur Hungc70bee22023-06-02 01:35:52 +00001668 return;
1669 }
1670
Arthur Hung69f95222023-10-04 07:39:02 +00001671 // Transform to screen space.
Vishnu Nairdc83d4b2024-08-15 16:29:20 +00001672 bounds = snapshot->localTransform.transform(bounds);
Arthur Hung69f95222023-10-04 07:39:02 +00001673
Arthur Hungc70bee22023-06-02 01:35:52 +00001674 // If the damage region is a small dirty, this could give the hint for the layer history that
1675 // it could suppress the heuristic rate when calculating.
Vishnu Nairdc83d4b2024-08-15 16:29:20 +00001676 snapshot->isSmallDirty =
1677 mFlinger->mScheduler->isSmallDirtyArea(mOwnerAppId,
1678 bounds.getWidth() * bounds.getHeight());
Arthur Hung69f95222023-10-04 07:39:02 +00001679}
1680
Dominik Laskowskif5d0ea52021-09-26 17:27:01 -07001681} // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001682
1683#if defined(__gl_h_)
1684#error "don't include gl/gl.h in this file"
1685#endif
1686
1687#if defined(__gl2_h_)
1688#error "don't include gl2/gl2.h in this file"
1689#endif
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001690
1691// TODO(b/129481165): remove the #pragma below and fix conversion issues
1692#pragma clang diagnostic pop // ignored "-Wconversion"