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