xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/Layer.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2007 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker // TODO(b/129481165): remove the #pragma below and fix conversion issues
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic push
20*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wconversion"
21*38e8c45fSAndroid Build Coastguard Worker 
22*38e8c45fSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
23*38e8c45fSAndroid Build Coastguard Worker #undef LOG_TAG
24*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "Layer"
25*38e8c45fSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_GRAPHICS
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker #include <android-base/properties.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <common/trace.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/CompositionEngine.h>
32*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/Display.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/LayerFECompositionState.h>
34*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/OutputLayer.h>
35*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/impl/OutputLayerCompositionState.h>
36*38e8c45fSAndroid Build Coastguard Worker #include <cutils/compiler.h>
37*38e8c45fSAndroid Build Coastguard Worker #include <cutils/native_handle.h>
38*38e8c45fSAndroid Build Coastguard Worker #include <cutils/properties.h>
39*38e8c45fSAndroid Build Coastguard Worker #include <ftl/enum.h>
40*38e8c45fSAndroid Build Coastguard Worker #include <ftl/fake_guard.h>
41*38e8c45fSAndroid Build Coastguard Worker #include <gui/BufferItem.h>
42*38e8c45fSAndroid Build Coastguard Worker #include <gui/Surface.h>
43*38e8c45fSAndroid Build Coastguard Worker #include <math.h>
44*38e8c45fSAndroid Build Coastguard Worker #include <private/android_filesystem_config.h>
45*38e8c45fSAndroid Build Coastguard Worker #include <renderengine/RenderEngine.h>
46*38e8c45fSAndroid Build Coastguard Worker #include <stdint.h>
47*38e8c45fSAndroid Build Coastguard Worker #include <stdlib.h>
48*38e8c45fSAndroid Build Coastguard Worker #include <sys/types.h>
49*38e8c45fSAndroid Build Coastguard Worker #include <system/graphics-base-v1.0.h>
50*38e8c45fSAndroid Build Coastguard Worker #include <ui/DebugUtils.h>
51*38e8c45fSAndroid Build Coastguard Worker #include <ui/FloatRect.h>
52*38e8c45fSAndroid Build Coastguard Worker #include <ui/GraphicBuffer.h>
53*38e8c45fSAndroid Build Coastguard Worker #include <ui/HdrRenderTypeUtils.h>
54*38e8c45fSAndroid Build Coastguard Worker #include <ui/PixelFormat.h>
55*38e8c45fSAndroid Build Coastguard Worker #include <ui/Rect.h>
56*38e8c45fSAndroid Build Coastguard Worker #include <ui/Transform.h>
57*38e8c45fSAndroid Build Coastguard Worker #include <utils/Errors.h>
58*38e8c45fSAndroid Build Coastguard Worker #include <utils/Log.h>
59*38e8c45fSAndroid Build Coastguard Worker #include <utils/NativeHandle.h>
60*38e8c45fSAndroid Build Coastguard Worker #include <utils/StopWatch.h>
61*38e8c45fSAndroid Build Coastguard Worker 
62*38e8c45fSAndroid Build Coastguard Worker #include <algorithm>
63*38e8c45fSAndroid Build Coastguard Worker #include <optional>
64*38e8c45fSAndroid Build Coastguard Worker 
65*38e8c45fSAndroid Build Coastguard Worker #include "DisplayDevice.h"
66*38e8c45fSAndroid Build Coastguard Worker #include "DisplayHardware/HWComposer.h"
67*38e8c45fSAndroid Build Coastguard Worker #include "FrameTimeline.h"
68*38e8c45fSAndroid Build Coastguard Worker #include "FrameTracer/FrameTracer.h"
69*38e8c45fSAndroid Build Coastguard Worker #include "FrontEnd/LayerCreationArgs.h"
70*38e8c45fSAndroid Build Coastguard Worker #include "FrontEnd/LayerHandle.h"
71*38e8c45fSAndroid Build Coastguard Worker #include "Layer.h"
72*38e8c45fSAndroid Build Coastguard Worker #include "LayerProtoHelper.h"
73*38e8c45fSAndroid Build Coastguard Worker #include "SurfaceFlinger.h"
74*38e8c45fSAndroid Build Coastguard Worker #include "TimeStats/TimeStats.h"
75*38e8c45fSAndroid Build Coastguard Worker #include "TransactionCallbackInvoker.h"
76*38e8c45fSAndroid Build Coastguard Worker #include "TunnelModeEnabledReporter.h"
77*38e8c45fSAndroid Build Coastguard Worker #include "Utils/FenceUtils.h"
78*38e8c45fSAndroid Build Coastguard Worker 
79*38e8c45fSAndroid Build Coastguard Worker #define DEBUG_RESIZE 0
80*38e8c45fSAndroid Build Coastguard Worker #define EARLY_RELEASE_ENABLED false
81*38e8c45fSAndroid Build Coastguard Worker 
82*38e8c45fSAndroid Build Coastguard Worker namespace android {
83*38e8c45fSAndroid Build Coastguard Worker using namespace std::chrono_literals;
84*38e8c45fSAndroid Build Coastguard Worker namespace {
85*38e8c45fSAndroid Build Coastguard Worker constexpr int kDumpTableRowLength = 159;
86*38e8c45fSAndroid Build Coastguard Worker 
87*38e8c45fSAndroid Build Coastguard Worker const ui::Transform kIdentityTransform;
88*38e8c45fSAndroid Build Coastguard Worker 
frameRateToSetFrameRateVotePayload(Layer::FrameRate frameRate)89*38e8c45fSAndroid Build Coastguard Worker TimeStats::SetFrameRateVote frameRateToSetFrameRateVotePayload(Layer::FrameRate frameRate) {
90*38e8c45fSAndroid Build Coastguard Worker     using FrameRateCompatibility = TimeStats::SetFrameRateVote::FrameRateCompatibility;
91*38e8c45fSAndroid Build Coastguard Worker     using Seamlessness = TimeStats::SetFrameRateVote::Seamlessness;
92*38e8c45fSAndroid Build Coastguard Worker     const auto frameRateCompatibility = [frameRate] {
93*38e8c45fSAndroid Build Coastguard Worker         switch (frameRate.vote.type) {
94*38e8c45fSAndroid Build Coastguard Worker             case Layer::FrameRateCompatibility::Default:
95*38e8c45fSAndroid Build Coastguard Worker                 return FrameRateCompatibility::Default;
96*38e8c45fSAndroid Build Coastguard Worker             case Layer::FrameRateCompatibility::ExactOrMultiple:
97*38e8c45fSAndroid Build Coastguard Worker                 return FrameRateCompatibility::ExactOrMultiple;
98*38e8c45fSAndroid Build Coastguard Worker             default:
99*38e8c45fSAndroid Build Coastguard Worker                 return FrameRateCompatibility::Undefined;
100*38e8c45fSAndroid Build Coastguard Worker         }
101*38e8c45fSAndroid Build Coastguard Worker     }();
102*38e8c45fSAndroid Build Coastguard Worker 
103*38e8c45fSAndroid Build Coastguard Worker     const auto seamlessness = [frameRate] {
104*38e8c45fSAndroid Build Coastguard Worker         switch (frameRate.vote.seamlessness) {
105*38e8c45fSAndroid Build Coastguard Worker             case scheduler::Seamlessness::OnlySeamless:
106*38e8c45fSAndroid Build Coastguard Worker                 return Seamlessness::ShouldBeSeamless;
107*38e8c45fSAndroid Build Coastguard Worker             case scheduler::Seamlessness::SeamedAndSeamless:
108*38e8c45fSAndroid Build Coastguard Worker                 return Seamlessness::NotRequired;
109*38e8c45fSAndroid Build Coastguard Worker             default:
110*38e8c45fSAndroid Build Coastguard Worker                 return Seamlessness::Undefined;
111*38e8c45fSAndroid Build Coastguard Worker         }
112*38e8c45fSAndroid Build Coastguard Worker     }();
113*38e8c45fSAndroid Build Coastguard Worker 
114*38e8c45fSAndroid Build Coastguard Worker     return TimeStats::SetFrameRateVote{.frameRate = frameRate.vote.rate.getValue(),
115*38e8c45fSAndroid Build Coastguard Worker                                        .frameRateCompatibility = frameRateCompatibility,
116*38e8c45fSAndroid Build Coastguard Worker                                        .seamlessness = seamlessness};
117*38e8c45fSAndroid Build Coastguard Worker }
118*38e8c45fSAndroid Build Coastguard Worker 
119*38e8c45fSAndroid Build Coastguard Worker } // namespace
120*38e8c45fSAndroid Build Coastguard Worker 
121*38e8c45fSAndroid Build Coastguard Worker using namespace ftl::flag_operators;
122*38e8c45fSAndroid Build Coastguard Worker 
123*38e8c45fSAndroid Build Coastguard Worker using base::StringAppendF;
124*38e8c45fSAndroid Build Coastguard Worker using frontend::LayerSnapshot;
125*38e8c45fSAndroid Build Coastguard Worker using frontend::RoundedCornerState;
126*38e8c45fSAndroid Build Coastguard Worker using gui::GameMode;
127*38e8c45fSAndroid Build Coastguard Worker using gui::LayerMetadata;
128*38e8c45fSAndroid Build Coastguard Worker using gui::WindowInfo;
129*38e8c45fSAndroid Build Coastguard Worker using ui::Size;
130*38e8c45fSAndroid Build Coastguard Worker 
131*38e8c45fSAndroid Build Coastguard Worker using PresentState = frametimeline::SurfaceFrame::PresentState;
132*38e8c45fSAndroid Build Coastguard Worker 
Layer(const surfaceflinger::LayerCreationArgs & args)133*38e8c45fSAndroid Build Coastguard Worker Layer::Layer(const surfaceflinger::LayerCreationArgs& args)
134*38e8c45fSAndroid Build Coastguard Worker       : sequence(args.sequence),
135*38e8c45fSAndroid Build Coastguard Worker         mFlinger(sp<SurfaceFlinger>::fromExisting(args.flinger)),
136*38e8c45fSAndroid Build Coastguard Worker         mName(base::StringPrintf("%s#%d", args.name.c_str(), sequence)),
137*38e8c45fSAndroid Build Coastguard Worker         mWindowType(static_cast<WindowInfo::Type>(
138*38e8c45fSAndroid Build Coastguard Worker                 args.metadata.getInt32(gui::METADATA_WINDOW_TYPE, 0))) {
139*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Creating Layer %s", getDebugName());
140*38e8c45fSAndroid Build Coastguard Worker 
141*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.crop = {0, 0, -1, -1};
142*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.sequence = 0;
143*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.transform.set(0, 0);
144*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.frameNumber = 0;
145*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.previousFrameNumber = 0;
146*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.barrierFrameNumber = 0;
147*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.producerId = 0;
148*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.barrierProducerId = 0;
149*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.bufferTransform = 0;
150*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.transformToDisplayInverse = false;
151*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.acquireFence = sp<Fence>::make(-1);
152*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.acquireFenceTime = std::make_shared<FenceTime>(mDrawingState.acquireFence);
153*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.dataspace = ui::Dataspace::V0_SRGB;
154*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.metadata = args.metadata;
155*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.frameTimelineInfo = {};
156*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.postTime = -1;
157*38e8c45fSAndroid Build Coastguard Worker     mDeprecatedFrameTracker.setDisplayRefreshPeriod(
158*38e8c45fSAndroid Build Coastguard Worker             args.flinger->mScheduler->getPacesetterVsyncPeriod().ns());
159*38e8c45fSAndroid Build Coastguard Worker 
160*38e8c45fSAndroid Build Coastguard Worker     mOwnerUid = args.ownerUid;
161*38e8c45fSAndroid Build Coastguard Worker     mOwnerPid = args.ownerPid;
162*38e8c45fSAndroid Build Coastguard Worker     mOwnerAppId = mOwnerUid % PER_USER_RANGE;
163*38e8c45fSAndroid Build Coastguard Worker 
164*38e8c45fSAndroid Build Coastguard Worker     mPotentialCursor = args.flags & ISurfaceComposerClient::eCursorWindow;
165*38e8c45fSAndroid Build Coastguard Worker     mLayerFEs.emplace_back(frontend::LayerHierarchy::TraversalPath{static_cast<uint32_t>(sequence)},
166*38e8c45fSAndroid Build Coastguard Worker                            args.flinger->getFactory().createLayerFE(mName, this));
167*38e8c45fSAndroid Build Coastguard Worker }
168*38e8c45fSAndroid Build Coastguard Worker 
onFirstRef()169*38e8c45fSAndroid Build Coastguard Worker void Layer::onFirstRef() {
170*38e8c45fSAndroid Build Coastguard Worker     mFlinger->onLayerFirstRef(this);
171*38e8c45fSAndroid Build Coastguard Worker }
172*38e8c45fSAndroid Build Coastguard Worker 
~Layer()173*38e8c45fSAndroid Build Coastguard Worker Layer::~Layer() {
174*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(std::this_thread::get_id() != mFlinger->mMainThreadId,
175*38e8c45fSAndroid Build Coastguard Worker                         "Layer destructor called off the main thread.");
176*38e8c45fSAndroid Build Coastguard Worker 
177*38e8c45fSAndroid Build Coastguard Worker     if (mBufferInfo.mBuffer != nullptr) {
178*38e8c45fSAndroid Build Coastguard Worker         callReleaseBufferCallback(mDrawingState.releaseBufferListener,
179*38e8c45fSAndroid Build Coastguard Worker                                   mBufferInfo.mBuffer->getBuffer(), mBufferInfo.mFrameNumber,
180*38e8c45fSAndroid Build Coastguard Worker                                   mBufferInfo.mFence);
181*38e8c45fSAndroid Build Coastguard Worker     }
182*38e8c45fSAndroid Build Coastguard Worker     const int32_t layerId = getSequence();
183*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mTimeStats->onDestroy(layerId);
184*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mFrameTracer->onDestroy(layerId);
185*38e8c45fSAndroid Build Coastguard Worker 
186*38e8c45fSAndroid Build Coastguard Worker     mFlinger->onLayerDestroyed(this);
187*38e8c45fSAndroid Build Coastguard Worker 
188*38e8c45fSAndroid Build Coastguard Worker     const auto currentTime = std::chrono::steady_clock::now();
189*38e8c45fSAndroid Build Coastguard Worker     if (mBufferInfo.mTimeSinceDataspaceUpdate > std::chrono::steady_clock::time_point::min()) {
190*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mLayerEvents.emplace_back(mOwnerUid, getSequence(), mBufferInfo.mDataspace,
191*38e8c45fSAndroid Build Coastguard Worker                                             std::chrono::duration_cast<std::chrono::milliseconds>(
192*38e8c45fSAndroid Build Coastguard Worker                                                     currentTime -
193*38e8c45fSAndroid Build Coastguard Worker                                                     mBufferInfo.mTimeSinceDataspaceUpdate));
194*38e8c45fSAndroid Build Coastguard Worker     }
195*38e8c45fSAndroid Build Coastguard Worker 
196*38e8c45fSAndroid Build Coastguard Worker     if (mDrawingState.sidebandStream != nullptr) {
197*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount();
198*38e8c45fSAndroid Build Coastguard Worker     }
199*38e8c45fSAndroid Build Coastguard Worker     if (hasTrustedPresentationListener()) {
200*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mNumTrustedPresentationListeners--;
201*38e8c45fSAndroid Build Coastguard Worker         updateTrustedPresentationState(nullptr, nullptr, -1 /* time_in_ms */, true /* leaveState*/);
202*38e8c45fSAndroid Build Coastguard Worker     }
203*38e8c45fSAndroid Build Coastguard Worker }
204*38e8c45fSAndroid Build Coastguard Worker 
205*38e8c45fSAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
206*38e8c45fSAndroid Build Coastguard Worker // set-up
207*38e8c45fSAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
getHandle()208*38e8c45fSAndroid Build Coastguard Worker sp<IBinder> Layer::getHandle() {
209*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock _l(mLock);
210*38e8c45fSAndroid Build Coastguard Worker     if (mGetHandleCalled) {
211*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Get handle called twice" );
212*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
213*38e8c45fSAndroid Build Coastguard Worker     }
214*38e8c45fSAndroid Build Coastguard Worker     mGetHandleCalled = true;
215*38e8c45fSAndroid Build Coastguard Worker     mHandleAlive = true;
216*38e8c45fSAndroid Build Coastguard Worker     return sp<LayerHandle>::make(mFlinger, sp<Layer>::fromExisting(this));
217*38e8c45fSAndroid Build Coastguard Worker }
218*38e8c45fSAndroid Build Coastguard Worker 
219*38e8c45fSAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
220*38e8c45fSAndroid Build Coastguard Worker // h/w composer set-up
221*38e8c45fSAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
222*38e8c45fSAndroid Build Coastguard Worker 
223*38e8c45fSAndroid Build Coastguard Worker // No early returns.
updateTrustedPresentationState(const DisplayDevice * display,const frontend::LayerSnapshot * snapshot,int64_t time_in_ms,bool leaveState)224*38e8c45fSAndroid Build Coastguard Worker void Layer::updateTrustedPresentationState(const DisplayDevice* display,
225*38e8c45fSAndroid Build Coastguard Worker                                            const frontend::LayerSnapshot* snapshot,
226*38e8c45fSAndroid Build Coastguard Worker                                            int64_t time_in_ms, bool leaveState) {
227*38e8c45fSAndroid Build Coastguard Worker     if (!hasTrustedPresentationListener()) {
228*38e8c45fSAndroid Build Coastguard Worker         return;
229*38e8c45fSAndroid Build Coastguard Worker     }
230*38e8c45fSAndroid Build Coastguard Worker     const bool lastState = mLastComputedTrustedPresentationState;
231*38e8c45fSAndroid Build Coastguard Worker     mLastComputedTrustedPresentationState = false;
232*38e8c45fSAndroid Build Coastguard Worker 
233*38e8c45fSAndroid Build Coastguard Worker     if (!leaveState) {
234*38e8c45fSAndroid Build Coastguard Worker         const auto outputLayer = findOutputLayerForDisplay(display, snapshot->path);
235*38e8c45fSAndroid Build Coastguard Worker         if (outputLayer != nullptr) {
236*38e8c45fSAndroid Build Coastguard Worker             if (outputLayer->getState().coveredRegionExcludingDisplayOverlays) {
237*38e8c45fSAndroid Build Coastguard Worker                 Region coveredRegion =
238*38e8c45fSAndroid Build Coastguard Worker                         *outputLayer->getState().coveredRegionExcludingDisplayOverlays;
239*38e8c45fSAndroid Build Coastguard Worker                 mLastComputedTrustedPresentationState =
240*38e8c45fSAndroid Build Coastguard Worker                         computeTrustedPresentationState(snapshot->geomLayerBounds,
241*38e8c45fSAndroid Build Coastguard Worker                                                         snapshot->sourceBounds(), coveredRegion,
242*38e8c45fSAndroid Build Coastguard Worker                                                         snapshot->transformedBounds,
243*38e8c45fSAndroid Build Coastguard Worker                                                         snapshot->alpha,
244*38e8c45fSAndroid Build Coastguard Worker                                                         snapshot->geomLayerTransform,
245*38e8c45fSAndroid Build Coastguard Worker                                                         mTrustedPresentationThresholds);
246*38e8c45fSAndroid Build Coastguard Worker             } else {
247*38e8c45fSAndroid Build Coastguard Worker                 ALOGE("CoveredRegionExcludingDisplayOverlays was not set for %s. Don't compute "
248*38e8c45fSAndroid Build Coastguard Worker                       "TrustedPresentationState",
249*38e8c45fSAndroid Build Coastguard Worker                       getDebugName());
250*38e8c45fSAndroid Build Coastguard Worker             }
251*38e8c45fSAndroid Build Coastguard Worker         }
252*38e8c45fSAndroid Build Coastguard Worker     }
253*38e8c45fSAndroid Build Coastguard Worker     const bool newState = mLastComputedTrustedPresentationState;
254*38e8c45fSAndroid Build Coastguard Worker     if (lastState && !newState) {
255*38e8c45fSAndroid Build Coastguard Worker         // We were in the trusted presentation state, but now we left it,
256*38e8c45fSAndroid Build Coastguard Worker         // emit the callback if needed
257*38e8c45fSAndroid Build Coastguard Worker         if (mLastReportedTrustedPresentationState) {
258*38e8c45fSAndroid Build Coastguard Worker             mLastReportedTrustedPresentationState = false;
259*38e8c45fSAndroid Build Coastguard Worker             mTrustedPresentationListener.invoke(false);
260*38e8c45fSAndroid Build Coastguard Worker         }
261*38e8c45fSAndroid Build Coastguard Worker         // Reset the timer
262*38e8c45fSAndroid Build Coastguard Worker         mEnteredTrustedPresentationStateTime = -1;
263*38e8c45fSAndroid Build Coastguard Worker     } else if (!lastState && newState) {
264*38e8c45fSAndroid Build Coastguard Worker         // We were not in the trusted presentation state, but we entered it, begin the timer
265*38e8c45fSAndroid Build Coastguard Worker         // and make sure this gets called at least once more!
266*38e8c45fSAndroid Build Coastguard Worker         mEnteredTrustedPresentationStateTime = time_in_ms;
267*38e8c45fSAndroid Build Coastguard Worker         mFlinger->forceFutureUpdate(mTrustedPresentationThresholds.stabilityRequirementMs * 1.5);
268*38e8c45fSAndroid Build Coastguard Worker     }
269*38e8c45fSAndroid Build Coastguard Worker 
270*38e8c45fSAndroid Build Coastguard Worker     // Has the timer elapsed, but we are still in the state? Emit a callback if needed
271*38e8c45fSAndroid Build Coastguard Worker     if (!mLastReportedTrustedPresentationState && newState &&
272*38e8c45fSAndroid Build Coastguard Worker         (time_in_ms - mEnteredTrustedPresentationStateTime >
273*38e8c45fSAndroid Build Coastguard Worker          mTrustedPresentationThresholds.stabilityRequirementMs)) {
274*38e8c45fSAndroid Build Coastguard Worker         mLastReportedTrustedPresentationState = true;
275*38e8c45fSAndroid Build Coastguard Worker         mTrustedPresentationListener.invoke(true);
276*38e8c45fSAndroid Build Coastguard Worker     }
277*38e8c45fSAndroid Build Coastguard Worker }
278*38e8c45fSAndroid Build Coastguard Worker 
279*38e8c45fSAndroid Build Coastguard Worker /**
280*38e8c45fSAndroid Build Coastguard Worker  * See SurfaceComposerClient.h: setTrustedPresentationCallback for discussion
281*38e8c45fSAndroid Build Coastguard Worker  * of how the parameters and thresholds are interpreted. The general spirit is
282*38e8c45fSAndroid Build Coastguard Worker  * to produce an upper bound on the amount of the buffer which was presented.
283*38e8c45fSAndroid Build Coastguard Worker  */
computeTrustedPresentationState(const FloatRect & bounds,const FloatRect & sourceBounds,const Region & coveredRegion,const FloatRect & screenBounds,float alpha,const ui::Transform & effectiveTransform,const TrustedPresentationThresholds & thresholds)284*38e8c45fSAndroid Build Coastguard Worker bool Layer::computeTrustedPresentationState(const FloatRect& bounds, const FloatRect& sourceBounds,
285*38e8c45fSAndroid Build Coastguard Worker                                             const Region& coveredRegion,
286*38e8c45fSAndroid Build Coastguard Worker                                             const FloatRect& screenBounds, float alpha,
287*38e8c45fSAndroid Build Coastguard Worker                                             const ui::Transform& effectiveTransform,
288*38e8c45fSAndroid Build Coastguard Worker                                             const TrustedPresentationThresholds& thresholds) {
289*38e8c45fSAndroid Build Coastguard Worker     if (alpha < thresholds.minAlpha) {
290*38e8c45fSAndroid Build Coastguard Worker         return false;
291*38e8c45fSAndroid Build Coastguard Worker     }
292*38e8c45fSAndroid Build Coastguard Worker     if (sourceBounds.getWidth() == 0 || sourceBounds.getHeight() == 0) {
293*38e8c45fSAndroid Build Coastguard Worker         return false;
294*38e8c45fSAndroid Build Coastguard Worker     }
295*38e8c45fSAndroid Build Coastguard Worker     if (screenBounds.getWidth() == 0 || screenBounds.getHeight() == 0) {
296*38e8c45fSAndroid Build Coastguard Worker         return false;
297*38e8c45fSAndroid Build Coastguard Worker     }
298*38e8c45fSAndroid Build Coastguard Worker 
299*38e8c45fSAndroid Build Coastguard Worker     const float sx = effectiveTransform.dsdx();
300*38e8c45fSAndroid Build Coastguard Worker     const float sy = effectiveTransform.dsdy();
301*38e8c45fSAndroid Build Coastguard Worker     float fractionRendered = std::min(sx * sy, 1.0f);
302*38e8c45fSAndroid Build Coastguard Worker 
303*38e8c45fSAndroid Build Coastguard Worker     float boundsOverSourceW = bounds.getWidth() / (float)sourceBounds.getWidth();
304*38e8c45fSAndroid Build Coastguard Worker     float boundsOverSourceH = bounds.getHeight() / (float)sourceBounds.getHeight();
305*38e8c45fSAndroid Build Coastguard Worker     fractionRendered *= boundsOverSourceW * boundsOverSourceH;
306*38e8c45fSAndroid Build Coastguard Worker 
307*38e8c45fSAndroid Build Coastguard Worker     Region tJunctionFreeRegion = Region::createTJunctionFreeRegion(coveredRegion);
308*38e8c45fSAndroid Build Coastguard Worker     // Compute the size of all the rects since they may be disconnected.
309*38e8c45fSAndroid Build Coastguard Worker     float coveredSize = 0;
310*38e8c45fSAndroid Build Coastguard Worker     for (auto rect = tJunctionFreeRegion.begin(); rect < tJunctionFreeRegion.end(); rect++) {
311*38e8c45fSAndroid Build Coastguard Worker         float size = rect->width() * rect->height();
312*38e8c45fSAndroid Build Coastguard Worker         coveredSize += size;
313*38e8c45fSAndroid Build Coastguard Worker     }
314*38e8c45fSAndroid Build Coastguard Worker 
315*38e8c45fSAndroid Build Coastguard Worker     fractionRendered *= (1 - (coveredSize / (screenBounds.getWidth() * screenBounds.getHeight())));
316*38e8c45fSAndroid Build Coastguard Worker 
317*38e8c45fSAndroid Build Coastguard Worker     if (fractionRendered < thresholds.minFractionRendered) {
318*38e8c45fSAndroid Build Coastguard Worker         return false;
319*38e8c45fSAndroid Build Coastguard Worker     }
320*38e8c45fSAndroid Build Coastguard Worker 
321*38e8c45fSAndroid Build Coastguard Worker     return true;
322*38e8c45fSAndroid Build Coastguard Worker }
323*38e8c45fSAndroid Build Coastguard Worker 
getCroppedBufferSize(const State & s) const324*38e8c45fSAndroid Build Coastguard Worker Rect Layer::getCroppedBufferSize(const State& s) const {
325*38e8c45fSAndroid Build Coastguard Worker     Rect size = getBufferSize(s);
326*38e8c45fSAndroid Build Coastguard Worker     Rect crop = Rect(getCrop(s));
327*38e8c45fSAndroid Build Coastguard Worker     if (!crop.isEmpty() && size.isValid()) {
328*38e8c45fSAndroid Build Coastguard Worker         size.intersect(crop, &size);
329*38e8c45fSAndroid Build Coastguard Worker     } else if (!crop.isEmpty()) {
330*38e8c45fSAndroid Build Coastguard Worker         size = crop;
331*38e8c45fSAndroid Build Coastguard Worker     }
332*38e8c45fSAndroid Build Coastguard Worker     return size;
333*38e8c45fSAndroid Build Coastguard Worker }
334*38e8c45fSAndroid Build Coastguard Worker 
getDebugName() const335*38e8c45fSAndroid Build Coastguard Worker const char* Layer::getDebugName() const {
336*38e8c45fSAndroid Build Coastguard Worker     return mName.c_str();
337*38e8c45fSAndroid Build Coastguard Worker }
338*38e8c45fSAndroid Build Coastguard Worker 
339*38e8c45fSAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
340*38e8c45fSAndroid Build Coastguard Worker // drawing...
341*38e8c45fSAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
342*38e8c45fSAndroid Build Coastguard Worker 
getCompositionType(const DisplayDevice & display) const343*38e8c45fSAndroid Build Coastguard Worker aidl::android::hardware::graphics::composer3::Composition Layer::getCompositionType(
344*38e8c45fSAndroid Build Coastguard Worker         const DisplayDevice& display) const {
345*38e8c45fSAndroid Build Coastguard Worker     const auto outputLayer = findOutputLayerForDisplay(&display);
346*38e8c45fSAndroid Build Coastguard Worker     return getCompositionType(outputLayer);
347*38e8c45fSAndroid Build Coastguard Worker }
348*38e8c45fSAndroid Build Coastguard Worker 
getCompositionType(const compositionengine::OutputLayer * outputLayer) const349*38e8c45fSAndroid Build Coastguard Worker aidl::android::hardware::graphics::composer3::Composition Layer::getCompositionType(
350*38e8c45fSAndroid Build Coastguard Worker         const compositionengine::OutputLayer* outputLayer) const {
351*38e8c45fSAndroid Build Coastguard Worker     if (outputLayer == nullptr) {
352*38e8c45fSAndroid Build Coastguard Worker         return aidl::android::hardware::graphics::composer3::Composition::INVALID;
353*38e8c45fSAndroid Build Coastguard Worker     }
354*38e8c45fSAndroid Build Coastguard Worker     if (outputLayer->getState().hwc) {
355*38e8c45fSAndroid Build Coastguard Worker         return (*outputLayer->getState().hwc).hwcCompositionType;
356*38e8c45fSAndroid Build Coastguard Worker     } else {
357*38e8c45fSAndroid Build Coastguard Worker         return aidl::android::hardware::graphics::composer3::Composition::CLIENT;
358*38e8c45fSAndroid Build Coastguard Worker     }
359*38e8c45fSAndroid Build Coastguard Worker }
360*38e8c45fSAndroid Build Coastguard Worker 
361*38e8c45fSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
362*38e8c45fSAndroid Build Coastguard Worker // transaction
363*38e8c45fSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
364*38e8c45fSAndroid Build Coastguard Worker 
commitTransaction()365*38e8c45fSAndroid Build Coastguard Worker void Layer::commitTransaction() {
366*38e8c45fSAndroid Build Coastguard Worker     // Set the present state for all bufferlessSurfaceFramesTX to Presented. The
367*38e8c45fSAndroid Build Coastguard Worker     // bufferSurfaceFrameTX will be presented in latchBuffer.
368*38e8c45fSAndroid Build Coastguard Worker     for (auto& [token, surfaceFrame] : mDrawingState.bufferlessSurfaceFramesTX) {
369*38e8c45fSAndroid Build Coastguard Worker         if (surfaceFrame->getPresentState() != PresentState::Presented) {
370*38e8c45fSAndroid Build Coastguard Worker             // With applyPendingStates, we could end up having presented surfaceframes from previous
371*38e8c45fSAndroid Build Coastguard Worker             // states
372*38e8c45fSAndroid Build Coastguard Worker             surfaceFrame->setPresentState(PresentState::Presented, mLastLatchTime);
373*38e8c45fSAndroid Build Coastguard Worker             mFlinger->mFrameTimeline->addSurfaceFrame(surfaceFrame);
374*38e8c45fSAndroid Build Coastguard Worker         }
375*38e8c45fSAndroid Build Coastguard Worker     }
376*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.bufferlessSurfaceFramesTX.clear();
377*38e8c45fSAndroid Build Coastguard Worker }
378*38e8c45fSAndroid Build Coastguard Worker 
setTransactionFlags(uint32_t mask)379*38e8c45fSAndroid Build Coastguard Worker void Layer::setTransactionFlags(uint32_t mask) {
380*38e8c45fSAndroid Build Coastguard Worker     mTransactionFlags |= mask;
381*38e8c45fSAndroid Build Coastguard Worker }
382*38e8c45fSAndroid Build Coastguard Worker 
setCrop(const FloatRect & crop)383*38e8c45fSAndroid Build Coastguard Worker bool Layer::setCrop(const FloatRect& crop) {
384*38e8c45fSAndroid Build Coastguard Worker     if (mDrawingState.crop == crop) return false;
385*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.sequence++;
386*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.crop = crop;
387*38e8c45fSAndroid Build Coastguard Worker 
388*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eTransactionNeeded);
389*38e8c45fSAndroid Build Coastguard Worker     return true;
390*38e8c45fSAndroid Build Coastguard Worker }
391*38e8c45fSAndroid Build Coastguard Worker 
isLayerFocusedBasedOnPriority(int32_t priority)392*38e8c45fSAndroid Build Coastguard Worker bool Layer::isLayerFocusedBasedOnPriority(int32_t priority) {
393*38e8c45fSAndroid Build Coastguard Worker     return priority == PRIORITY_FOCUSED_WITH_MODE || priority == PRIORITY_FOCUSED_WITHOUT_MODE;
394*38e8c45fSAndroid Build Coastguard Worker };
395*38e8c45fSAndroid Build Coastguard Worker 
setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo & info,nsecs_t postTime,gui::GameMode gameMode)396*38e8c45fSAndroid Build Coastguard Worker void Layer::setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info,
397*38e8c45fSAndroid Build Coastguard Worker                                                       nsecs_t postTime, gui::GameMode gameMode) {
398*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.postTime = postTime;
399*38e8c45fSAndroid Build Coastguard Worker 
400*38e8c45fSAndroid Build Coastguard Worker     // Check if one of the bufferlessSurfaceFramesTX contains the same vsyncId. This can happen if
401*38e8c45fSAndroid Build Coastguard Worker     // there are two transactions with the same token, the first one without a buffer and the
402*38e8c45fSAndroid Build Coastguard Worker     // second one with a buffer. We promote the bufferlessSurfaceFrame to a bufferSurfaceFrameTX
403*38e8c45fSAndroid Build Coastguard Worker     // in that case.
404*38e8c45fSAndroid Build Coastguard Worker     auto it = mDrawingState.bufferlessSurfaceFramesTX.find(info.vsyncId);
405*38e8c45fSAndroid Build Coastguard Worker     if (it != mDrawingState.bufferlessSurfaceFramesTX.end()) {
406*38e8c45fSAndroid Build Coastguard Worker         // Promote the bufferlessSurfaceFrame to a bufferSurfaceFrameTX
407*38e8c45fSAndroid Build Coastguard Worker         mDrawingState.bufferSurfaceFrameTX = it->second;
408*38e8c45fSAndroid Build Coastguard Worker         mDrawingState.bufferlessSurfaceFramesTX.erase(it);
409*38e8c45fSAndroid Build Coastguard Worker         mDrawingState.bufferSurfaceFrameTX->promoteToBuffer();
410*38e8c45fSAndroid Build Coastguard Worker         mDrawingState.bufferSurfaceFrameTX->setActualQueueTime(postTime);
411*38e8c45fSAndroid Build Coastguard Worker     } else {
412*38e8c45fSAndroid Build Coastguard Worker         mDrawingState.bufferSurfaceFrameTX =
413*38e8c45fSAndroid Build Coastguard Worker                 createSurfaceFrameForBuffer(info, postTime, mTransactionName, gameMode);
414*38e8c45fSAndroid Build Coastguard Worker     }
415*38e8c45fSAndroid Build Coastguard Worker 
416*38e8c45fSAndroid Build Coastguard Worker     setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName, gameMode);
417*38e8c45fSAndroid Build Coastguard Worker }
418*38e8c45fSAndroid Build Coastguard Worker 
setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo & info,nsecs_t postTime,gui::GameMode gameMode)419*38e8c45fSAndroid Build Coastguard Worker void Layer::setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo& info,
420*38e8c45fSAndroid Build Coastguard Worker                                                           nsecs_t postTime,
421*38e8c45fSAndroid Build Coastguard Worker                                                           gui::GameMode gameMode) {
422*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.frameTimelineInfo = info;
423*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.postTime = postTime;
424*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eTransactionNeeded);
425*38e8c45fSAndroid Build Coastguard Worker 
426*38e8c45fSAndroid Build Coastguard Worker     if (const auto& bufferSurfaceFrameTX = mDrawingState.bufferSurfaceFrameTX;
427*38e8c45fSAndroid Build Coastguard Worker         bufferSurfaceFrameTX != nullptr) {
428*38e8c45fSAndroid Build Coastguard Worker         if (bufferSurfaceFrameTX->getToken() == info.vsyncId) {
429*38e8c45fSAndroid Build Coastguard Worker             // BufferSurfaceFrame takes precedence over BufferlessSurfaceFrame. If the same token is
430*38e8c45fSAndroid Build Coastguard Worker             // being used for BufferSurfaceFrame, don't create a new one.
431*38e8c45fSAndroid Build Coastguard Worker             return;
432*38e8c45fSAndroid Build Coastguard Worker         }
433*38e8c45fSAndroid Build Coastguard Worker     }
434*38e8c45fSAndroid Build Coastguard Worker     // For Transactions without a buffer, we create only one SurfaceFrame per vsyncId. If multiple
435*38e8c45fSAndroid Build Coastguard Worker     // transactions use the same vsyncId, we just treat them as one SurfaceFrame (unless they are
436*38e8c45fSAndroid Build Coastguard Worker     // targeting different vsyncs).
437*38e8c45fSAndroid Build Coastguard Worker     auto it = mDrawingState.bufferlessSurfaceFramesTX.find(info.vsyncId);
438*38e8c45fSAndroid Build Coastguard Worker     if (it == mDrawingState.bufferlessSurfaceFramesTX.end()) {
439*38e8c45fSAndroid Build Coastguard Worker         auto surfaceFrame = createSurfaceFrameForTransaction(info, postTime, gameMode);
440*38e8c45fSAndroid Build Coastguard Worker         mDrawingState.bufferlessSurfaceFramesTX[info.vsyncId] = surfaceFrame;
441*38e8c45fSAndroid Build Coastguard Worker     } else {
442*38e8c45fSAndroid Build Coastguard Worker         if (it->second->getPresentState() == PresentState::Presented) {
443*38e8c45fSAndroid Build Coastguard Worker             // If the SurfaceFrame was already presented, its safe to overwrite it since it must
444*38e8c45fSAndroid Build Coastguard Worker             // have been from previous vsync.
445*38e8c45fSAndroid Build Coastguard Worker             it->second = createSurfaceFrameForTransaction(info, postTime, gameMode);
446*38e8c45fSAndroid Build Coastguard Worker         }
447*38e8c45fSAndroid Build Coastguard Worker     }
448*38e8c45fSAndroid Build Coastguard Worker 
449*38e8c45fSAndroid Build Coastguard Worker     setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName, gameMode);
450*38e8c45fSAndroid Build Coastguard Worker }
451*38e8c45fSAndroid Build Coastguard Worker 
addSurfaceFrameDroppedForBuffer(std::shared_ptr<frametimeline::SurfaceFrame> & surfaceFrame,nsecs_t dropTime)452*38e8c45fSAndroid Build Coastguard Worker void Layer::addSurfaceFrameDroppedForBuffer(
453*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame, nsecs_t dropTime) {
454*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setDropTime(dropTime);
455*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setPresentState(PresentState::Dropped);
456*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mFrameTimeline->addSurfaceFrame(surfaceFrame);
457*38e8c45fSAndroid Build Coastguard Worker }
458*38e8c45fSAndroid Build Coastguard Worker 
addSurfaceFramePresentedForBuffer(std::shared_ptr<frametimeline::SurfaceFrame> & surfaceFrame,nsecs_t acquireFenceTime,nsecs_t currentLatchTime)459*38e8c45fSAndroid Build Coastguard Worker void Layer::addSurfaceFramePresentedForBuffer(
460*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame, nsecs_t acquireFenceTime,
461*38e8c45fSAndroid Build Coastguard Worker         nsecs_t currentLatchTime) {
462*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setAcquireFenceTime(acquireFenceTime);
463*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setPresentState(PresentState::Presented, mLastLatchTime);
464*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mFrameTimeline->addSurfaceFrame(surfaceFrame);
465*38e8c45fSAndroid Build Coastguard Worker     updateLastLatchTime(currentLatchTime);
466*38e8c45fSAndroid Build Coastguard Worker }
467*38e8c45fSAndroid Build Coastguard Worker 
createSurfaceFrameForTransaction(const FrameTimelineInfo & info,nsecs_t postTime,gui::GameMode gameMode)468*38e8c45fSAndroid Build Coastguard Worker std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForTransaction(
469*38e8c45fSAndroid Build Coastguard Worker         const FrameTimelineInfo& info, nsecs_t postTime, gui::GameMode gameMode) {
470*38e8c45fSAndroid Build Coastguard Worker     auto surfaceFrame =
471*38e8c45fSAndroid Build Coastguard Worker             mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid,
472*38e8c45fSAndroid Build Coastguard Worker                                                                  getSequence(), mName,
473*38e8c45fSAndroid Build Coastguard Worker                                                                  mTransactionName,
474*38e8c45fSAndroid Build Coastguard Worker                                                                  /*isBuffer*/ false, gameMode);
475*38e8c45fSAndroid Build Coastguard Worker     // Buffer hasn't yet been latched, so use mDrawingState
476*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setDesiredPresentTime(mDrawingState.desiredPresentTime);
477*38e8c45fSAndroid Build Coastguard Worker 
478*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setActualStartTime(info.startTimeNanos);
479*38e8c45fSAndroid Build Coastguard Worker     // For Transactions, the post time is considered to be both queue and acquire fence time.
480*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setActualQueueTime(postTime);
481*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setAcquireFenceTime(postTime);
482*38e8c45fSAndroid Build Coastguard Worker     const auto fps = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
483*38e8c45fSAndroid Build Coastguard Worker     if (fps) {
484*38e8c45fSAndroid Build Coastguard Worker         surfaceFrame->setRenderRate(*fps);
485*38e8c45fSAndroid Build Coastguard Worker     }
486*38e8c45fSAndroid Build Coastguard Worker     return surfaceFrame;
487*38e8c45fSAndroid Build Coastguard Worker }
488*38e8c45fSAndroid Build Coastguard Worker 
createSurfaceFrameForBuffer(const FrameTimelineInfo & info,nsecs_t queueTime,std::string debugName,gui::GameMode gameMode)489*38e8c45fSAndroid Build Coastguard Worker std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForBuffer(
490*38e8c45fSAndroid Build Coastguard Worker         const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName,
491*38e8c45fSAndroid Build Coastguard Worker         gui::GameMode gameMode) {
492*38e8c45fSAndroid Build Coastguard Worker     auto surfaceFrame =
493*38e8c45fSAndroid Build Coastguard Worker             mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid,
494*38e8c45fSAndroid Build Coastguard Worker                                                                  getSequence(), mName, debugName,
495*38e8c45fSAndroid Build Coastguard Worker                                                                  /*isBuffer*/ true, gameMode);
496*38e8c45fSAndroid Build Coastguard Worker     // Buffer hasn't yet been latched, so use mDrawingState
497*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setDesiredPresentTime(mDrawingState.desiredPresentTime);
498*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setActualStartTime(info.startTimeNanos);
499*38e8c45fSAndroid Build Coastguard Worker     // For buffers, acquire fence time will set during latch.
500*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setActualQueueTime(queueTime);
501*38e8c45fSAndroid Build Coastguard Worker     const auto fps = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
502*38e8c45fSAndroid Build Coastguard Worker     if (fps) {
503*38e8c45fSAndroid Build Coastguard Worker         surfaceFrame->setRenderRate(*fps);
504*38e8c45fSAndroid Build Coastguard Worker     }
505*38e8c45fSAndroid Build Coastguard Worker     return surfaceFrame;
506*38e8c45fSAndroid Build Coastguard Worker }
507*38e8c45fSAndroid Build Coastguard Worker 
setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo & info,nsecs_t postTime,std::string debugName,gui::GameMode gameMode)508*38e8c45fSAndroid Build Coastguard Worker void Layer::setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, nsecs_t postTime,
509*38e8c45fSAndroid Build Coastguard Worker                                                   std::string debugName, gui::GameMode gameMode) {
510*38e8c45fSAndroid Build Coastguard Worker     if (info.skippedFrameVsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) {
511*38e8c45fSAndroid Build Coastguard Worker         return;
512*38e8c45fSAndroid Build Coastguard Worker     }
513*38e8c45fSAndroid Build Coastguard Worker 
514*38e8c45fSAndroid Build Coastguard Worker     FrameTimelineInfo skippedFrameTimelineInfo = info;
515*38e8c45fSAndroid Build Coastguard Worker     skippedFrameTimelineInfo.vsyncId = info.skippedFrameVsyncId;
516*38e8c45fSAndroid Build Coastguard Worker 
517*38e8c45fSAndroid Build Coastguard Worker     auto surfaceFrame =
518*38e8c45fSAndroid Build Coastguard Worker             mFlinger->mFrameTimeline->createSurfaceFrameForToken(skippedFrameTimelineInfo,
519*38e8c45fSAndroid Build Coastguard Worker                                                                  mOwnerPid, mOwnerUid,
520*38e8c45fSAndroid Build Coastguard Worker                                                                  getSequence(), mName, debugName,
521*38e8c45fSAndroid Build Coastguard Worker                                                                  /*isBuffer*/ false, gameMode);
522*38e8c45fSAndroid Build Coastguard Worker     // Buffer hasn't yet been latched, so use mDrawingState
523*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setDesiredPresentTime(mDrawingState.desiredPresentTime);
524*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setActualStartTime(skippedFrameTimelineInfo.skippedFrameStartTimeNanos);
525*38e8c45fSAndroid Build Coastguard Worker     // For Transactions, the post time is considered to be both queue and acquire fence time.
526*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setActualQueueTime(postTime);
527*38e8c45fSAndroid Build Coastguard Worker     surfaceFrame->setAcquireFenceTime(postTime);
528*38e8c45fSAndroid Build Coastguard Worker     const auto fps = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
529*38e8c45fSAndroid Build Coastguard Worker     if (fps) {
530*38e8c45fSAndroid Build Coastguard Worker         surfaceFrame->setRenderRate(*fps);
531*38e8c45fSAndroid Build Coastguard Worker     }
532*38e8c45fSAndroid Build Coastguard Worker     addSurfaceFrameDroppedForBuffer(surfaceFrame, postTime);
533*38e8c45fSAndroid Build Coastguard Worker }
534*38e8c45fSAndroid Build Coastguard Worker 
setFrameRateForLayerTree(FrameRate frameRate,const scheduler::LayerProps & layerProps,nsecs_t now)535*38e8c45fSAndroid Build Coastguard Worker bool Layer::setFrameRateForLayerTree(FrameRate frameRate, const scheduler::LayerProps& layerProps,
536*38e8c45fSAndroid Build Coastguard Worker                                      nsecs_t now) {
537*38e8c45fSAndroid Build Coastguard Worker     if (mDrawingState.frameRateForLayerTree == frameRate) {
538*38e8c45fSAndroid Build Coastguard Worker         return false;
539*38e8c45fSAndroid Build Coastguard Worker     }
540*38e8c45fSAndroid Build Coastguard Worker 
541*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.frameRateForLayerTree = frameRate;
542*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mScheduler
543*38e8c45fSAndroid Build Coastguard Worker             ->recordLayerHistory(sequence, layerProps, now, now,
544*38e8c45fSAndroid Build Coastguard Worker                                  scheduler::LayerHistory::LayerUpdateType::SetFrameRate);
545*38e8c45fSAndroid Build Coastguard Worker     return true;
546*38e8c45fSAndroid Build Coastguard Worker }
547*38e8c45fSAndroid Build Coastguard Worker 
getFrameRateForLayerTree() const548*38e8c45fSAndroid Build Coastguard Worker Layer::FrameRate Layer::getFrameRateForLayerTree() const {
549*38e8c45fSAndroid Build Coastguard Worker     return getDrawingState().frameRateForLayerTree;
550*38e8c45fSAndroid Build Coastguard Worker }
551*38e8c45fSAndroid Build Coastguard Worker 
552*38e8c45fSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
553*38e8c45fSAndroid Build Coastguard Worker // debugging
554*38e8c45fSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
555*38e8c45fSAndroid Build Coastguard Worker 
miniDumpHeader(std::string & result)556*38e8c45fSAndroid Build Coastguard Worker void Layer::miniDumpHeader(std::string& result) {
557*38e8c45fSAndroid Build Coastguard Worker     result.append(kDumpTableRowLength, '-');
558*38e8c45fSAndroid Build Coastguard Worker     result.append("\n");
559*38e8c45fSAndroid Build Coastguard Worker     result.append(" Layer name\n");
560*38e8c45fSAndroid Build Coastguard Worker     result.append("           Z | ");
561*38e8c45fSAndroid Build Coastguard Worker     result.append(" Window Type | ");
562*38e8c45fSAndroid Build Coastguard Worker     result.append(" Comp Type | ");
563*38e8c45fSAndroid Build Coastguard Worker     result.append(" Transform | ");
564*38e8c45fSAndroid Build Coastguard Worker     result.append("  Disp Frame (LTRB) | ");
565*38e8c45fSAndroid Build Coastguard Worker     result.append("         Source Crop (LTRB) | ");
566*38e8c45fSAndroid Build Coastguard Worker     result.append("    Frame Rate (Explicit) (Seamlessness) [Focused]\n");
567*38e8c45fSAndroid Build Coastguard Worker     result.append(kDumpTableRowLength, '-');
568*38e8c45fSAndroid Build Coastguard Worker     result.append("\n");
569*38e8c45fSAndroid Build Coastguard Worker }
570*38e8c45fSAndroid Build Coastguard Worker 
miniDump(std::string & result,const frontend::LayerSnapshot & snapshot,const DisplayDevice & display) const571*38e8c45fSAndroid Build Coastguard Worker void Layer::miniDump(std::string& result, const frontend::LayerSnapshot& snapshot,
572*38e8c45fSAndroid Build Coastguard Worker                      const DisplayDevice& display) const {
573*38e8c45fSAndroid Build Coastguard Worker     const auto outputLayer = findOutputLayerForDisplay(&display, snapshot.path);
574*38e8c45fSAndroid Build Coastguard Worker     if (!outputLayer) {
575*38e8c45fSAndroid Build Coastguard Worker         return;
576*38e8c45fSAndroid Build Coastguard Worker     }
577*38e8c45fSAndroid Build Coastguard Worker 
578*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, " %s\n", snapshot.debugName.c_str());
579*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "  %10zu | ", snapshot.globalZ);
580*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "  %10d | ",
581*38e8c45fSAndroid Build Coastguard Worker                   snapshot.layerMetadata.getInt32(gui::METADATA_WINDOW_TYPE, 0));
582*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "%10s | ", toString(getCompositionType(outputLayer)).c_str());
583*38e8c45fSAndroid Build Coastguard Worker     const auto& outputLayerState = outputLayer->getState();
584*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "%10s | ", toString(outputLayerState.bufferTransform).c_str());
585*38e8c45fSAndroid Build Coastguard Worker     const Rect& frame = outputLayerState.displayFrame;
586*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "%4d %4d %4d %4d | ", frame.left, frame.top, frame.right, frame.bottom);
587*38e8c45fSAndroid Build Coastguard Worker     const FloatRect& crop = outputLayerState.sourceCrop;
588*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "%6.1f %6.1f %6.1f %6.1f | ", crop.left, crop.top, crop.right,
589*38e8c45fSAndroid Build Coastguard Worker                   crop.bottom);
590*38e8c45fSAndroid Build Coastguard Worker     const auto frameRate = snapshot.frameRate;
591*38e8c45fSAndroid Build Coastguard Worker     std::string frameRateStr;
592*38e8c45fSAndroid Build Coastguard Worker     if (frameRate.vote.rate.isValid()) {
593*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&frameRateStr, "%.2f", frameRate.vote.rate.getValue());
594*38e8c45fSAndroid Build Coastguard Worker     }
595*38e8c45fSAndroid Build Coastguard Worker     if (frameRate.vote.rate.isValid() || frameRate.vote.type != FrameRateCompatibility::Default) {
596*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&result, "%6s %15s %17s", frameRateStr.c_str(),
597*38e8c45fSAndroid Build Coastguard Worker                       ftl::enum_string(frameRate.vote.type).c_str(),
598*38e8c45fSAndroid Build Coastguard Worker                       ftl::enum_string(frameRate.vote.seamlessness).c_str());
599*38e8c45fSAndroid Build Coastguard Worker     } else if (frameRate.category != FrameRateCategory::Default) {
600*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&result, "%6s %15s %17s", frameRateStr.c_str(),
601*38e8c45fSAndroid Build Coastguard Worker                       (std::string("Cat::") + ftl::enum_string(frameRate.category)).c_str(),
602*38e8c45fSAndroid Build Coastguard Worker                       ftl::enum_string(frameRate.vote.seamlessness).c_str());
603*38e8c45fSAndroid Build Coastguard Worker     } else {
604*38e8c45fSAndroid Build Coastguard Worker         result.append(41, ' ');
605*38e8c45fSAndroid Build Coastguard Worker     }
606*38e8c45fSAndroid Build Coastguard Worker 
607*38e8c45fSAndroid Build Coastguard Worker     const auto focused = isLayerFocusedBasedOnPriority(snapshot.frameRateSelectionPriority);
608*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "    [%s]\n", focused ? "*" : " ");
609*38e8c45fSAndroid Build Coastguard Worker 
610*38e8c45fSAndroid Build Coastguard Worker     result.append(kDumpTableRowLength, '-');
611*38e8c45fSAndroid Build Coastguard Worker     result.append("\n");
612*38e8c45fSAndroid Build Coastguard Worker }
613*38e8c45fSAndroid Build Coastguard Worker 
dumpFrameStats(std::string & result) const614*38e8c45fSAndroid Build Coastguard Worker void Layer::dumpFrameStats(std::string& result) const {
615*38e8c45fSAndroid Build Coastguard Worker     if (FlagManager::getInstance().deprecate_frame_tracker()) {
616*38e8c45fSAndroid Build Coastguard Worker         FrameStats fs = FrameStats();
617*38e8c45fSAndroid Build Coastguard Worker         getFrameStats(&fs);
618*38e8c45fSAndroid Build Coastguard Worker         for (auto desired = fs.desiredPresentTimesNano.begin(),
619*38e8c45fSAndroid Build Coastguard Worker                   actual = fs.actualPresentTimesNano.begin(),
620*38e8c45fSAndroid Build Coastguard Worker                   ready = fs.frameReadyTimesNano.begin();
621*38e8c45fSAndroid Build Coastguard Worker              desired != fs.desiredPresentTimesNano.end() &&
622*38e8c45fSAndroid Build Coastguard Worker              actual != fs.actualPresentTimesNano.end() && ready != fs.frameReadyTimesNano.end();
623*38e8c45fSAndroid Build Coastguard Worker              ++desired, ++actual, ++ready) {
624*38e8c45fSAndroid Build Coastguard Worker             result.append(std::format("{}\t{}\t{}\n", *desired, *actual, *ready));
625*38e8c45fSAndroid Build Coastguard Worker         }
626*38e8c45fSAndroid Build Coastguard Worker 
627*38e8c45fSAndroid Build Coastguard Worker         result.push_back('\n');
628*38e8c45fSAndroid Build Coastguard Worker     } else {
629*38e8c45fSAndroid Build Coastguard Worker         mDeprecatedFrameTracker.dumpStats(result);
630*38e8c45fSAndroid Build Coastguard Worker     }
631*38e8c45fSAndroid Build Coastguard Worker }
632*38e8c45fSAndroid Build Coastguard Worker 
clearFrameStats()633*38e8c45fSAndroid Build Coastguard Worker void Layer::clearFrameStats() {
634*38e8c45fSAndroid Build Coastguard Worker     if (FlagManager::getInstance().deprecate_frame_tracker()) {
635*38e8c45fSAndroid Build Coastguard Worker         mFrameStatsHistorySize = 0;
636*38e8c45fSAndroid Build Coastguard Worker     } else {
637*38e8c45fSAndroid Build Coastguard Worker         mDeprecatedFrameTracker.clearStats();
638*38e8c45fSAndroid Build Coastguard Worker     }
639*38e8c45fSAndroid Build Coastguard Worker }
640*38e8c45fSAndroid Build Coastguard Worker 
getFrameStats(FrameStats * outStats) const641*38e8c45fSAndroid Build Coastguard Worker void Layer::getFrameStats(FrameStats* outStats) const {
642*38e8c45fSAndroid Build Coastguard Worker     if (FlagManager::getInstance().deprecate_frame_tracker()) {
643*38e8c45fSAndroid Build Coastguard Worker         if (auto ftl = getTimeline()) {
644*38e8c45fSAndroid Build Coastguard Worker             float fps = ftl->get().computeFps({getSequence()});
645*38e8c45fSAndroid Build Coastguard Worker             ftl->get().generateFrameStats(getSequence(), mFrameStatsHistorySize, outStats);
646*38e8c45fSAndroid Build Coastguard Worker             outStats->refreshPeriodNano = Fps::fromValue(fps).getPeriodNsecs();
647*38e8c45fSAndroid Build Coastguard Worker         }
648*38e8c45fSAndroid Build Coastguard Worker     } else {
649*38e8c45fSAndroid Build Coastguard Worker         mDeprecatedFrameTracker.getStats(outStats);
650*38e8c45fSAndroid Build Coastguard Worker     }
651*38e8c45fSAndroid Build Coastguard Worker }
652*38e8c45fSAndroid Build Coastguard Worker 
onDisconnect()653*38e8c45fSAndroid Build Coastguard Worker void Layer::onDisconnect() {
654*38e8c45fSAndroid Build Coastguard Worker     const int32_t layerId = getSequence();
655*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mTimeStats->onDestroy(layerId);
656*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mFrameTracer->onDestroy(layerId);
657*38e8c45fSAndroid Build Coastguard Worker }
658*38e8c45fSAndroid Build Coastguard Worker 
writeCompositionStateToProto(perfetto::protos::LayerProto * layerProto,ui::LayerStack layerStack)659*38e8c45fSAndroid Build Coastguard Worker void Layer::writeCompositionStateToProto(perfetto::protos::LayerProto* layerProto,
660*38e8c45fSAndroid Build Coastguard Worker                                          ui::LayerStack layerStack) {
661*38e8c45fSAndroid Build Coastguard Worker     ftl::FakeGuard guard(mFlinger->mStateLock); // Called from the main thread.
662*38e8c45fSAndroid Build Coastguard Worker     ftl::FakeGuard mainThreadGuard(kMainThreadContext);
663*38e8c45fSAndroid Build Coastguard Worker 
664*38e8c45fSAndroid Build Coastguard Worker     // Only populate for the primary display.
665*38e8c45fSAndroid Build Coastguard Worker     if (const auto display = mFlinger->getDisplayFromLayerStack(layerStack)) {
666*38e8c45fSAndroid Build Coastguard Worker         const auto compositionType = getCompositionType(*display);
667*38e8c45fSAndroid Build Coastguard Worker         layerProto->set_hwc_composition_type(
668*38e8c45fSAndroid Build Coastguard Worker                 static_cast<perfetto::protos::HwcCompositionType>(compositionType));
669*38e8c45fSAndroid Build Coastguard Worker         LayerProtoHelper::writeToProto(getVisibleRegion(display),
670*38e8c45fSAndroid Build Coastguard Worker                                        [&]() { return layerProto->mutable_visible_region(); });
671*38e8c45fSAndroid Build Coastguard Worker     }
672*38e8c45fSAndroid Build Coastguard Worker }
673*38e8c45fSAndroid Build Coastguard Worker 
findOutputLayerForDisplay(const DisplayDevice * display) const674*38e8c45fSAndroid Build Coastguard Worker compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(
675*38e8c45fSAndroid Build Coastguard Worker         const DisplayDevice* display) const {
676*38e8c45fSAndroid Build Coastguard Worker     if (!display) return nullptr;
677*38e8c45fSAndroid Build Coastguard Worker     sp<LayerFE> layerFE;
678*38e8c45fSAndroid Build Coastguard Worker     frontend::LayerHierarchy::TraversalPath path{.id = static_cast<uint32_t>(sequence)};
679*38e8c45fSAndroid Build Coastguard Worker     for (auto& [p, layer] : mLayerFEs) {
680*38e8c45fSAndroid Build Coastguard Worker         if (p == path) {
681*38e8c45fSAndroid Build Coastguard Worker             layerFE = layer;
682*38e8c45fSAndroid Build Coastguard Worker         }
683*38e8c45fSAndroid Build Coastguard Worker     }
684*38e8c45fSAndroid Build Coastguard Worker 
685*38e8c45fSAndroid Build Coastguard Worker     if (!layerFE) return nullptr;
686*38e8c45fSAndroid Build Coastguard Worker     return display->getCompositionDisplay()->getOutputLayerForLayer(layerFE);
687*38e8c45fSAndroid Build Coastguard Worker }
688*38e8c45fSAndroid Build Coastguard Worker 
findOutputLayerForDisplay(const DisplayDevice * display,const frontend::LayerHierarchy::TraversalPath & path) const689*38e8c45fSAndroid Build Coastguard Worker compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(
690*38e8c45fSAndroid Build Coastguard Worker         const DisplayDevice* display, const frontend::LayerHierarchy::TraversalPath& path) const {
691*38e8c45fSAndroid Build Coastguard Worker     if (!display) return nullptr;
692*38e8c45fSAndroid Build Coastguard Worker     sp<LayerFE> layerFE;
693*38e8c45fSAndroid Build Coastguard Worker     for (auto& [p, layer] : mLayerFEs) {
694*38e8c45fSAndroid Build Coastguard Worker         if (p == path) {
695*38e8c45fSAndroid Build Coastguard Worker             layerFE = layer;
696*38e8c45fSAndroid Build Coastguard Worker         }
697*38e8c45fSAndroid Build Coastguard Worker     }
698*38e8c45fSAndroid Build Coastguard Worker 
699*38e8c45fSAndroid Build Coastguard Worker     if (!layerFE) return nullptr;
700*38e8c45fSAndroid Build Coastguard Worker     return display->getCompositionDisplay()->getOutputLayerForLayer(layerFE);
701*38e8c45fSAndroid Build Coastguard Worker }
702*38e8c45fSAndroid Build Coastguard Worker 
getVisibleRegion(const DisplayDevice * display) const703*38e8c45fSAndroid Build Coastguard Worker Region Layer::getVisibleRegion(const DisplayDevice* display) const {
704*38e8c45fSAndroid Build Coastguard Worker     const auto outputLayer = findOutputLayerForDisplay(display);
705*38e8c45fSAndroid Build Coastguard Worker     return outputLayer ? outputLayer->getState().visibleRegion : Region();
706*38e8c45fSAndroid Build Coastguard Worker }
707*38e8c45fSAndroid Build Coastguard Worker 
callReleaseBufferCallback(const sp<ITransactionCompletedListener> & listener,const sp<GraphicBuffer> & buffer,uint64_t framenumber,const sp<Fence> & releaseFence)708*38e8c45fSAndroid Build Coastguard Worker void Layer::callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener,
709*38e8c45fSAndroid Build Coastguard Worker                                       const sp<GraphicBuffer>& buffer, uint64_t framenumber,
710*38e8c45fSAndroid Build Coastguard Worker                                       const sp<Fence>& releaseFence) {
711*38e8c45fSAndroid Build Coastguard Worker     if (!listener && !mBufferReleaseChannel) {
712*38e8c45fSAndroid Build Coastguard Worker         return;
713*38e8c45fSAndroid Build Coastguard Worker     }
714*38e8c45fSAndroid Build Coastguard Worker 
715*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64, getDebugName(), framenumber);
716*38e8c45fSAndroid Build Coastguard Worker 
717*38e8c45fSAndroid Build Coastguard Worker     ReleaseCallbackId callbackId{buffer->getId(), framenumber};
718*38e8c45fSAndroid Build Coastguard Worker     const sp<Fence>& fence = releaseFence ? releaseFence : Fence::NO_FENCE;
719*38e8c45fSAndroid Build Coastguard Worker     uint32_t currentMaxAcquiredBufferCount =
720*38e8c45fSAndroid Build Coastguard Worker             mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid);
721*38e8c45fSAndroid Build Coastguard Worker 
722*38e8c45fSAndroid Build Coastguard Worker     if (listener) {
723*38e8c45fSAndroid Build Coastguard Worker         listener->onReleaseBuffer(callbackId, fence, currentMaxAcquiredBufferCount);
724*38e8c45fSAndroid Build Coastguard Worker     }
725*38e8c45fSAndroid Build Coastguard Worker 
726*38e8c45fSAndroid Build Coastguard Worker     if (!mBufferReleaseChannel) {
727*38e8c45fSAndroid Build Coastguard Worker         return;
728*38e8c45fSAndroid Build Coastguard Worker     }
729*38e8c45fSAndroid Build Coastguard Worker 
730*38e8c45fSAndroid Build Coastguard Worker     status_t status = mBufferReleaseChannel->writeReleaseFence(callbackId, fence,
731*38e8c45fSAndroid Build Coastguard Worker                                                                currentMaxAcquiredBufferCount);
732*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
733*38e8c45fSAndroid Build Coastguard Worker         int error = -status;
734*38e8c45fSAndroid Build Coastguard Worker         // callReleaseBufferCallback is called during Layer's destructor. In this case, it's
735*38e8c45fSAndroid Build Coastguard Worker         // expected to receive connection errors.
736*38e8c45fSAndroid Build Coastguard Worker         if (error != EPIPE && error != ECONNRESET) {
737*38e8c45fSAndroid Build Coastguard Worker             ALOGD("[%s] writeReleaseFence failed. error %d (%s)", getDebugName(), error,
738*38e8c45fSAndroid Build Coastguard Worker                   strerror(error));
739*38e8c45fSAndroid Build Coastguard Worker         }
740*38e8c45fSAndroid Build Coastguard Worker     }
741*38e8c45fSAndroid Build Coastguard Worker }
742*38e8c45fSAndroid Build Coastguard Worker 
findCallbackHandle()743*38e8c45fSAndroid Build Coastguard Worker sp<CallbackHandle> Layer::findCallbackHandle() {
744*38e8c45fSAndroid Build Coastguard Worker     // If we are displayed on multiple displays in a single composition cycle then we would
745*38e8c45fSAndroid Build Coastguard Worker     // need to do careful tracking to enable the use of the mLastClientCompositionFence.
746*38e8c45fSAndroid Build Coastguard Worker     //  For example we can only use it if all the displays are client comp, and we need
747*38e8c45fSAndroid Build Coastguard Worker     //  to merge all the client comp fences. We could do this, but for now we just
748*38e8c45fSAndroid Build Coastguard Worker     // disable the optimization when a layer is composed on multiple displays.
749*38e8c45fSAndroid Build Coastguard Worker     if (mClearClientCompositionFenceOnLayerDisplayed) {
750*38e8c45fSAndroid Build Coastguard Worker         mLastClientCompositionFence = nullptr;
751*38e8c45fSAndroid Build Coastguard Worker     } else {
752*38e8c45fSAndroid Build Coastguard Worker         mClearClientCompositionFenceOnLayerDisplayed = true;
753*38e8c45fSAndroid Build Coastguard Worker     }
754*38e8c45fSAndroid Build Coastguard Worker 
755*38e8c45fSAndroid Build Coastguard Worker     // The previous release fence notifies the client that SurfaceFlinger is done with the previous
756*38e8c45fSAndroid Build Coastguard Worker     // buffer that was presented on this layer. The first transaction that came in this frame that
757*38e8c45fSAndroid Build Coastguard Worker     // replaced the previous buffer on this layer needs this release fence, because the fence will
758*38e8c45fSAndroid Build Coastguard Worker     // let the client know when that previous buffer is removed from the screen.
759*38e8c45fSAndroid Build Coastguard Worker     //
760*38e8c45fSAndroid Build Coastguard Worker     // Every other transaction on this layer does not need a release fence because no other
761*38e8c45fSAndroid Build Coastguard Worker     // Transactions that were set on this layer this frame are going to have their preceding buffer
762*38e8c45fSAndroid Build Coastguard Worker     // removed from the display this frame.
763*38e8c45fSAndroid Build Coastguard Worker     //
764*38e8c45fSAndroid Build Coastguard Worker     // For example, if we have 3 transactions this frame. The first transaction doesn't contain a
765*38e8c45fSAndroid Build Coastguard Worker     // buffer so it doesn't need a previous release fence because the layer still needs the previous
766*38e8c45fSAndroid Build Coastguard Worker     // buffer. The second transaction contains a buffer so it needs a previous release fence because
767*38e8c45fSAndroid Build Coastguard Worker     // the previous buffer will be released this frame. The third transaction also contains a
768*38e8c45fSAndroid Build Coastguard Worker     // buffer. It replaces the buffer in the second transaction. The buffer in the second
769*38e8c45fSAndroid Build Coastguard Worker     // transaction will now no longer be presented so it is released immediately and the third
770*38e8c45fSAndroid Build Coastguard Worker     // transaction doesn't need a previous release fence.
771*38e8c45fSAndroid Build Coastguard Worker     sp<CallbackHandle> ch;
772*38e8c45fSAndroid Build Coastguard Worker     for (auto& handle : mDrawingState.callbackHandles) {
773*38e8c45fSAndroid Build Coastguard Worker         if (handle->releasePreviousBuffer && mPreviousReleaseBufferEndpoint == handle->listener) {
774*38e8c45fSAndroid Build Coastguard Worker             ch = handle;
775*38e8c45fSAndroid Build Coastguard Worker             break;
776*38e8c45fSAndroid Build Coastguard Worker         }
777*38e8c45fSAndroid Build Coastguard Worker     }
778*38e8c45fSAndroid Build Coastguard Worker     return ch;
779*38e8c45fSAndroid Build Coastguard Worker }
780*38e8c45fSAndroid Build Coastguard Worker 
prepareReleaseCallbacks(ftl::Future<FenceResult> futureFenceResult,ui::LayerStack layerStack)781*38e8c45fSAndroid Build Coastguard Worker void Layer::prepareReleaseCallbacks(ftl::Future<FenceResult> futureFenceResult,
782*38e8c45fSAndroid Build Coastguard Worker                                     ui::LayerStack layerStack) {
783*38e8c45fSAndroid Build Coastguard Worker     sp<CallbackHandle> ch = findCallbackHandle();
784*38e8c45fSAndroid Build Coastguard Worker 
785*38e8c45fSAndroid Build Coastguard Worker     if (ch != nullptr) {
786*38e8c45fSAndroid Build Coastguard Worker         ch->previousReleaseCallbackId = mPreviousReleaseCallbackId;
787*38e8c45fSAndroid Build Coastguard Worker         ch->previousReleaseFences.emplace_back(std::move(futureFenceResult));
788*38e8c45fSAndroid Build Coastguard Worker         ch->name = mName;
789*38e8c45fSAndroid Build Coastguard Worker     } else {
790*38e8c45fSAndroid Build Coastguard Worker         // If we didn't get a release callback yet (e.g. some scenarios when capturing
791*38e8c45fSAndroid Build Coastguard Worker         // screenshots asynchronously) then make sure we don't drop the fence.
792*38e8c45fSAndroid Build Coastguard Worker         // Older fences for the same layer stack can be dropped when a new fence arrives.
793*38e8c45fSAndroid Build Coastguard Worker         // An assumption here is that RenderEngine performs work sequentially, so an
794*38e8c45fSAndroid Build Coastguard Worker         // incoming fence will not fire before an existing fence.
795*38e8c45fSAndroid Build Coastguard Worker         mAdditionalPreviousReleaseFences.emplace_or_replace(layerStack,
796*38e8c45fSAndroid Build Coastguard Worker                                                             std::move(futureFenceResult));
797*38e8c45fSAndroid Build Coastguard Worker     }
798*38e8c45fSAndroid Build Coastguard Worker 
799*38e8c45fSAndroid Build Coastguard Worker     if (mBufferInfo.mBuffer) {
800*38e8c45fSAndroid Build Coastguard Worker         mPreviouslyPresentedLayerStacks.push_back(layerStack);
801*38e8c45fSAndroid Build Coastguard Worker     }
802*38e8c45fSAndroid Build Coastguard Worker 
803*38e8c45fSAndroid Build Coastguard Worker     if (mDrawingState.frameNumber > 0) {
804*38e8c45fSAndroid Build Coastguard Worker         mDrawingState.previousFrameNumber = mDrawingState.frameNumber;
805*38e8c45fSAndroid Build Coastguard Worker     }
806*38e8c45fSAndroid Build Coastguard Worker }
807*38e8c45fSAndroid Build Coastguard Worker 
releasePendingBuffer(nsecs_t dequeueReadyTime)808*38e8c45fSAndroid Build Coastguard Worker void Layer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
809*38e8c45fSAndroid Build Coastguard Worker     for (const auto& handle : mDrawingState.callbackHandles) {
810*38e8c45fSAndroid Build Coastguard Worker         handle->bufferReleaseChannel = mBufferReleaseChannel;
811*38e8c45fSAndroid Build Coastguard Worker         handle->transformHint = mTransformHint;
812*38e8c45fSAndroid Build Coastguard Worker         handle->dequeueReadyTime = dequeueReadyTime;
813*38e8c45fSAndroid Build Coastguard Worker         handle->currentMaxAcquiredBufferCount =
814*38e8c45fSAndroid Build Coastguard Worker                 mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid);
815*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_FORMAT_INSTANT("releasePendingBuffer %s - %" PRIu64, getDebugName(),
816*38e8c45fSAndroid Build Coastguard Worker                                handle->previousReleaseCallbackId.framenumber);
817*38e8c45fSAndroid Build Coastguard Worker     }
818*38e8c45fSAndroid Build Coastguard Worker 
819*38e8c45fSAndroid Build Coastguard Worker     for (auto& handle : mDrawingState.callbackHandles) {
820*38e8c45fSAndroid Build Coastguard Worker         if (handle->releasePreviousBuffer && mPreviousReleaseBufferEndpoint == handle->listener) {
821*38e8c45fSAndroid Build Coastguard Worker             handle->previousReleaseCallbackId = mPreviousReleaseCallbackId;
822*38e8c45fSAndroid Build Coastguard Worker             break;
823*38e8c45fSAndroid Build Coastguard Worker         }
824*38e8c45fSAndroid Build Coastguard Worker     }
825*38e8c45fSAndroid Build Coastguard Worker 
826*38e8c45fSAndroid Build Coastguard Worker     mFlinger->getTransactionCallbackInvoker().addCallbackHandles(mDrawingState.callbackHandles);
827*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.callbackHandles = {};
828*38e8c45fSAndroid Build Coastguard Worker }
829*38e8c45fSAndroid Build Coastguard Worker 
setTransform(uint32_t transform)830*38e8c45fSAndroid Build Coastguard Worker bool Layer::setTransform(uint32_t transform) {
831*38e8c45fSAndroid Build Coastguard Worker     if (mDrawingState.bufferTransform == transform) return false;
832*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.bufferTransform = transform;
833*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eTransactionNeeded);
834*38e8c45fSAndroid Build Coastguard Worker     return true;
835*38e8c45fSAndroid Build Coastguard Worker }
836*38e8c45fSAndroid Build Coastguard Worker 
setTransformToDisplayInverse(bool transformToDisplayInverse)837*38e8c45fSAndroid Build Coastguard Worker bool Layer::setTransformToDisplayInverse(bool transformToDisplayInverse) {
838*38e8c45fSAndroid Build Coastguard Worker     if (mDrawingState.transformToDisplayInverse == transformToDisplayInverse) return false;
839*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.sequence++;
840*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.transformToDisplayInverse = transformToDisplayInverse;
841*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eTransactionNeeded);
842*38e8c45fSAndroid Build Coastguard Worker     return true;
843*38e8c45fSAndroid Build Coastguard Worker }
844*38e8c45fSAndroid Build Coastguard Worker 
releasePreviousBuffer()845*38e8c45fSAndroid Build Coastguard Worker void Layer::releasePreviousBuffer() {
846*38e8c45fSAndroid Build Coastguard Worker     mReleasePreviousBuffer = true;
847*38e8c45fSAndroid Build Coastguard Worker     if (!mBufferInfo.mBuffer ||
848*38e8c45fSAndroid Build Coastguard Worker         (!mDrawingState.buffer->hasSameBuffer(*mBufferInfo.mBuffer) ||
849*38e8c45fSAndroid Build Coastguard Worker          mDrawingState.frameNumber != mBufferInfo.mFrameNumber)) {
850*38e8c45fSAndroid Build Coastguard Worker         // If mDrawingState has a buffer, and we are about to update again
851*38e8c45fSAndroid Build Coastguard Worker         // before swapping to drawing state, then the first buffer will be
852*38e8c45fSAndroid Build Coastguard Worker         // dropped and we should decrement the pending buffer count and
853*38e8c45fSAndroid Build Coastguard Worker         // call any release buffer callbacks if set.
854*38e8c45fSAndroid Build Coastguard Worker         callReleaseBufferCallback(mDrawingState.releaseBufferListener,
855*38e8c45fSAndroid Build Coastguard Worker                                   mDrawingState.buffer->getBuffer(), mDrawingState.frameNumber,
856*38e8c45fSAndroid Build Coastguard Worker                                   mDrawingState.acquireFence);
857*38e8c45fSAndroid Build Coastguard Worker         const int32_t layerId = getSequence();
858*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mTimeStats->removeTimeRecord(layerId, mDrawingState.frameNumber);
859*38e8c45fSAndroid Build Coastguard Worker         decrementPendingBufferCount();
860*38e8c45fSAndroid Build Coastguard Worker         if (mDrawingState.bufferSurfaceFrameTX != nullptr &&
861*38e8c45fSAndroid Build Coastguard Worker             mDrawingState.bufferSurfaceFrameTX->getPresentState() != PresentState::Presented) {
862*38e8c45fSAndroid Build Coastguard Worker             addSurfaceFrameDroppedForBuffer(mDrawingState.bufferSurfaceFrameTX, systemTime());
863*38e8c45fSAndroid Build Coastguard Worker             mDrawingState.bufferSurfaceFrameTX.reset();
864*38e8c45fSAndroid Build Coastguard Worker         }
865*38e8c45fSAndroid Build Coastguard Worker     } else if (EARLY_RELEASE_ENABLED && mLastClientCompositionFence != nullptr) {
866*38e8c45fSAndroid Build Coastguard Worker         callReleaseBufferCallback(mDrawingState.releaseBufferListener,
867*38e8c45fSAndroid Build Coastguard Worker                                   mDrawingState.buffer->getBuffer(), mDrawingState.frameNumber,
868*38e8c45fSAndroid Build Coastguard Worker                                   mLastClientCompositionFence);
869*38e8c45fSAndroid Build Coastguard Worker         mLastClientCompositionFence = nullptr;
870*38e8c45fSAndroid Build Coastguard Worker     }
871*38e8c45fSAndroid Build Coastguard Worker }
872*38e8c45fSAndroid Build Coastguard Worker 
resetDrawingStateBufferInfo()873*38e8c45fSAndroid Build Coastguard Worker void Layer::resetDrawingStateBufferInfo() {
874*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.producerId = 0;
875*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.frameNumber = 0;
876*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.previousFrameNumber = 0;
877*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.releaseBufferListener = nullptr;
878*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.buffer = nullptr;
879*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.acquireFence = sp<Fence>::make(-1);
880*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.acquireFenceTime = std::make_unique<FenceTime>(mDrawingState.acquireFence);
881*38e8c45fSAndroid Build Coastguard Worker     mCallbackHandleAcquireTimeOrFence = mDrawingState.acquireFenceTime->getSignalTime();
882*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.releaseBufferEndpoint = nullptr;
883*38e8c45fSAndroid Build Coastguard Worker }
884*38e8c45fSAndroid Build Coastguard Worker 
setBuffer(std::shared_ptr<renderengine::ExternalTexture> & buffer,const BufferData & bufferData,nsecs_t postTime,nsecs_t desiredPresentTime,bool isAutoTimestamp,const FrameTimelineInfo & info,gui::GameMode gameMode)885*38e8c45fSAndroid Build Coastguard Worker bool Layer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer,
886*38e8c45fSAndroid Build Coastguard Worker                       const BufferData& bufferData, nsecs_t postTime, nsecs_t desiredPresentTime,
887*38e8c45fSAndroid Build Coastguard Worker                       bool isAutoTimestamp, const FrameTimelineInfo& info, gui::GameMode gameMode) {
888*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_FORMAT("setBuffer %s - hasBuffer=%s", getDebugName(), (buffer ? "true" : "false"));
889*38e8c45fSAndroid Build Coastguard Worker 
890*38e8c45fSAndroid Build Coastguard Worker     const bool frameNumberChanged =
891*38e8c45fSAndroid Build Coastguard Worker             bufferData.flags.test(BufferData::BufferDataChange::frameNumberChanged);
892*38e8c45fSAndroid Build Coastguard Worker     const uint64_t frameNumber =
893*38e8c45fSAndroid Build Coastguard Worker             frameNumberChanged ? bufferData.frameNumber : mDrawingState.frameNumber + 1;
894*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_FORMAT_INSTANT("setBuffer %s - %" PRIu64, getDebugName(), frameNumber);
895*38e8c45fSAndroid Build Coastguard Worker 
896*38e8c45fSAndroid Build Coastguard Worker     if (mDrawingState.buffer) {
897*38e8c45fSAndroid Build Coastguard Worker         releasePreviousBuffer();
898*38e8c45fSAndroid Build Coastguard Worker     } else if (buffer) {
899*38e8c45fSAndroid Build Coastguard Worker         // if we are latching a buffer for the first time then clear the mLastLatchTime since
900*38e8c45fSAndroid Build Coastguard Worker         // we don't want to incorrectly classify a frame if we miss the desired present time.
901*38e8c45fSAndroid Build Coastguard Worker         updateLastLatchTime(0);
902*38e8c45fSAndroid Build Coastguard Worker     }
903*38e8c45fSAndroid Build Coastguard Worker 
904*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.desiredPresentTime = desiredPresentTime;
905*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.isAutoTimestamp = isAutoTimestamp;
906*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.latchedVsyncId = info.vsyncId;
907*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.useVsyncIdForRefreshRateSelection = info.useForRefreshRateSelection;
908*38e8c45fSAndroid Build Coastguard Worker     if (!buffer) {
909*38e8c45fSAndroid Build Coastguard Worker         resetDrawingStateBufferInfo();
910*38e8c45fSAndroid Build Coastguard Worker         setTransactionFlags(eTransactionNeeded);
911*38e8c45fSAndroid Build Coastguard Worker         mDrawingState.bufferSurfaceFrameTX = nullptr;
912*38e8c45fSAndroid Build Coastguard Worker         setFrameTimelineVsyncForBufferlessTransaction(info, postTime, gameMode);
913*38e8c45fSAndroid Build Coastguard Worker         return true;
914*38e8c45fSAndroid Build Coastguard Worker     } else {
915*38e8c45fSAndroid Build Coastguard Worker         // release sideband stream if it exists and a non null buffer is being set
916*38e8c45fSAndroid Build Coastguard Worker         if (mDrawingState.sidebandStream != nullptr) {
917*38e8c45fSAndroid Build Coastguard Worker             setSidebandStream(nullptr, info, postTime, gameMode);
918*38e8c45fSAndroid Build Coastguard Worker         }
919*38e8c45fSAndroid Build Coastguard Worker     }
920*38e8c45fSAndroid Build Coastguard Worker 
921*38e8c45fSAndroid Build Coastguard Worker     if ((mDrawingState.producerId > bufferData.producerId) ||
922*38e8c45fSAndroid Build Coastguard Worker         ((mDrawingState.producerId == bufferData.producerId) &&
923*38e8c45fSAndroid Build Coastguard Worker          (mDrawingState.frameNumber > frameNumber))) {
924*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Out of order buffers detected for %s producedId=%d frameNumber=%" PRIu64
925*38e8c45fSAndroid Build Coastguard Worker               " -> producedId=%d frameNumber=%" PRIu64,
926*38e8c45fSAndroid Build Coastguard Worker               getDebugName(), mDrawingState.producerId, mDrawingState.frameNumber,
927*38e8c45fSAndroid Build Coastguard Worker               bufferData.producerId, frameNumber);
928*38e8c45fSAndroid Build Coastguard Worker         TransactionTraceWriter::getInstance().invoke("out_of_order_buffers_", /*overwrite=*/false);
929*38e8c45fSAndroid Build Coastguard Worker     }
930*38e8c45fSAndroid Build Coastguard Worker 
931*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.producerId = bufferData.producerId;
932*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.barrierProducerId =
933*38e8c45fSAndroid Build Coastguard Worker             std::max(mDrawingState.producerId, mDrawingState.barrierProducerId);
934*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.frameNumber = frameNumber;
935*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.barrierFrameNumber =
936*38e8c45fSAndroid Build Coastguard Worker             std::max(mDrawingState.frameNumber, mDrawingState.barrierFrameNumber);
937*38e8c45fSAndroid Build Coastguard Worker 
938*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.releaseBufferListener = bufferData.releaseBufferListener;
939*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.buffer = std::move(buffer);
940*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.acquireFence = bufferData.flags.test(BufferData::BufferDataChange::fenceChanged)
941*38e8c45fSAndroid Build Coastguard Worker             ? bufferData.acquireFence
942*38e8c45fSAndroid Build Coastguard Worker             : Fence::NO_FENCE;
943*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.acquireFenceTime = std::make_unique<FenceTime>(mDrawingState.acquireFence);
944*38e8c45fSAndroid Build Coastguard Worker     if (mDrawingState.acquireFenceTime->getSignalTime() == Fence::SIGNAL_TIME_PENDING) {
945*38e8c45fSAndroid Build Coastguard Worker         // We latched this buffer unsiganled, so we need to pass the acquire fence
946*38e8c45fSAndroid Build Coastguard Worker         // on the callback instead of just the acquire time, since it's unknown at
947*38e8c45fSAndroid Build Coastguard Worker         // this point.
948*38e8c45fSAndroid Build Coastguard Worker         mCallbackHandleAcquireTimeOrFence = mDrawingState.acquireFence;
949*38e8c45fSAndroid Build Coastguard Worker     } else {
950*38e8c45fSAndroid Build Coastguard Worker         mCallbackHandleAcquireTimeOrFence = mDrawingState.acquireFenceTime->getSignalTime();
951*38e8c45fSAndroid Build Coastguard Worker     }
952*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eTransactionNeeded);
953*38e8c45fSAndroid Build Coastguard Worker 
954*38e8c45fSAndroid Build Coastguard Worker     const int32_t layerId = getSequence();
955*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mTimeStats->setPostTime(layerId, mDrawingState.frameNumber, getName().c_str(),
956*38e8c45fSAndroid Build Coastguard Worker                                       mOwnerUid, postTime, gameMode);
957*38e8c45fSAndroid Build Coastguard Worker 
958*38e8c45fSAndroid Build Coastguard Worker     setFrameTimelineVsyncForBufferTransaction(info, postTime, gameMode);
959*38e8c45fSAndroid Build Coastguard Worker 
960*38e8c45fSAndroid Build Coastguard Worker     if (bufferData.dequeueTime > 0) {
961*38e8c45fSAndroid Build Coastguard Worker         const uint64_t bufferId = mDrawingState.buffer->getId();
962*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mFrameTracer->traceNewLayer(layerId, getName().c_str());
963*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber,
964*38e8c45fSAndroid Build Coastguard Worker                                                bufferData.dequeueTime,
965*38e8c45fSAndroid Build Coastguard Worker                                                FrameTracer::FrameEvent::DEQUEUE);
966*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, postTime,
967*38e8c45fSAndroid Build Coastguard Worker                                                FrameTracer::FrameEvent::QUEUE);
968*38e8c45fSAndroid Build Coastguard Worker     }
969*38e8c45fSAndroid Build Coastguard Worker 
970*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.releaseBufferEndpoint = bufferData.releaseBufferEndpoint;
971*38e8c45fSAndroid Build Coastguard Worker 
972*38e8c45fSAndroid Build Coastguard Worker     // If the layer had been updated a TextureView, this would make sure the present time could be
973*38e8c45fSAndroid Build Coastguard Worker     // same to TextureView update when it's a small dirty, and get the correct heuristic rate.
974*38e8c45fSAndroid Build Coastguard Worker     if (mFlinger->mScheduler->supportSmallDirtyDetection(mOwnerAppId)) {
975*38e8c45fSAndroid Build Coastguard Worker         if (mDrawingState.useVsyncIdForRefreshRateSelection) {
976*38e8c45fSAndroid Build Coastguard Worker             mUsedVsyncIdForRefreshRateSelection = true;
977*38e8c45fSAndroid Build Coastguard Worker         }
978*38e8c45fSAndroid Build Coastguard Worker     }
979*38e8c45fSAndroid Build Coastguard Worker     return true;
980*38e8c45fSAndroid Build Coastguard Worker }
981*38e8c45fSAndroid Build Coastguard Worker 
setDesiredPresentTime(nsecs_t desiredPresentTime,bool isAutoTimestamp)982*38e8c45fSAndroid Build Coastguard Worker void Layer::setDesiredPresentTime(nsecs_t desiredPresentTime, bool isAutoTimestamp) {
983*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.desiredPresentTime = desiredPresentTime;
984*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.isAutoTimestamp = isAutoTimestamp;
985*38e8c45fSAndroid Build Coastguard Worker }
986*38e8c45fSAndroid Build Coastguard Worker 
recordLayerHistoryBufferUpdate(const scheduler::LayerProps & layerProps,nsecs_t now)987*38e8c45fSAndroid Build Coastguard Worker void Layer::recordLayerHistoryBufferUpdate(const scheduler::LayerProps& layerProps, nsecs_t now) {
988*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
989*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t presentTime = [&] {
990*38e8c45fSAndroid Build Coastguard Worker         if (!mDrawingState.isAutoTimestamp) {
991*38e8c45fSAndroid Build Coastguard Worker             SFTRACE_FORMAT_INSTANT("desiredPresentTime");
992*38e8c45fSAndroid Build Coastguard Worker             return mDrawingState.desiredPresentTime;
993*38e8c45fSAndroid Build Coastguard Worker         }
994*38e8c45fSAndroid Build Coastguard Worker 
995*38e8c45fSAndroid Build Coastguard Worker         if (mDrawingState.useVsyncIdForRefreshRateSelection) {
996*38e8c45fSAndroid Build Coastguard Worker             const auto prediction =
997*38e8c45fSAndroid Build Coastguard Worker                     mFlinger->mFrameTimeline->getTokenManager()->getPredictionsForToken(
998*38e8c45fSAndroid Build Coastguard Worker                             mDrawingState.latchedVsyncId);
999*38e8c45fSAndroid Build Coastguard Worker             if (prediction.has_value()) {
1000*38e8c45fSAndroid Build Coastguard Worker                 SFTRACE_FORMAT_INSTANT("predictedPresentTime");
1001*38e8c45fSAndroid Build Coastguard Worker                 mMaxTimeForUseVsyncId = prediction->presentTime +
1002*38e8c45fSAndroid Build Coastguard Worker                         scheduler::LayerHistory::kMaxPeriodForHistory.count();
1003*38e8c45fSAndroid Build Coastguard Worker                 return prediction->presentTime;
1004*38e8c45fSAndroid Build Coastguard Worker             }
1005*38e8c45fSAndroid Build Coastguard Worker         }
1006*38e8c45fSAndroid Build Coastguard Worker 
1007*38e8c45fSAndroid Build Coastguard Worker         if (!mFlinger->mScheduler->supportSmallDirtyDetection(mOwnerAppId)) {
1008*38e8c45fSAndroid Build Coastguard Worker             return static_cast<nsecs_t>(0);
1009*38e8c45fSAndroid Build Coastguard Worker         }
1010*38e8c45fSAndroid Build Coastguard Worker 
1011*38e8c45fSAndroid Build Coastguard Worker         // If the layer is not an application and didn't set an explicit rate or desiredPresentTime,
1012*38e8c45fSAndroid Build Coastguard Worker         // return "0" to tell the layer history that it will use the max refresh rate without
1013*38e8c45fSAndroid Build Coastguard Worker         // calculating the adaptive rate.
1014*38e8c45fSAndroid Build Coastguard Worker         if (mWindowType != WindowInfo::Type::APPLICATION &&
1015*38e8c45fSAndroid Build Coastguard Worker             mWindowType != WindowInfo::Type::BASE_APPLICATION) {
1016*38e8c45fSAndroid Build Coastguard Worker             return static_cast<nsecs_t>(0);
1017*38e8c45fSAndroid Build Coastguard Worker         }
1018*38e8c45fSAndroid Build Coastguard Worker 
1019*38e8c45fSAndroid Build Coastguard Worker         // Return the valid present time only when the layer potentially updated a TextureView so
1020*38e8c45fSAndroid Build Coastguard Worker         // LayerHistory could heuristically calculate the rate if the UI is continually updating.
1021*38e8c45fSAndroid Build Coastguard Worker         if (mUsedVsyncIdForRefreshRateSelection) {
1022*38e8c45fSAndroid Build Coastguard Worker             const auto prediction =
1023*38e8c45fSAndroid Build Coastguard Worker                     mFlinger->mFrameTimeline->getTokenManager()->getPredictionsForToken(
1024*38e8c45fSAndroid Build Coastguard Worker                             mDrawingState.latchedVsyncId);
1025*38e8c45fSAndroid Build Coastguard Worker             if (prediction.has_value()) {
1026*38e8c45fSAndroid Build Coastguard Worker                 if (mMaxTimeForUseVsyncId >= prediction->presentTime) {
1027*38e8c45fSAndroid Build Coastguard Worker                     return prediction->presentTime;
1028*38e8c45fSAndroid Build Coastguard Worker                 }
1029*38e8c45fSAndroid Build Coastguard Worker                 mUsedVsyncIdForRefreshRateSelection = false;
1030*38e8c45fSAndroid Build Coastguard Worker             }
1031*38e8c45fSAndroid Build Coastguard Worker         }
1032*38e8c45fSAndroid Build Coastguard Worker 
1033*38e8c45fSAndroid Build Coastguard Worker         return static_cast<nsecs_t>(0);
1034*38e8c45fSAndroid Build Coastguard Worker     }();
1035*38e8c45fSAndroid Build Coastguard Worker 
1036*38e8c45fSAndroid Build Coastguard Worker     if (SFTRACE_ENABLED() && presentTime > 0) {
1037*38e8c45fSAndroid Build Coastguard Worker         const auto presentIn = TimePoint::fromNs(presentTime) - TimePoint::now();
1038*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_FORMAT_INSTANT("presentIn %s", to_string(presentIn).c_str());
1039*38e8c45fSAndroid Build Coastguard Worker     }
1040*38e8c45fSAndroid Build Coastguard Worker 
1041*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mScheduler->recordLayerHistory(sequence, layerProps, presentTime, now,
1042*38e8c45fSAndroid Build Coastguard Worker                                              scheduler::LayerHistory::LayerUpdateType::Buffer);
1043*38e8c45fSAndroid Build Coastguard Worker }
1044*38e8c45fSAndroid Build Coastguard Worker 
recordLayerHistoryAnimationTx(const scheduler::LayerProps & layerProps,nsecs_t now)1045*38e8c45fSAndroid Build Coastguard Worker void Layer::recordLayerHistoryAnimationTx(const scheduler::LayerProps& layerProps, nsecs_t now) {
1046*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t presentTime =
1047*38e8c45fSAndroid Build Coastguard Worker             mDrawingState.isAutoTimestamp ? 0 : mDrawingState.desiredPresentTime;
1048*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mScheduler->recordLayerHistory(sequence, layerProps, presentTime, now,
1049*38e8c45fSAndroid Build Coastguard Worker                                              scheduler::LayerHistory::LayerUpdateType::AnimationTX);
1050*38e8c45fSAndroid Build Coastguard Worker }
1051*38e8c45fSAndroid Build Coastguard Worker 
setDataspace(ui::Dataspace dataspace)1052*38e8c45fSAndroid Build Coastguard Worker bool Layer::setDataspace(ui::Dataspace dataspace) {
1053*38e8c45fSAndroid Build Coastguard Worker     if (mDrawingState.dataspace == dataspace) return false;
1054*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.dataspace = dataspace;
1055*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eTransactionNeeded);
1056*38e8c45fSAndroid Build Coastguard Worker     return true;
1057*38e8c45fSAndroid Build Coastguard Worker }
1058*38e8c45fSAndroid Build Coastguard Worker 
setExtendedRangeBrightness(float currentBufferRatio,float desiredRatio)1059*38e8c45fSAndroid Build Coastguard Worker bool Layer::setExtendedRangeBrightness(float currentBufferRatio, float desiredRatio) {
1060*38e8c45fSAndroid Build Coastguard Worker     if (mDrawingState.currentHdrSdrRatio == currentBufferRatio &&
1061*38e8c45fSAndroid Build Coastguard Worker         mDrawingState.desiredHdrSdrRatio == desiredRatio)
1062*38e8c45fSAndroid Build Coastguard Worker         return false;
1063*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.currentHdrSdrRatio = currentBufferRatio;
1064*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.desiredHdrSdrRatio = desiredRatio;
1065*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eTransactionNeeded);
1066*38e8c45fSAndroid Build Coastguard Worker     return true;
1067*38e8c45fSAndroid Build Coastguard Worker }
1068*38e8c45fSAndroid Build Coastguard Worker 
setDesiredHdrHeadroom(float desiredRatio)1069*38e8c45fSAndroid Build Coastguard Worker bool Layer::setDesiredHdrHeadroom(float desiredRatio) {
1070*38e8c45fSAndroid Build Coastguard Worker     if (mDrawingState.desiredHdrSdrRatio == desiredRatio) return false;
1071*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.desiredHdrSdrRatio = desiredRatio;
1072*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eTransactionNeeded);
1073*38e8c45fSAndroid Build Coastguard Worker     return true;
1074*38e8c45fSAndroid Build Coastguard Worker }
1075*38e8c45fSAndroid Build Coastguard Worker 
setSidebandStream(const sp<NativeHandle> & sidebandStream,const FrameTimelineInfo & info,nsecs_t postTime,gui::GameMode gameMode)1076*38e8c45fSAndroid Build Coastguard Worker bool Layer::setSidebandStream(const sp<NativeHandle>& sidebandStream, const FrameTimelineInfo& info,
1077*38e8c45fSAndroid Build Coastguard Worker                               nsecs_t postTime, gui::GameMode gameMode) {
1078*38e8c45fSAndroid Build Coastguard Worker     if (mDrawingState.sidebandStream == sidebandStream) return false;
1079*38e8c45fSAndroid Build Coastguard Worker 
1080*38e8c45fSAndroid Build Coastguard Worker     if (mDrawingState.sidebandStream != nullptr && sidebandStream == nullptr) {
1081*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount();
1082*38e8c45fSAndroid Build Coastguard Worker     } else if (sidebandStream != nullptr) {
1083*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mTunnelModeEnabledReporter->incrementTunnelModeCount();
1084*38e8c45fSAndroid Build Coastguard Worker     }
1085*38e8c45fSAndroid Build Coastguard Worker 
1086*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.sidebandStream = sidebandStream;
1087*38e8c45fSAndroid Build Coastguard Worker     if (sidebandStream != nullptr && mDrawingState.buffer != nullptr) {
1088*38e8c45fSAndroid Build Coastguard Worker         releasePreviousBuffer();
1089*38e8c45fSAndroid Build Coastguard Worker         resetDrawingStateBufferInfo();
1090*38e8c45fSAndroid Build Coastguard Worker         mDrawingState.bufferSurfaceFrameTX = nullptr;
1091*38e8c45fSAndroid Build Coastguard Worker         setFrameTimelineVsyncForBufferlessTransaction(info, postTime, gameMode);
1092*38e8c45fSAndroid Build Coastguard Worker     }
1093*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eTransactionNeeded);
1094*38e8c45fSAndroid Build Coastguard Worker     if (!mSidebandStreamChanged.exchange(true)) {
1095*38e8c45fSAndroid Build Coastguard Worker         // mSidebandStreamChanged was false
1096*38e8c45fSAndroid Build Coastguard Worker         mFlinger->onLayerUpdate();
1097*38e8c45fSAndroid Build Coastguard Worker     }
1098*38e8c45fSAndroid Build Coastguard Worker     return true;
1099*38e8c45fSAndroid Build Coastguard Worker }
1100*38e8c45fSAndroid Build Coastguard Worker 
setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>> & handles,bool willPresent)1101*38e8c45fSAndroid Build Coastguard Worker bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles,
1102*38e8c45fSAndroid Build Coastguard Worker                                              bool willPresent) {
1103*38e8c45fSAndroid Build Coastguard Worker     // If there is no handle, we will not send a callback so reset mReleasePreviousBuffer and return
1104*38e8c45fSAndroid Build Coastguard Worker     if (handles.empty()) {
1105*38e8c45fSAndroid Build Coastguard Worker         mReleasePreviousBuffer = false;
1106*38e8c45fSAndroid Build Coastguard Worker         return false;
1107*38e8c45fSAndroid Build Coastguard Worker     }
1108*38e8c45fSAndroid Build Coastguard Worker 
1109*38e8c45fSAndroid Build Coastguard Worker     std::deque<sp<CallbackHandle>> remainingHandles;
1110*38e8c45fSAndroid Build Coastguard Worker     for (const auto& handle : handles) {
1111*38e8c45fSAndroid Build Coastguard Worker         // If this transaction set a buffer on this layer, release its previous buffer
1112*38e8c45fSAndroid Build Coastguard Worker         handle->releasePreviousBuffer = mReleasePreviousBuffer;
1113*38e8c45fSAndroid Build Coastguard Worker 
1114*38e8c45fSAndroid Build Coastguard Worker         // If this layer will be presented in this frame
1115*38e8c45fSAndroid Build Coastguard Worker         if (willPresent) {
1116*38e8c45fSAndroid Build Coastguard Worker             // If this transaction set an acquire fence on this layer, set its acquire time
1117*38e8c45fSAndroid Build Coastguard Worker             handle->acquireTimeOrFence = mCallbackHandleAcquireTimeOrFence;
1118*38e8c45fSAndroid Build Coastguard Worker             handle->frameNumber = mDrawingState.frameNumber;
1119*38e8c45fSAndroid Build Coastguard Worker             handle->previousFrameNumber = mDrawingState.previousFrameNumber;
1120*38e8c45fSAndroid Build Coastguard Worker             if (mPreviousReleaseBufferEndpoint == handle->listener) {
1121*38e8c45fSAndroid Build Coastguard Worker                 // Add fence from previous screenshot now so that it can be dispatched to the
1122*38e8c45fSAndroid Build Coastguard Worker                 // client.
1123*38e8c45fSAndroid Build Coastguard Worker                 for (auto& [_, future] : mAdditionalPreviousReleaseFences) {
1124*38e8c45fSAndroid Build Coastguard Worker                     handle->previousReleaseFences.emplace_back(std::move(future));
1125*38e8c45fSAndroid Build Coastguard Worker                 }
1126*38e8c45fSAndroid Build Coastguard Worker                 mAdditionalPreviousReleaseFences.clear();
1127*38e8c45fSAndroid Build Coastguard Worker             }
1128*38e8c45fSAndroid Build Coastguard Worker             // Store so latched time and release fence can be set
1129*38e8c45fSAndroid Build Coastguard Worker             mDrawingState.callbackHandles.push_back(handle);
1130*38e8c45fSAndroid Build Coastguard Worker 
1131*38e8c45fSAndroid Build Coastguard Worker         } else { // If this layer will NOT need to be relatched and presented this frame
1132*38e8c45fSAndroid Build Coastguard Worker             // Queue this handle to be notified below.
1133*38e8c45fSAndroid Build Coastguard Worker             remainingHandles.push_back(handle);
1134*38e8c45fSAndroid Build Coastguard Worker         }
1135*38e8c45fSAndroid Build Coastguard Worker     }
1136*38e8c45fSAndroid Build Coastguard Worker 
1137*38e8c45fSAndroid Build Coastguard Worker     if (!remainingHandles.empty()) {
1138*38e8c45fSAndroid Build Coastguard Worker         // Notify the transaction completed threads these handles are done. These are only the
1139*38e8c45fSAndroid Build Coastguard Worker         // handles that were not added to the mDrawingState, which will be notified later.
1140*38e8c45fSAndroid Build Coastguard Worker         mFlinger->getTransactionCallbackInvoker().addCallbackHandles(remainingHandles);
1141*38e8c45fSAndroid Build Coastguard Worker     }
1142*38e8c45fSAndroid Build Coastguard Worker 
1143*38e8c45fSAndroid Build Coastguard Worker     mReleasePreviousBuffer = false;
1144*38e8c45fSAndroid Build Coastguard Worker     mCallbackHandleAcquireTimeOrFence = -1;
1145*38e8c45fSAndroid Build Coastguard Worker 
1146*38e8c45fSAndroid Build Coastguard Worker     return willPresent;
1147*38e8c45fSAndroid Build Coastguard Worker }
1148*38e8c45fSAndroid Build Coastguard Worker 
getBufferSize(const State &) const1149*38e8c45fSAndroid Build Coastguard Worker Rect Layer::getBufferSize(const State& /*s*/) const {
1150*38e8c45fSAndroid Build Coastguard Worker     // for buffer state layers we use the display frame size as the buffer size.
1151*38e8c45fSAndroid Build Coastguard Worker 
1152*38e8c45fSAndroid Build Coastguard Worker     if (mBufferInfo.mBuffer == nullptr) {
1153*38e8c45fSAndroid Build Coastguard Worker         return Rect::INVALID_RECT;
1154*38e8c45fSAndroid Build Coastguard Worker     }
1155*38e8c45fSAndroid Build Coastguard Worker 
1156*38e8c45fSAndroid Build Coastguard Worker     uint32_t bufWidth = mBufferInfo.mBuffer->getWidth();
1157*38e8c45fSAndroid Build Coastguard Worker     uint32_t bufHeight = mBufferInfo.mBuffer->getHeight();
1158*38e8c45fSAndroid Build Coastguard Worker 
1159*38e8c45fSAndroid Build Coastguard Worker     // Undo any transformations on the buffer and return the result.
1160*38e8c45fSAndroid Build Coastguard Worker     if (mBufferInfo.mTransform & ui::Transform::ROT_90) {
1161*38e8c45fSAndroid Build Coastguard Worker         std::swap(bufWidth, bufHeight);
1162*38e8c45fSAndroid Build Coastguard Worker     }
1163*38e8c45fSAndroid Build Coastguard Worker 
1164*38e8c45fSAndroid Build Coastguard Worker     if (getTransformToDisplayInverse()) {
1165*38e8c45fSAndroid Build Coastguard Worker         uint32_t invTransform = SurfaceFlinger::getActiveDisplayRotationFlags();
1166*38e8c45fSAndroid Build Coastguard Worker         if (invTransform & ui::Transform::ROT_90) {
1167*38e8c45fSAndroid Build Coastguard Worker             std::swap(bufWidth, bufHeight);
1168*38e8c45fSAndroid Build Coastguard Worker         }
1169*38e8c45fSAndroid Build Coastguard Worker     }
1170*38e8c45fSAndroid Build Coastguard Worker 
1171*38e8c45fSAndroid Build Coastguard Worker     return Rect(0, 0, static_cast<int32_t>(bufWidth), static_cast<int32_t>(bufHeight));
1172*38e8c45fSAndroid Build Coastguard Worker }
1173*38e8c45fSAndroid Build Coastguard Worker 
fenceHasSignaled() const1174*38e8c45fSAndroid Build Coastguard Worker bool Layer::fenceHasSignaled() const {
1175*38e8c45fSAndroid Build Coastguard Worker     if (SurfaceFlinger::enableLatchUnsignaledConfig != LatchUnsignaledConfig::Disabled) {
1176*38e8c45fSAndroid Build Coastguard Worker         return true;
1177*38e8c45fSAndroid Build Coastguard Worker     }
1178*38e8c45fSAndroid Build Coastguard Worker 
1179*38e8c45fSAndroid Build Coastguard Worker     const bool fenceSignaled =
1180*38e8c45fSAndroid Build Coastguard Worker             getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled;
1181*38e8c45fSAndroid Build Coastguard Worker     if (!fenceSignaled) {
1182*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mTimeStats->incrementLatchSkipped(getSequence(),
1183*38e8c45fSAndroid Build Coastguard Worker                                                     TimeStats::LatchSkipReason::LateAcquire);
1184*38e8c45fSAndroid Build Coastguard Worker     }
1185*38e8c45fSAndroid Build Coastguard Worker 
1186*38e8c45fSAndroid Build Coastguard Worker     return fenceSignaled;
1187*38e8c45fSAndroid Build Coastguard Worker }
1188*38e8c45fSAndroid Build Coastguard Worker 
onPreComposition(nsecs_t refreshStartTime)1189*38e8c45fSAndroid Build Coastguard Worker void Layer::onPreComposition(nsecs_t refreshStartTime) {
1190*38e8c45fSAndroid Build Coastguard Worker     for (const auto& handle : mDrawingState.callbackHandles) {
1191*38e8c45fSAndroid Build Coastguard Worker         handle->refreshStartTime = refreshStartTime;
1192*38e8c45fSAndroid Build Coastguard Worker     }
1193*38e8c45fSAndroid Build Coastguard Worker }
1194*38e8c45fSAndroid Build Coastguard Worker 
latchSidebandStream(bool & recomputeVisibleRegions)1195*38e8c45fSAndroid Build Coastguard Worker bool Layer::latchSidebandStream(bool& recomputeVisibleRegions) {
1196*38e8c45fSAndroid Build Coastguard Worker     if (mSidebandStreamChanged.exchange(false)) {
1197*38e8c45fSAndroid Build Coastguard Worker         const State& s(getDrawingState());
1198*38e8c45fSAndroid Build Coastguard Worker         // mSidebandStreamChanged was true
1199*38e8c45fSAndroid Build Coastguard Worker         mSidebandStream = s.sidebandStream;
1200*38e8c45fSAndroid Build Coastguard Worker         if (mSidebandStream != nullptr) {
1201*38e8c45fSAndroid Build Coastguard Worker             setTransactionFlags(eTransactionNeeded);
1202*38e8c45fSAndroid Build Coastguard Worker             mFlinger->setTransactionFlags(eTraversalNeeded);
1203*38e8c45fSAndroid Build Coastguard Worker         }
1204*38e8c45fSAndroid Build Coastguard Worker         recomputeVisibleRegions = true;
1205*38e8c45fSAndroid Build Coastguard Worker         return true;
1206*38e8c45fSAndroid Build Coastguard Worker     }
1207*38e8c45fSAndroid Build Coastguard Worker     return false;
1208*38e8c45fSAndroid Build Coastguard Worker }
1209*38e8c45fSAndroid Build Coastguard Worker 
updateTexImage(nsecs_t latchTime,bool bgColorOnly)1210*38e8c45fSAndroid Build Coastguard Worker void Layer::updateTexImage(nsecs_t latchTime, bool bgColorOnly) {
1211*38e8c45fSAndroid Build Coastguard Worker     const State& s(getDrawingState());
1212*38e8c45fSAndroid Build Coastguard Worker 
1213*38e8c45fSAndroid Build Coastguard Worker     if (!s.buffer) {
1214*38e8c45fSAndroid Build Coastguard Worker         if (bgColorOnly || mBufferInfo.mBuffer) {
1215*38e8c45fSAndroid Build Coastguard Worker             for (auto& handle : mDrawingState.callbackHandles) {
1216*38e8c45fSAndroid Build Coastguard Worker                 handle->latchTime = latchTime;
1217*38e8c45fSAndroid Build Coastguard Worker             }
1218*38e8c45fSAndroid Build Coastguard Worker         }
1219*38e8c45fSAndroid Build Coastguard Worker         return;
1220*38e8c45fSAndroid Build Coastguard Worker     }
1221*38e8c45fSAndroid Build Coastguard Worker 
1222*38e8c45fSAndroid Build Coastguard Worker     for (auto& handle : mDrawingState.callbackHandles) {
1223*38e8c45fSAndroid Build Coastguard Worker         if (handle->frameNumber == mDrawingState.frameNumber) {
1224*38e8c45fSAndroid Build Coastguard Worker             handle->latchTime = latchTime;
1225*38e8c45fSAndroid Build Coastguard Worker         }
1226*38e8c45fSAndroid Build Coastguard Worker     }
1227*38e8c45fSAndroid Build Coastguard Worker 
1228*38e8c45fSAndroid Build Coastguard Worker     const int32_t layerId = getSequence();
1229*38e8c45fSAndroid Build Coastguard Worker     const uint64_t bufferId = mDrawingState.buffer->getId();
1230*38e8c45fSAndroid Build Coastguard Worker     const uint64_t frameNumber = mDrawingState.frameNumber;
1231*38e8c45fSAndroid Build Coastguard Worker     const auto acquireFence = std::make_shared<FenceTime>(mDrawingState.acquireFence);
1232*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mTimeStats->setAcquireFence(layerId, frameNumber, acquireFence);
1233*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mTimeStats->setLatchTime(layerId, frameNumber, latchTime);
1234*38e8c45fSAndroid Build Coastguard Worker 
1235*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mFrameTracer->traceFence(layerId, bufferId, frameNumber, acquireFence,
1236*38e8c45fSAndroid Build Coastguard Worker                                        FrameTracer::FrameEvent::ACQUIRE_FENCE);
1237*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, latchTime,
1238*38e8c45fSAndroid Build Coastguard Worker                                            FrameTracer::FrameEvent::LATCH);
1239*38e8c45fSAndroid Build Coastguard Worker 
1240*38e8c45fSAndroid Build Coastguard Worker     auto& bufferSurfaceFrame = mDrawingState.bufferSurfaceFrameTX;
1241*38e8c45fSAndroid Build Coastguard Worker     if (bufferSurfaceFrame != nullptr &&
1242*38e8c45fSAndroid Build Coastguard Worker         bufferSurfaceFrame->getPresentState() != PresentState::Presented) {
1243*38e8c45fSAndroid Build Coastguard Worker         // Update only if the bufferSurfaceFrame wasn't already presented. A Presented
1244*38e8c45fSAndroid Build Coastguard Worker         // bufferSurfaceFrame could be seen here if a pending state was applied successfully and we
1245*38e8c45fSAndroid Build Coastguard Worker         // are processing the next state.
1246*38e8c45fSAndroid Build Coastguard Worker         addSurfaceFramePresentedForBuffer(bufferSurfaceFrame,
1247*38e8c45fSAndroid Build Coastguard Worker                                           mDrawingState.acquireFenceTime->getSignalTime(),
1248*38e8c45fSAndroid Build Coastguard Worker                                           latchTime);
1249*38e8c45fSAndroid Build Coastguard Worker         mDrawingState.bufferSurfaceFrameTX.reset();
1250*38e8c45fSAndroid Build Coastguard Worker     }
1251*38e8c45fSAndroid Build Coastguard Worker 
1252*38e8c45fSAndroid Build Coastguard Worker     std::deque<sp<CallbackHandle>> remainingHandles;
1253*38e8c45fSAndroid Build Coastguard Worker     mFlinger->getTransactionCallbackInvoker()
1254*38e8c45fSAndroid Build Coastguard Worker             .addOnCommitCallbackHandles(mDrawingState.callbackHandles, remainingHandles);
1255*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.callbackHandles = remainingHandles;
1256*38e8c45fSAndroid Build Coastguard Worker }
1257*38e8c45fSAndroid Build Coastguard Worker 
gatherBufferInfo()1258*38e8c45fSAndroid Build Coastguard Worker void Layer::gatherBufferInfo() {
1259*38e8c45fSAndroid Build Coastguard Worker     mPreviousReleaseCallbackId = {getCurrentBufferId(), mBufferInfo.mFrameNumber};
1260*38e8c45fSAndroid Build Coastguard Worker     mPreviousReleaseBufferEndpoint = mBufferInfo.mReleaseBufferEndpoint;
1261*38e8c45fSAndroid Build Coastguard Worker     if (!mDrawingState.buffer) {
1262*38e8c45fSAndroid Build Coastguard Worker         mBufferInfo = {};
1263*38e8c45fSAndroid Build Coastguard Worker         return;
1264*38e8c45fSAndroid Build Coastguard Worker     }
1265*38e8c45fSAndroid Build Coastguard Worker 
1266*38e8c45fSAndroid Build Coastguard Worker     if ((!mBufferInfo.mBuffer || !mDrawingState.buffer->hasSameBuffer(*mBufferInfo.mBuffer))) {
1267*38e8c45fSAndroid Build Coastguard Worker         decrementPendingBufferCount();
1268*38e8c45fSAndroid Build Coastguard Worker     }
1269*38e8c45fSAndroid Build Coastguard Worker 
1270*38e8c45fSAndroid Build Coastguard Worker     mBufferInfo.mBuffer = mDrawingState.buffer;
1271*38e8c45fSAndroid Build Coastguard Worker     mBufferInfo.mReleaseBufferEndpoint = mDrawingState.releaseBufferEndpoint;
1272*38e8c45fSAndroid Build Coastguard Worker     mBufferInfo.mFence = mDrawingState.acquireFence;
1273*38e8c45fSAndroid Build Coastguard Worker     mBufferInfo.mFrameNumber = mDrawingState.frameNumber;
1274*38e8c45fSAndroid Build Coastguard Worker     mBufferInfo.mPixelFormat =
1275*38e8c45fSAndroid Build Coastguard Worker             !mBufferInfo.mBuffer ? PIXEL_FORMAT_NONE : mBufferInfo.mBuffer->getPixelFormat();
1276*38e8c45fSAndroid Build Coastguard Worker     mBufferInfo.mFrameLatencyNeeded = true;
1277*38e8c45fSAndroid Build Coastguard Worker     mBufferInfo.mDesiredPresentTime = mDrawingState.desiredPresentTime;
1278*38e8c45fSAndroid Build Coastguard Worker     mBufferInfo.mFenceTime = std::make_shared<FenceTime>(mDrawingState.acquireFence);
1279*38e8c45fSAndroid Build Coastguard Worker     mBufferInfo.mTransform = mDrawingState.bufferTransform;
1280*38e8c45fSAndroid Build Coastguard Worker     auto lastDataspace = mBufferInfo.mDataspace;
1281*38e8c45fSAndroid Build Coastguard Worker     mBufferInfo.mDataspace = translateDataspace(mDrawingState.dataspace);
1282*38e8c45fSAndroid Build Coastguard Worker     if (mBufferInfo.mBuffer != nullptr) {
1283*38e8c45fSAndroid Build Coastguard Worker         auto& mapper = GraphicBufferMapper::get();
1284*38e8c45fSAndroid Build Coastguard Worker         // TODO: We should measure if it's faster to do a blind write if we're on newer api levels
1285*38e8c45fSAndroid Build Coastguard Worker         // and don't need to possibly remaps buffers.
1286*38e8c45fSAndroid Build Coastguard Worker         ui::Dataspace dataspace = ui::Dataspace::UNKNOWN;
1287*38e8c45fSAndroid Build Coastguard Worker         status_t err = OK;
1288*38e8c45fSAndroid Build Coastguard Worker         {
1289*38e8c45fSAndroid Build Coastguard Worker             SFTRACE_NAME("getDataspace");
1290*38e8c45fSAndroid Build Coastguard Worker             err = mapper.getDataspace(mBufferInfo.mBuffer->getBuffer()->handle, &dataspace);
1291*38e8c45fSAndroid Build Coastguard Worker         }
1292*38e8c45fSAndroid Build Coastguard Worker         if (err != OK || dataspace != mBufferInfo.mDataspace) {
1293*38e8c45fSAndroid Build Coastguard Worker             {
1294*38e8c45fSAndroid Build Coastguard Worker                 SFTRACE_NAME("setDataspace");
1295*38e8c45fSAndroid Build Coastguard Worker                 err = mapper.setDataspace(mBufferInfo.mBuffer->getBuffer()->handle,
1296*38e8c45fSAndroid Build Coastguard Worker                                           static_cast<ui::Dataspace>(mBufferInfo.mDataspace));
1297*38e8c45fSAndroid Build Coastguard Worker             }
1298*38e8c45fSAndroid Build Coastguard Worker 
1299*38e8c45fSAndroid Build Coastguard Worker             // Some GPU drivers may cache gralloc metadata which means before we composite we need
1300*38e8c45fSAndroid Build Coastguard Worker             // to upsert RenderEngine's caches. Put in a special workaround to be backwards
1301*38e8c45fSAndroid Build Coastguard Worker             // compatible with old vendors, with a ticking clock.
1302*38e8c45fSAndroid Build Coastguard Worker             static const int32_t kVendorVersion =
1303*38e8c45fSAndroid Build Coastguard Worker                     base::GetIntProperty("ro.board.api_level", __ANDROID_API_FUTURE__);
1304*38e8c45fSAndroid Build Coastguard Worker             if (const auto format =
1305*38e8c45fSAndroid Build Coastguard Worker                         static_cast<aidl::android::hardware::graphics::common::PixelFormat>(
1306*38e8c45fSAndroid Build Coastguard Worker                                 mBufferInfo.mBuffer->getPixelFormat());
1307*38e8c45fSAndroid Build Coastguard Worker                 err == OK && kVendorVersion < __ANDROID_API_U__ &&
1308*38e8c45fSAndroid Build Coastguard Worker                 (format ==
1309*38e8c45fSAndroid Build Coastguard Worker                          aidl::android::hardware::graphics::common::PixelFormat::
1310*38e8c45fSAndroid Build Coastguard Worker                                  IMPLEMENTATION_DEFINED ||
1311*38e8c45fSAndroid Build Coastguard Worker                  format == aidl::android::hardware::graphics::common::PixelFormat::YCBCR_420_888 ||
1312*38e8c45fSAndroid Build Coastguard Worker                  format == aidl::android::hardware::graphics::common::PixelFormat::YV12 ||
1313*38e8c45fSAndroid Build Coastguard Worker                  format == aidl::android::hardware::graphics::common::PixelFormat::YCBCR_P010)) {
1314*38e8c45fSAndroid Build Coastguard Worker                 mBufferInfo.mBuffer->remapBuffer();
1315*38e8c45fSAndroid Build Coastguard Worker             }
1316*38e8c45fSAndroid Build Coastguard Worker         }
1317*38e8c45fSAndroid Build Coastguard Worker     }
1318*38e8c45fSAndroid Build Coastguard Worker     if (lastDataspace != mBufferInfo.mDataspace ||
1319*38e8c45fSAndroid Build Coastguard Worker         mBufferInfo.mTimeSinceDataspaceUpdate == std::chrono::steady_clock::time_point::min()) {
1320*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mHdrLayerInfoChanged = true;
1321*38e8c45fSAndroid Build Coastguard Worker         const auto currentTime = std::chrono::steady_clock::now();
1322*38e8c45fSAndroid Build Coastguard Worker         if (mBufferInfo.mTimeSinceDataspaceUpdate > std::chrono::steady_clock::time_point::min()) {
1323*38e8c45fSAndroid Build Coastguard Worker             mFlinger->mLayerEvents
1324*38e8c45fSAndroid Build Coastguard Worker                     .emplace_back(mOwnerUid, getSequence(), lastDataspace,
1325*38e8c45fSAndroid Build Coastguard Worker                                   std::chrono::duration_cast<std::chrono::milliseconds>(
1326*38e8c45fSAndroid Build Coastguard Worker                                           currentTime - mBufferInfo.mTimeSinceDataspaceUpdate));
1327*38e8c45fSAndroid Build Coastguard Worker         }
1328*38e8c45fSAndroid Build Coastguard Worker         mBufferInfo.mTimeSinceDataspaceUpdate = currentTime;
1329*38e8c45fSAndroid Build Coastguard Worker     }
1330*38e8c45fSAndroid Build Coastguard Worker     if (mBufferInfo.mDesiredHdrSdrRatio != mDrawingState.desiredHdrSdrRatio) {
1331*38e8c45fSAndroid Build Coastguard Worker         mBufferInfo.mDesiredHdrSdrRatio = mDrawingState.desiredHdrSdrRatio;
1332*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mHdrLayerInfoChanged = true;
1333*38e8c45fSAndroid Build Coastguard Worker     }
1334*38e8c45fSAndroid Build Coastguard Worker     mBufferInfo.mCrop = computeBufferCrop(mDrawingState);
1335*38e8c45fSAndroid Build Coastguard Worker     mBufferInfo.mTransformToDisplayInverse = mDrawingState.transformToDisplayInverse;
1336*38e8c45fSAndroid Build Coastguard Worker }
1337*38e8c45fSAndroid Build Coastguard Worker 
computeBufferCrop(const State & s)1338*38e8c45fSAndroid Build Coastguard Worker Rect Layer::computeBufferCrop(const State& s) {
1339*38e8c45fSAndroid Build Coastguard Worker     if (s.buffer && !s.bufferCrop.isEmpty()) {
1340*38e8c45fSAndroid Build Coastguard Worker         Rect bufferCrop;
1341*38e8c45fSAndroid Build Coastguard Worker         s.buffer->getBounds().intersect(s.bufferCrop, &bufferCrop);
1342*38e8c45fSAndroid Build Coastguard Worker         return bufferCrop;
1343*38e8c45fSAndroid Build Coastguard Worker     } else if (s.buffer) {
1344*38e8c45fSAndroid Build Coastguard Worker         return s.buffer->getBounds();
1345*38e8c45fSAndroid Build Coastguard Worker     } else {
1346*38e8c45fSAndroid Build Coastguard Worker         return s.bufferCrop;
1347*38e8c45fSAndroid Build Coastguard Worker     }
1348*38e8c45fSAndroid Build Coastguard Worker }
1349*38e8c45fSAndroid Build Coastguard Worker 
decrementPendingBufferCount()1350*38e8c45fSAndroid Build Coastguard Worker void Layer::decrementPendingBufferCount() {
1351*38e8c45fSAndroid Build Coastguard Worker     int32_t pendingBuffers = --mPendingBuffers;
1352*38e8c45fSAndroid Build Coastguard Worker     tracePendingBufferCount(pendingBuffers);
1353*38e8c45fSAndroid Build Coastguard Worker }
1354*38e8c45fSAndroid Build Coastguard Worker 
tracePendingBufferCount(int32_t pendingBuffers)1355*38e8c45fSAndroid Build Coastguard Worker void Layer::tracePendingBufferCount(int32_t pendingBuffers) {
1356*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_INT(mBlastTransactionName.c_str(), pendingBuffers);
1357*38e8c45fSAndroid Build Coastguard Worker }
1358*38e8c45fSAndroid Build Coastguard Worker 
getCompositionEngineLayerFE(const frontend::LayerHierarchy::TraversalPath & path)1359*38e8c45fSAndroid Build Coastguard Worker sp<LayerFE> Layer::getCompositionEngineLayerFE(
1360*38e8c45fSAndroid Build Coastguard Worker         const frontend::LayerHierarchy::TraversalPath& path) {
1361*38e8c45fSAndroid Build Coastguard Worker     for (auto& [p, layerFE] : mLayerFEs) {
1362*38e8c45fSAndroid Build Coastguard Worker         if (p == path) {
1363*38e8c45fSAndroid Build Coastguard Worker             return layerFE;
1364*38e8c45fSAndroid Build Coastguard Worker         }
1365*38e8c45fSAndroid Build Coastguard Worker     }
1366*38e8c45fSAndroid Build Coastguard Worker     auto layerFE = mFlinger->getFactory().createLayerFE(mName, this);
1367*38e8c45fSAndroid Build Coastguard Worker     mLayerFEs.emplace_back(path, layerFE);
1368*38e8c45fSAndroid Build Coastguard Worker     return layerFE;
1369*38e8c45fSAndroid Build Coastguard Worker }
1370*38e8c45fSAndroid Build Coastguard Worker 
onCompositionPresented(const DisplayDevice * display,const std::shared_ptr<FenceTime> & glDoneFence,const std::shared_ptr<FenceTime> & presentFence,const CompositorTiming & compositorTiming,gui::GameMode gameMode)1371*38e8c45fSAndroid Build Coastguard Worker void Layer::onCompositionPresented(const DisplayDevice* display,
1372*38e8c45fSAndroid Build Coastguard Worker                                    const std::shared_ptr<FenceTime>& glDoneFence,
1373*38e8c45fSAndroid Build Coastguard Worker                                    const std::shared_ptr<FenceTime>& presentFence,
1374*38e8c45fSAndroid Build Coastguard Worker                                    const CompositorTiming& compositorTiming,
1375*38e8c45fSAndroid Build Coastguard Worker                                    gui::GameMode gameMode) {
1376*38e8c45fSAndroid Build Coastguard Worker     // mFrameLatencyNeeded is true when a new frame was latched for the
1377*38e8c45fSAndroid Build Coastguard Worker     // composition.
1378*38e8c45fSAndroid Build Coastguard Worker     if (!mBufferInfo.mFrameLatencyNeeded) return;
1379*38e8c45fSAndroid Build Coastguard Worker 
1380*38e8c45fSAndroid Build Coastguard Worker     for (const auto& handle : mDrawingState.callbackHandles) {
1381*38e8c45fSAndroid Build Coastguard Worker         handle->gpuCompositionDoneFence = glDoneFence;
1382*38e8c45fSAndroid Build Coastguard Worker         handle->compositorTiming = compositorTiming;
1383*38e8c45fSAndroid Build Coastguard Worker     }
1384*38e8c45fSAndroid Build Coastguard Worker 
1385*38e8c45fSAndroid Build Coastguard Worker     // Update mDeprecatedFrameTracker.
1386*38e8c45fSAndroid Build Coastguard Worker     nsecs_t desiredPresentTime = mBufferInfo.mDesiredPresentTime;
1387*38e8c45fSAndroid Build Coastguard Worker     mDeprecatedFrameTracker.setDesiredPresentTime(desiredPresentTime);
1388*38e8c45fSAndroid Build Coastguard Worker 
1389*38e8c45fSAndroid Build Coastguard Worker     const int32_t layerId = getSequence();
1390*38e8c45fSAndroid Build Coastguard Worker     mFlinger->mTimeStats->setDesiredTime(layerId, mCurrentFrameNumber, desiredPresentTime);
1391*38e8c45fSAndroid Build Coastguard Worker 
1392*38e8c45fSAndroid Build Coastguard Worker     const auto outputLayer = findOutputLayerForDisplay(display);
1393*38e8c45fSAndroid Build Coastguard Worker     if (outputLayer && outputLayer->requiresClientComposition()) {
1394*38e8c45fSAndroid Build Coastguard Worker         nsecs_t clientCompositionTimestamp = outputLayer->getState().clientCompositionTimestamp;
1395*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mFrameTracer->traceTimestamp(layerId, getCurrentBufferId(), mCurrentFrameNumber,
1396*38e8c45fSAndroid Build Coastguard Worker                                                clientCompositionTimestamp,
1397*38e8c45fSAndroid Build Coastguard Worker                                                FrameTracer::FrameEvent::FALLBACK_COMPOSITION);
1398*38e8c45fSAndroid Build Coastguard Worker         // Update the SurfaceFrames in the drawing state
1399*38e8c45fSAndroid Build Coastguard Worker         if (mDrawingState.bufferSurfaceFrameTX) {
1400*38e8c45fSAndroid Build Coastguard Worker             mDrawingState.bufferSurfaceFrameTX->setGpuComposition();
1401*38e8c45fSAndroid Build Coastguard Worker         }
1402*38e8c45fSAndroid Build Coastguard Worker         for (auto& [token, surfaceFrame] : mDrawingState.bufferlessSurfaceFramesTX) {
1403*38e8c45fSAndroid Build Coastguard Worker             surfaceFrame->setGpuComposition();
1404*38e8c45fSAndroid Build Coastguard Worker         }
1405*38e8c45fSAndroid Build Coastguard Worker     }
1406*38e8c45fSAndroid Build Coastguard Worker 
1407*38e8c45fSAndroid Build Coastguard Worker     // The SurfaceFrame's AcquireFence is the same as this.
1408*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<FenceTime> frameReadyFence = mBufferInfo.mFenceTime;
1409*38e8c45fSAndroid Build Coastguard Worker     if (frameReadyFence->isValid()) {
1410*38e8c45fSAndroid Build Coastguard Worker         mDeprecatedFrameTracker.setFrameReadyFence(std::move(frameReadyFence));
1411*38e8c45fSAndroid Build Coastguard Worker     } else {
1412*38e8c45fSAndroid Build Coastguard Worker         // There was no fence for this frame, so assume that it was ready
1413*38e8c45fSAndroid Build Coastguard Worker         // to be presented at the desired present time.
1414*38e8c45fSAndroid Build Coastguard Worker         mDeprecatedFrameTracker.setFrameReadyTime(desiredPresentTime);
1415*38e8c45fSAndroid Build Coastguard Worker     }
1416*38e8c45fSAndroid Build Coastguard Worker     if (display) {
1417*38e8c45fSAndroid Build Coastguard Worker         const auto activeMode = display->refreshRateSelector().getActiveMode();
1418*38e8c45fSAndroid Build Coastguard Worker         const Fps refreshRate = activeMode.fps;
1419*38e8c45fSAndroid Build Coastguard Worker         const std::optional<Fps> renderRate =
1420*38e8c45fSAndroid Build Coastguard Worker                 mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
1421*38e8c45fSAndroid Build Coastguard Worker 
1422*38e8c45fSAndroid Build Coastguard Worker         const auto vote = frameRateToSetFrameRateVotePayload(getFrameRateForLayerTree());
1423*38e8c45fSAndroid Build Coastguard Worker 
1424*38e8c45fSAndroid Build Coastguard Worker         if (presentFence->isValid()) {
1425*38e8c45fSAndroid Build Coastguard Worker             mFlinger->mTimeStats->setPresentFence(layerId, mCurrentFrameNumber, presentFence,
1426*38e8c45fSAndroid Build Coastguard Worker                                                   refreshRate, renderRate, vote, gameMode);
1427*38e8c45fSAndroid Build Coastguard Worker             mFlinger->mFrameTracer->traceFence(layerId, getCurrentBufferId(), mCurrentFrameNumber,
1428*38e8c45fSAndroid Build Coastguard Worker                                                presentFence,
1429*38e8c45fSAndroid Build Coastguard Worker                                                FrameTracer::FrameEvent::PRESENT_FENCE);
1430*38e8c45fSAndroid Build Coastguard Worker             mDeprecatedFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
1431*38e8c45fSAndroid Build Coastguard Worker         } else if (const auto displayId = PhysicalDisplayId::tryCast(display->getId());
1432*38e8c45fSAndroid Build Coastguard Worker                    displayId && mFlinger->getHwComposer().isConnected(*displayId)) {
1433*38e8c45fSAndroid Build Coastguard Worker             // The HWC doesn't support present fences, so use the present timestamp instead.
1434*38e8c45fSAndroid Build Coastguard Worker             const nsecs_t presentTimestamp =
1435*38e8c45fSAndroid Build Coastguard Worker                     mFlinger->getHwComposer().getPresentTimestamp(*displayId);
1436*38e8c45fSAndroid Build Coastguard Worker 
1437*38e8c45fSAndroid Build Coastguard Worker             const nsecs_t now = systemTime(CLOCK_MONOTONIC);
1438*38e8c45fSAndroid Build Coastguard Worker             const nsecs_t vsyncPeriod =
1439*38e8c45fSAndroid Build Coastguard Worker                     mFlinger->getHwComposer()
1440*38e8c45fSAndroid Build Coastguard Worker                             .getDisplayVsyncPeriod(*displayId)
1441*38e8c45fSAndroid Build Coastguard Worker                             .value_opt()
1442*38e8c45fSAndroid Build Coastguard Worker                             .value_or(activeMode.modePtr->getVsyncRate().getPeriodNsecs());
1443*38e8c45fSAndroid Build Coastguard Worker 
1444*38e8c45fSAndroid Build Coastguard Worker             const nsecs_t actualPresentTime = now - ((now - presentTimestamp) % vsyncPeriod);
1445*38e8c45fSAndroid Build Coastguard Worker 
1446*38e8c45fSAndroid Build Coastguard Worker             mFlinger->mTimeStats->setPresentTime(layerId, mCurrentFrameNumber, actualPresentTime,
1447*38e8c45fSAndroid Build Coastguard Worker                                                  refreshRate, renderRate, vote, gameMode);
1448*38e8c45fSAndroid Build Coastguard Worker             mFlinger->mFrameTracer->traceTimestamp(layerId, getCurrentBufferId(),
1449*38e8c45fSAndroid Build Coastguard Worker                                                    mCurrentFrameNumber, actualPresentTime,
1450*38e8c45fSAndroid Build Coastguard Worker                                                    FrameTracer::FrameEvent::PRESENT_FENCE);
1451*38e8c45fSAndroid Build Coastguard Worker             mDeprecatedFrameTracker.setActualPresentTime(actualPresentTime);
1452*38e8c45fSAndroid Build Coastguard Worker         }
1453*38e8c45fSAndroid Build Coastguard Worker     }
1454*38e8c45fSAndroid Build Coastguard Worker 
1455*38e8c45fSAndroid Build Coastguard Worker     mFrameStatsHistorySize++;
1456*38e8c45fSAndroid Build Coastguard Worker     mDeprecatedFrameTracker.advanceFrame();
1457*38e8c45fSAndroid Build Coastguard Worker     mBufferInfo.mFrameLatencyNeeded = false;
1458*38e8c45fSAndroid Build Coastguard Worker }
1459*38e8c45fSAndroid Build Coastguard Worker 
latchBufferImpl(bool & recomputeVisibleRegions,nsecs_t latchTime,bool bgColorOnly)1460*38e8c45fSAndroid Build Coastguard Worker bool Layer::latchBufferImpl(bool& recomputeVisibleRegions, nsecs_t latchTime, bool bgColorOnly) {
1461*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_FORMAT_INSTANT("latchBuffer %s - %" PRIu64, getDebugName(),
1462*38e8c45fSAndroid Build Coastguard Worker                            getDrawingState().frameNumber);
1463*38e8c45fSAndroid Build Coastguard Worker 
1464*38e8c45fSAndroid Build Coastguard Worker     bool refreshRequired = latchSidebandStream(recomputeVisibleRegions);
1465*38e8c45fSAndroid Build Coastguard Worker 
1466*38e8c45fSAndroid Build Coastguard Worker     if (refreshRequired) {
1467*38e8c45fSAndroid Build Coastguard Worker         return refreshRequired;
1468*38e8c45fSAndroid Build Coastguard Worker     }
1469*38e8c45fSAndroid Build Coastguard Worker 
1470*38e8c45fSAndroid Build Coastguard Worker     // If the head buffer's acquire fence hasn't signaled yet, return and
1471*38e8c45fSAndroid Build Coastguard Worker     // try again later
1472*38e8c45fSAndroid Build Coastguard Worker     if (!fenceHasSignaled()) {
1473*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_NAME("!fenceHasSignaled()");
1474*38e8c45fSAndroid Build Coastguard Worker         mFlinger->onLayerUpdate();
1475*38e8c45fSAndroid Build Coastguard Worker         return false;
1476*38e8c45fSAndroid Build Coastguard Worker     }
1477*38e8c45fSAndroid Build Coastguard Worker     updateTexImage(latchTime, bgColorOnly);
1478*38e8c45fSAndroid Build Coastguard Worker 
1479*38e8c45fSAndroid Build Coastguard Worker     // Capture the old state of the layer for comparisons later
1480*38e8c45fSAndroid Build Coastguard Worker     BufferInfo oldBufferInfo = mBufferInfo;
1481*38e8c45fSAndroid Build Coastguard Worker     mPreviousFrameNumber = mCurrentFrameNumber;
1482*38e8c45fSAndroid Build Coastguard Worker     mCurrentFrameNumber = mDrawingState.frameNumber;
1483*38e8c45fSAndroid Build Coastguard Worker     gatherBufferInfo();
1484*38e8c45fSAndroid Build Coastguard Worker 
1485*38e8c45fSAndroid Build Coastguard Worker     if (mBufferInfo.mBuffer) {
1486*38e8c45fSAndroid Build Coastguard Worker         // We latched a buffer that will be presented soon. Clear the previously presented layer
1487*38e8c45fSAndroid Build Coastguard Worker         // stack list.
1488*38e8c45fSAndroid Build Coastguard Worker         mPreviouslyPresentedLayerStacks.clear();
1489*38e8c45fSAndroid Build Coastguard Worker     }
1490*38e8c45fSAndroid Build Coastguard Worker 
1491*38e8c45fSAndroid Build Coastguard Worker     if (mDrawingState.buffer == nullptr) {
1492*38e8c45fSAndroid Build Coastguard Worker         const bool bufferReleased = oldBufferInfo.mBuffer != nullptr;
1493*38e8c45fSAndroid Build Coastguard Worker         recomputeVisibleRegions = bufferReleased;
1494*38e8c45fSAndroid Build Coastguard Worker         return bufferReleased;
1495*38e8c45fSAndroid Build Coastguard Worker     }
1496*38e8c45fSAndroid Build Coastguard Worker 
1497*38e8c45fSAndroid Build Coastguard Worker     if (oldBufferInfo.mBuffer == nullptr) {
1498*38e8c45fSAndroid Build Coastguard Worker         // the first time we receive a buffer, we need to trigger a
1499*38e8c45fSAndroid Build Coastguard Worker         // geometry invalidation.
1500*38e8c45fSAndroid Build Coastguard Worker         recomputeVisibleRegions = true;
1501*38e8c45fSAndroid Build Coastguard Worker     }
1502*38e8c45fSAndroid Build Coastguard Worker 
1503*38e8c45fSAndroid Build Coastguard Worker     if ((mBufferInfo.mCrop != oldBufferInfo.mCrop) ||
1504*38e8c45fSAndroid Build Coastguard Worker         (mBufferInfo.mTransform != oldBufferInfo.mTransform) ||
1505*38e8c45fSAndroid Build Coastguard Worker         (mBufferInfo.mTransformToDisplayInverse != oldBufferInfo.mTransformToDisplayInverse)) {
1506*38e8c45fSAndroid Build Coastguard Worker         recomputeVisibleRegions = true;
1507*38e8c45fSAndroid Build Coastguard Worker     }
1508*38e8c45fSAndroid Build Coastguard Worker 
1509*38e8c45fSAndroid Build Coastguard Worker     if (oldBufferInfo.mBuffer != nullptr) {
1510*38e8c45fSAndroid Build Coastguard Worker         uint32_t bufWidth = mBufferInfo.mBuffer->getWidth();
1511*38e8c45fSAndroid Build Coastguard Worker         uint32_t bufHeight = mBufferInfo.mBuffer->getHeight();
1512*38e8c45fSAndroid Build Coastguard Worker         if (bufWidth != oldBufferInfo.mBuffer->getWidth() ||
1513*38e8c45fSAndroid Build Coastguard Worker             bufHeight != oldBufferInfo.mBuffer->getHeight()) {
1514*38e8c45fSAndroid Build Coastguard Worker             recomputeVisibleRegions = true;
1515*38e8c45fSAndroid Build Coastguard Worker         }
1516*38e8c45fSAndroid Build Coastguard Worker     }
1517*38e8c45fSAndroid Build Coastguard Worker     return true;
1518*38e8c45fSAndroid Build Coastguard Worker }
1519*38e8c45fSAndroid Build Coastguard Worker 
getTransformToDisplayInverse() const1520*38e8c45fSAndroid Build Coastguard Worker bool Layer::getTransformToDisplayInverse() const {
1521*38e8c45fSAndroid Build Coastguard Worker     return mBufferInfo.mTransformToDisplayInverse;
1522*38e8c45fSAndroid Build Coastguard Worker }
1523*38e8c45fSAndroid Build Coastguard Worker 
translateDataspace(ui::Dataspace dataspace)1524*38e8c45fSAndroid Build Coastguard Worker ui::Dataspace Layer::translateDataspace(ui::Dataspace dataspace) {
1525*38e8c45fSAndroid Build Coastguard Worker     ui::Dataspace updatedDataspace = dataspace;
1526*38e8c45fSAndroid Build Coastguard Worker     // translate legacy dataspaces to modern dataspaces
1527*38e8c45fSAndroid Build Coastguard Worker     switch (dataspace) {
1528*38e8c45fSAndroid Build Coastguard Worker         // Treat unknown dataspaces as V0_sRGB
1529*38e8c45fSAndroid Build Coastguard Worker         case ui::Dataspace::UNKNOWN:
1530*38e8c45fSAndroid Build Coastguard Worker         case ui::Dataspace::SRGB:
1531*38e8c45fSAndroid Build Coastguard Worker             updatedDataspace = ui::Dataspace::V0_SRGB;
1532*38e8c45fSAndroid Build Coastguard Worker             break;
1533*38e8c45fSAndroid Build Coastguard Worker         case ui::Dataspace::SRGB_LINEAR:
1534*38e8c45fSAndroid Build Coastguard Worker             updatedDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1535*38e8c45fSAndroid Build Coastguard Worker             break;
1536*38e8c45fSAndroid Build Coastguard Worker         case ui::Dataspace::JFIF:
1537*38e8c45fSAndroid Build Coastguard Worker             updatedDataspace = ui::Dataspace::V0_JFIF;
1538*38e8c45fSAndroid Build Coastguard Worker             break;
1539*38e8c45fSAndroid Build Coastguard Worker         case ui::Dataspace::BT601_625:
1540*38e8c45fSAndroid Build Coastguard Worker             updatedDataspace = ui::Dataspace::V0_BT601_625;
1541*38e8c45fSAndroid Build Coastguard Worker             break;
1542*38e8c45fSAndroid Build Coastguard Worker         case ui::Dataspace::BT601_525:
1543*38e8c45fSAndroid Build Coastguard Worker             updatedDataspace = ui::Dataspace::V0_BT601_525;
1544*38e8c45fSAndroid Build Coastguard Worker             break;
1545*38e8c45fSAndroid Build Coastguard Worker         case ui::Dataspace::BT709:
1546*38e8c45fSAndroid Build Coastguard Worker             updatedDataspace = ui::Dataspace::V0_BT709;
1547*38e8c45fSAndroid Build Coastguard Worker             break;
1548*38e8c45fSAndroid Build Coastguard Worker         default:
1549*38e8c45fSAndroid Build Coastguard Worker             break;
1550*38e8c45fSAndroid Build Coastguard Worker     }
1551*38e8c45fSAndroid Build Coastguard Worker 
1552*38e8c45fSAndroid Build Coastguard Worker     return updatedDataspace;
1553*38e8c45fSAndroid Build Coastguard Worker }
1554*38e8c45fSAndroid Build Coastguard Worker 
getBuffer() const1555*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer> Layer::getBuffer() const {
1556*38e8c45fSAndroid Build Coastguard Worker     return mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer() : nullptr;
1557*38e8c45fSAndroid Build Coastguard Worker }
1558*38e8c45fSAndroid Build Coastguard Worker 
setTrustedPresentationInfo(TrustedPresentationThresholds const & thresholds,TrustedPresentationListener const & listener)1559*38e8c45fSAndroid Build Coastguard Worker bool Layer::setTrustedPresentationInfo(TrustedPresentationThresholds const& thresholds,
1560*38e8c45fSAndroid Build Coastguard Worker                                        TrustedPresentationListener const& listener) {
1561*38e8c45fSAndroid Build Coastguard Worker     bool hadTrustedPresentationListener = hasTrustedPresentationListener();
1562*38e8c45fSAndroid Build Coastguard Worker     mTrustedPresentationListener = listener;
1563*38e8c45fSAndroid Build Coastguard Worker     mTrustedPresentationThresholds = thresholds;
1564*38e8c45fSAndroid Build Coastguard Worker     bool haveTrustedPresentationListener = hasTrustedPresentationListener();
1565*38e8c45fSAndroid Build Coastguard Worker     if (!hadTrustedPresentationListener && haveTrustedPresentationListener) {
1566*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mNumTrustedPresentationListeners++;
1567*38e8c45fSAndroid Build Coastguard Worker     } else if (hadTrustedPresentationListener && !haveTrustedPresentationListener) {
1568*38e8c45fSAndroid Build Coastguard Worker         mFlinger->mNumTrustedPresentationListeners--;
1569*38e8c45fSAndroid Build Coastguard Worker     }
1570*38e8c45fSAndroid Build Coastguard Worker 
1571*38e8c45fSAndroid Build Coastguard Worker     // Reset trusted presentation states to ensure we start the time again.
1572*38e8c45fSAndroid Build Coastguard Worker     mEnteredTrustedPresentationStateTime = -1;
1573*38e8c45fSAndroid Build Coastguard Worker     mLastReportedTrustedPresentationState = false;
1574*38e8c45fSAndroid Build Coastguard Worker     mLastComputedTrustedPresentationState = false;
1575*38e8c45fSAndroid Build Coastguard Worker 
1576*38e8c45fSAndroid Build Coastguard Worker     // If there's a new trusted presentation listener, the code needs to go through the composite
1577*38e8c45fSAndroid Build Coastguard Worker     // path to ensure it recomutes the current state and invokes the TrustedPresentationListener if
1578*38e8c45fSAndroid Build Coastguard Worker     // we're already in the requested state.
1579*38e8c45fSAndroid Build Coastguard Worker     return haveTrustedPresentationListener;
1580*38e8c45fSAndroid Build Coastguard Worker }
1581*38e8c45fSAndroid Build Coastguard Worker 
setBufferReleaseChannel(const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint> & channel)1582*38e8c45fSAndroid Build Coastguard Worker void Layer::setBufferReleaseChannel(
1583*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint>& channel) {
1584*38e8c45fSAndroid Build Coastguard Worker     mBufferReleaseChannel = channel;
1585*38e8c45fSAndroid Build Coastguard Worker }
1586*38e8c45fSAndroid Build Coastguard Worker 
updateLastLatchTime(nsecs_t latchTime)1587*38e8c45fSAndroid Build Coastguard Worker void Layer::updateLastLatchTime(nsecs_t latchTime) {
1588*38e8c45fSAndroid Build Coastguard Worker     mLastLatchTime = latchTime;
1589*38e8c45fSAndroid Build Coastguard Worker }
1590*38e8c45fSAndroid Build Coastguard Worker 
setIsSmallDirty(frontend::LayerSnapshot * snapshot)1591*38e8c45fSAndroid Build Coastguard Worker void Layer::setIsSmallDirty(frontend::LayerSnapshot* snapshot) {
1592*38e8c45fSAndroid Build Coastguard Worker     if (!mFlinger->mScheduler->supportSmallDirtyDetection(mOwnerAppId)) {
1593*38e8c45fSAndroid Build Coastguard Worker         snapshot->isSmallDirty = false;
1594*38e8c45fSAndroid Build Coastguard Worker         return;
1595*38e8c45fSAndroid Build Coastguard Worker     }
1596*38e8c45fSAndroid Build Coastguard Worker 
1597*38e8c45fSAndroid Build Coastguard Worker     if (mWindowType != WindowInfo::Type::APPLICATION &&
1598*38e8c45fSAndroid Build Coastguard Worker         mWindowType != WindowInfo::Type::BASE_APPLICATION) {
1599*38e8c45fSAndroid Build Coastguard Worker         snapshot->isSmallDirty = false;
1600*38e8c45fSAndroid Build Coastguard Worker         return;
1601*38e8c45fSAndroid Build Coastguard Worker     }
1602*38e8c45fSAndroid Build Coastguard Worker 
1603*38e8c45fSAndroid Build Coastguard Worker     Rect bounds = snapshot->surfaceDamage.getBounds();
1604*38e8c45fSAndroid Build Coastguard Worker     if (!bounds.isValid()) {
1605*38e8c45fSAndroid Build Coastguard Worker         snapshot->isSmallDirty = false;
1606*38e8c45fSAndroid Build Coastguard Worker         return;
1607*38e8c45fSAndroid Build Coastguard Worker     }
1608*38e8c45fSAndroid Build Coastguard Worker 
1609*38e8c45fSAndroid Build Coastguard Worker     // Transform to screen space.
1610*38e8c45fSAndroid Build Coastguard Worker     bounds = snapshot->localTransform.transform(bounds);
1611*38e8c45fSAndroid Build Coastguard Worker 
1612*38e8c45fSAndroid Build Coastguard Worker     // If the damage region is a small dirty, this could give the hint for the layer history that
1613*38e8c45fSAndroid Build Coastguard Worker     // it could suppress the heuristic rate when calculating.
1614*38e8c45fSAndroid Build Coastguard Worker     snapshot->isSmallDirty =
1615*38e8c45fSAndroid Build Coastguard Worker             mFlinger->mScheduler->isSmallDirtyArea(mOwnerAppId,
1616*38e8c45fSAndroid Build Coastguard Worker                                                    bounds.getWidth() * bounds.getHeight());
1617*38e8c45fSAndroid Build Coastguard Worker }
1618*38e8c45fSAndroid Build Coastguard Worker 
1619*38e8c45fSAndroid Build Coastguard Worker } // namespace android
1620*38e8c45fSAndroid Build Coastguard Worker 
1621*38e8c45fSAndroid Build Coastguard Worker #if defined(__gl_h_)
1622*38e8c45fSAndroid Build Coastguard Worker #error "don't include gl/gl.h in this file"
1623*38e8c45fSAndroid Build Coastguard Worker #endif
1624*38e8c45fSAndroid Build Coastguard Worker 
1625*38e8c45fSAndroid Build Coastguard Worker #if defined(__gl2_h_)
1626*38e8c45fSAndroid Build Coastguard Worker #error "don't include gl2/gl2.h in this file"
1627*38e8c45fSAndroid Build Coastguard Worker #endif
1628*38e8c45fSAndroid Build Coastguard Worker 
1629*38e8c45fSAndroid Build Coastguard Worker // TODO(b/129481165): remove the #pragma below and fix conversion issues
1630*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic pop // ignored "-Wconversion"
1631