xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2007 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker // TODO(b/129481165): remove the #pragma below and fix conversion issues
18*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic push
19*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wconversion"
20*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wextra"
21*38e8c45fSAndroid Build Coastguard Worker 
22*38e8c45fSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
23*38e8c45fSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_GRAPHICS
24*38e8c45fSAndroid Build Coastguard Worker 
25*38e8c45fSAndroid Build Coastguard Worker #include "SurfaceFlinger.h"
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker #include <aidl/android/hardware/power/Boost.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <android-base/parseint.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <android-base/properties.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <android-base/strings.h>
32*38e8c45fSAndroid Build Coastguard Worker #include <android/configuration.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <android/gui/IDisplayEventConnection.h>
34*38e8c45fSAndroid Build Coastguard Worker #include <android/gui/StaticDisplayInfo.h>
35*38e8c45fSAndroid Build Coastguard Worker #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
36*38e8c45fSAndroid Build Coastguard Worker #include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
37*38e8c45fSAndroid Build Coastguard Worker #include <android/hardware/configstore/1.1/types.h>
38*38e8c45fSAndroid Build Coastguard Worker #include <android/native_window.h>
39*38e8c45fSAndroid Build Coastguard Worker #include <android/os/IInputFlinger.h>
40*38e8c45fSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
41*38e8c45fSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
42*38e8c45fSAndroid Build Coastguard Worker #include <binder/PermissionCache.h>
43*38e8c45fSAndroid Build Coastguard Worker #include <com_android_graphics_libgui_flags.h>
44*38e8c45fSAndroid Build Coastguard Worker #include <com_android_graphics_surfaceflinger_flags.h>
45*38e8c45fSAndroid Build Coastguard Worker #include <common/FlagManager.h>
46*38e8c45fSAndroid Build Coastguard Worker #include <common/trace.h>
47*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/CompositionEngine.h>
48*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/CompositionRefreshArgs.h>
49*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/Display.h>
50*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/DisplayColorProfile.h>
51*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/DisplayColorProfileCreationArgs.h>
52*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/DisplayCreationArgs.h>
53*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/LayerFECompositionState.h>
54*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/OutputLayer.h>
55*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/RenderSurface.h>
56*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/impl/DisplayColorProfile.h>
57*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/impl/OutputCompositionState.h>
58*38e8c45fSAndroid Build Coastguard Worker #include <compositionengine/impl/OutputLayerCompositionState.h>
59*38e8c45fSAndroid Build Coastguard Worker #include <configstore/Utils.h>
60*38e8c45fSAndroid Build Coastguard Worker #include <cutils/compiler.h>
61*38e8c45fSAndroid Build Coastguard Worker #include <cutils/properties.h>
62*38e8c45fSAndroid Build Coastguard Worker #include <fmt/format.h>
63*38e8c45fSAndroid Build Coastguard Worker #include <ftl/algorithm.h>
64*38e8c45fSAndroid Build Coastguard Worker #include <ftl/concat.h>
65*38e8c45fSAndroid Build Coastguard Worker #include <ftl/fake_guard.h>
66*38e8c45fSAndroid Build Coastguard Worker #include <ftl/future.h>
67*38e8c45fSAndroid Build Coastguard Worker #include <ftl/small_map.h>
68*38e8c45fSAndroid Build Coastguard Worker #include <ftl/unit.h>
69*38e8c45fSAndroid Build Coastguard Worker #include <gui/AidlUtil.h>
70*38e8c45fSAndroid Build Coastguard Worker #include <gui/BufferQueue.h>
71*38e8c45fSAndroid Build Coastguard Worker #include <gui/DebugEGLImageTracker.h>
72*38e8c45fSAndroid Build Coastguard Worker #include <gui/IProducerListener.h>
73*38e8c45fSAndroid Build Coastguard Worker #include <gui/JankInfo.h>
74*38e8c45fSAndroid Build Coastguard Worker #include <gui/LayerMetadata.h>
75*38e8c45fSAndroid Build Coastguard Worker #include <gui/LayerState.h>
76*38e8c45fSAndroid Build Coastguard Worker #include <gui/Surface.h>
77*38e8c45fSAndroid Build Coastguard Worker #include <gui/SurfaceComposerClient.h>
78*38e8c45fSAndroid Build Coastguard Worker #include <hidl/ServiceManagement.h>
79*38e8c45fSAndroid Build Coastguard Worker #include <layerproto/LayerProtoHeader.h>
80*38e8c45fSAndroid Build Coastguard Worker #include <linux/sched/types.h>
81*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
82*38e8c45fSAndroid Build Coastguard Worker #include <private/android_filesystem_config.h>
83*38e8c45fSAndroid Build Coastguard Worker #include <private/gui/SyncFeatures.h>
84*38e8c45fSAndroid Build Coastguard Worker #include <processgroup/processgroup.h>
85*38e8c45fSAndroid Build Coastguard Worker #include <renderengine/RenderEngine.h>
86*38e8c45fSAndroid Build Coastguard Worker #include <renderengine/impl/ExternalTexture.h>
87*38e8c45fSAndroid Build Coastguard Worker #include <scheduler/FrameTargeter.h>
88*38e8c45fSAndroid Build Coastguard Worker #include <statslog_surfaceflinger.h>
89*38e8c45fSAndroid Build Coastguard Worker #include <sys/types.h>
90*38e8c45fSAndroid Build Coastguard Worker #include <ui/ColorSpace.h>
91*38e8c45fSAndroid Build Coastguard Worker #include <ui/DebugUtils.h>
92*38e8c45fSAndroid Build Coastguard Worker #include <ui/DisplayId.h>
93*38e8c45fSAndroid Build Coastguard Worker #include <ui/DisplayMode.h>
94*38e8c45fSAndroid Build Coastguard Worker #include <ui/DisplayStatInfo.h>
95*38e8c45fSAndroid Build Coastguard Worker #include <ui/DisplayState.h>
96*38e8c45fSAndroid Build Coastguard Worker #include <ui/DynamicDisplayInfo.h>
97*38e8c45fSAndroid Build Coastguard Worker #include <ui/FrameRateCategoryRate.h>
98*38e8c45fSAndroid Build Coastguard Worker #include <ui/GraphicBufferAllocator.h>
99*38e8c45fSAndroid Build Coastguard Worker #include <ui/HdrRenderTypeUtils.h>
100*38e8c45fSAndroid Build Coastguard Worker #include <ui/LayerStack.h>
101*38e8c45fSAndroid Build Coastguard Worker #include <ui/PixelFormat.h>
102*38e8c45fSAndroid Build Coastguard Worker #include <ui/StaticDisplayInfo.h>
103*38e8c45fSAndroid Build Coastguard Worker #include <unistd.h>
104*38e8c45fSAndroid Build Coastguard Worker #include <utils/StopWatch.h>
105*38e8c45fSAndroid Build Coastguard Worker #include <utils/String16.h>
106*38e8c45fSAndroid Build Coastguard Worker #include <utils/String8.h>
107*38e8c45fSAndroid Build Coastguard Worker #include <utils/Timers.h>
108*38e8c45fSAndroid Build Coastguard Worker #include <utils/misc.h>
109*38e8c45fSAndroid Build Coastguard Worker #include <algorithm>
110*38e8c45fSAndroid Build Coastguard Worker #include <cerrno>
111*38e8c45fSAndroid Build Coastguard Worker #include <cinttypes>
112*38e8c45fSAndroid Build Coastguard Worker #include <cmath>
113*38e8c45fSAndroid Build Coastguard Worker #include <cstdint>
114*38e8c45fSAndroid Build Coastguard Worker #include <filesystem>
115*38e8c45fSAndroid Build Coastguard Worker #include <functional>
116*38e8c45fSAndroid Build Coastguard Worker #include <memory>
117*38e8c45fSAndroid Build Coastguard Worker #include <mutex>
118*38e8c45fSAndroid Build Coastguard Worker #include <optional>
119*38e8c45fSAndroid Build Coastguard Worker #include <string>
120*38e8c45fSAndroid Build Coastguard Worker #include <type_traits>
121*38e8c45fSAndroid Build Coastguard Worker #include <unordered_map>
122*38e8c45fSAndroid Build Coastguard Worker #include <vector>
123*38e8c45fSAndroid Build Coastguard Worker 
124*38e8c45fSAndroid Build Coastguard Worker #include <common/FlagManager.h>
125*38e8c45fSAndroid Build Coastguard Worker #include <gui/LayerStatePermissions.h>
126*38e8c45fSAndroid Build Coastguard Worker #include <gui/SchedulingPolicy.h>
127*38e8c45fSAndroid Build Coastguard Worker #include <gui/SyncScreenCaptureListener.h>
128*38e8c45fSAndroid Build Coastguard Worker #include <ui/DisplayIdentification.h>
129*38e8c45fSAndroid Build Coastguard Worker #include "ActivePictureUpdater.h"
130*38e8c45fSAndroid Build Coastguard Worker #include "BackgroundExecutor.h"
131*38e8c45fSAndroid Build Coastguard Worker #include "Client.h"
132*38e8c45fSAndroid Build Coastguard Worker #include "ClientCache.h"
133*38e8c45fSAndroid Build Coastguard Worker #include "Colorizer.h"
134*38e8c45fSAndroid Build Coastguard Worker #include "DisplayDevice.h"
135*38e8c45fSAndroid Build Coastguard Worker #include "DisplayHardware/ComposerHal.h"
136*38e8c45fSAndroid Build Coastguard Worker #include "DisplayHardware/FramebufferSurface.h"
137*38e8c45fSAndroid Build Coastguard Worker #include "DisplayHardware/HWComposer.h"
138*38e8c45fSAndroid Build Coastguard Worker #include "DisplayHardware/Hal.h"
139*38e8c45fSAndroid Build Coastguard Worker #include "DisplayHardware/VirtualDisplaySurface.h"
140*38e8c45fSAndroid Build Coastguard Worker #include "DisplayRenderArea.h"
141*38e8c45fSAndroid Build Coastguard Worker #include "Effects/Daltonizer.h"
142*38e8c45fSAndroid Build Coastguard Worker #include "FpsReporter.h"
143*38e8c45fSAndroid Build Coastguard Worker #include "FrameTimeline/FrameTimeline.h"
144*38e8c45fSAndroid Build Coastguard Worker #include "FrameTracer/FrameTracer.h"
145*38e8c45fSAndroid Build Coastguard Worker #include "FrontEnd/LayerCreationArgs.h"
146*38e8c45fSAndroid Build Coastguard Worker #include "FrontEnd/LayerHandle.h"
147*38e8c45fSAndroid Build Coastguard Worker #include "FrontEnd/LayerLifecycleManager.h"
148*38e8c45fSAndroid Build Coastguard Worker #include "FrontEnd/LayerLog.h"
149*38e8c45fSAndroid Build Coastguard Worker #include "FrontEnd/LayerSnapshot.h"
150*38e8c45fSAndroid Build Coastguard Worker #include "HdrLayerInfoReporter.h"
151*38e8c45fSAndroid Build Coastguard Worker #include "Jank/JankTracker.h"
152*38e8c45fSAndroid Build Coastguard Worker #include "Layer.h"
153*38e8c45fSAndroid Build Coastguard Worker #include "LayerProtoHelper.h"
154*38e8c45fSAndroid Build Coastguard Worker #include "LayerRenderArea.h"
155*38e8c45fSAndroid Build Coastguard Worker #include "LayerVector.h"
156*38e8c45fSAndroid Build Coastguard Worker #include "MutexUtils.h"
157*38e8c45fSAndroid Build Coastguard Worker #include "NativeWindowSurface.h"
158*38e8c45fSAndroid Build Coastguard Worker #include "PowerAdvisor/PowerAdvisor.h"
159*38e8c45fSAndroid Build Coastguard Worker #include "RegionSamplingThread.h"
160*38e8c45fSAndroid Build Coastguard Worker #include "RenderAreaBuilder.h"
161*38e8c45fSAndroid Build Coastguard Worker #include "Scheduler/EventThread.h"
162*38e8c45fSAndroid Build Coastguard Worker #include "Scheduler/LayerHistory.h"
163*38e8c45fSAndroid Build Coastguard Worker #include "Scheduler/Scheduler.h"
164*38e8c45fSAndroid Build Coastguard Worker #include "Scheduler/VsyncConfiguration.h"
165*38e8c45fSAndroid Build Coastguard Worker #include "Scheduler/VsyncModulator.h"
166*38e8c45fSAndroid Build Coastguard Worker #include "ScreenCaptureOutput.h"
167*38e8c45fSAndroid Build Coastguard Worker #include "SurfaceFlingerProperties.h"
168*38e8c45fSAndroid Build Coastguard Worker #include "TimeStats/TimeStats.h"
169*38e8c45fSAndroid Build Coastguard Worker #include "TunnelModeEnabledReporter.h"
170*38e8c45fSAndroid Build Coastguard Worker #include "Utils/Dumper.h"
171*38e8c45fSAndroid Build Coastguard Worker #include "WindowInfosListenerInvoker.h"
172*38e8c45fSAndroid Build Coastguard Worker 
173*38e8c45fSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/common/DisplayDecorationSupport.h>
174*38e8c45fSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
175*38e8c45fSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/composer3/OutputType.h>
176*38e8c45fSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/composer3/RenderIntent.h>
177*38e8c45fSAndroid Build Coastguard Worker 
178*38e8c45fSAndroid Build Coastguard Worker #undef NO_THREAD_SAFETY_ANALYSIS
179*38e8c45fSAndroid Build Coastguard Worker #define NO_THREAD_SAFETY_ANALYSIS \
180*38e8c45fSAndroid Build Coastguard Worker     _Pragma("GCC error \"Prefer <ftl/fake_guard.h> or MutexUtils.h helpers.\"")
181*38e8c45fSAndroid Build Coastguard Worker 
182*38e8c45fSAndroid Build Coastguard Worker namespace android {
183*38e8c45fSAndroid Build Coastguard Worker using namespace std::chrono_literals;
184*38e8c45fSAndroid Build Coastguard Worker using namespace std::string_literals;
185*38e8c45fSAndroid Build Coastguard Worker using namespace std::string_view_literals;
186*38e8c45fSAndroid Build Coastguard Worker 
187*38e8c45fSAndroid Build Coastguard Worker using namespace hardware::configstore;
188*38e8c45fSAndroid Build Coastguard Worker using namespace hardware::configstore::V1_0;
189*38e8c45fSAndroid Build Coastguard Worker using namespace sysprop;
190*38e8c45fSAndroid Build Coastguard Worker using ftl::Flags;
191*38e8c45fSAndroid Build Coastguard Worker using namespace ftl::flag_operators;
192*38e8c45fSAndroid Build Coastguard Worker 
193*38e8c45fSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::common::DisplayDecorationSupport;
194*38e8c45fSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::composer3::Capability;
195*38e8c45fSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::composer3::DisplayCapability;
196*38e8c45fSAndroid Build Coastguard Worker using CompositionStrategyPredictionState = android::compositionengine::impl::
197*38e8c45fSAndroid Build Coastguard Worker         OutputCompositionState::CompositionStrategyPredictionState;
198*38e8c45fSAndroid Build Coastguard Worker 
199*38e8c45fSAndroid Build Coastguard Worker using base::StringAppendF;
200*38e8c45fSAndroid Build Coastguard Worker using display::PhysicalDisplay;
201*38e8c45fSAndroid Build Coastguard Worker using display::PhysicalDisplays;
202*38e8c45fSAndroid Build Coastguard Worker using frontend::TransactionHandler;
203*38e8c45fSAndroid Build Coastguard Worker using gui::DisplayInfo;
204*38e8c45fSAndroid Build Coastguard Worker using gui::GameMode;
205*38e8c45fSAndroid Build Coastguard Worker using gui::IDisplayEventConnection;
206*38e8c45fSAndroid Build Coastguard Worker using gui::IWindowInfosListener;
207*38e8c45fSAndroid Build Coastguard Worker using gui::LayerMetadata;
208*38e8c45fSAndroid Build Coastguard Worker using gui::WindowInfo;
209*38e8c45fSAndroid Build Coastguard Worker using gui::aidl_utils::binderStatusFromStatusT;
210*38e8c45fSAndroid Build Coastguard Worker using scheduler::VsyncModulator;
211*38e8c45fSAndroid Build Coastguard Worker using ui::Dataspace;
212*38e8c45fSAndroid Build Coastguard Worker using ui::DisplayPrimaries;
213*38e8c45fSAndroid Build Coastguard Worker using ui::RenderIntent;
214*38e8c45fSAndroid Build Coastguard Worker 
215*38e8c45fSAndroid Build Coastguard Worker namespace hal = android::hardware::graphics::composer::hal;
216*38e8c45fSAndroid Build Coastguard Worker 
217*38e8c45fSAndroid Build Coastguard Worker namespace {
218*38e8c45fSAndroid Build Coastguard Worker 
219*38e8c45fSAndroid Build Coastguard Worker static constexpr int FOUR_K_WIDTH = 3840;
220*38e8c45fSAndroid Build Coastguard Worker static constexpr int FOUR_K_HEIGHT = 2160;
221*38e8c45fSAndroid Build Coastguard Worker 
222*38e8c45fSAndroid Build Coastguard Worker // TODO(b/141333600): Consolidate with DisplayMode::Builder::getDefaultDensity.
223*38e8c45fSAndroid Build Coastguard Worker constexpr float FALLBACK_DENSITY = ACONFIGURATION_DENSITY_TV;
224*38e8c45fSAndroid Build Coastguard Worker 
getDensityFromProperty(const char * property,bool required)225*38e8c45fSAndroid Build Coastguard Worker float getDensityFromProperty(const char* property, bool required) {
226*38e8c45fSAndroid Build Coastguard Worker     char value[PROPERTY_VALUE_MAX];
227*38e8c45fSAndroid Build Coastguard Worker     const float density = property_get(property, value, nullptr) > 0 ? std::atof(value) : 0.f;
228*38e8c45fSAndroid Build Coastguard Worker     if (!density && required) {
229*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s must be defined as a build property", property);
230*38e8c45fSAndroid Build Coastguard Worker         return FALLBACK_DENSITY;
231*38e8c45fSAndroid Build Coastguard Worker     }
232*38e8c45fSAndroid Build Coastguard Worker     return density;
233*38e8c45fSAndroid Build Coastguard Worker }
234*38e8c45fSAndroid Build Coastguard Worker 
235*38e8c45fSAndroid Build Coastguard Worker // Currently we only support V0_SRGB and DISPLAY_P3 as composition preference.
validateCompositionDataspace(Dataspace dataspace)236*38e8c45fSAndroid Build Coastguard Worker bool validateCompositionDataspace(Dataspace dataspace) {
237*38e8c45fSAndroid Build Coastguard Worker     return dataspace == Dataspace::V0_SRGB || dataspace == Dataspace::DISPLAY_P3;
238*38e8c45fSAndroid Build Coastguard Worker }
239*38e8c45fSAndroid Build Coastguard Worker 
getIdleTimerTimeout(PhysicalDisplayId displayId)240*38e8c45fSAndroid Build Coastguard Worker std::chrono::milliseconds getIdleTimerTimeout(PhysicalDisplayId displayId) {
241*38e8c45fSAndroid Build Coastguard Worker     if (const int32_t displayIdleTimerMs =
242*38e8c45fSAndroid Build Coastguard Worker                 base::GetIntProperty("debug.sf.set_idle_timer_ms_"s +
243*38e8c45fSAndroid Build Coastguard Worker                                              std::to_string(displayId.value),
244*38e8c45fSAndroid Build Coastguard Worker                                      0);
245*38e8c45fSAndroid Build Coastguard Worker         displayIdleTimerMs > 0) {
246*38e8c45fSAndroid Build Coastguard Worker         return std::chrono::milliseconds(displayIdleTimerMs);
247*38e8c45fSAndroid Build Coastguard Worker     }
248*38e8c45fSAndroid Build Coastguard Worker 
249*38e8c45fSAndroid Build Coastguard Worker     const int32_t setIdleTimerMs = base::GetIntProperty("debug.sf.set_idle_timer_ms"s, 0);
250*38e8c45fSAndroid Build Coastguard Worker     const int32_t millis = setIdleTimerMs ? setIdleTimerMs : sysprop::set_idle_timer_ms(0);
251*38e8c45fSAndroid Build Coastguard Worker     return std::chrono::milliseconds(millis);
252*38e8c45fSAndroid Build Coastguard Worker }
253*38e8c45fSAndroid Build Coastguard Worker 
getKernelIdleTimerSyspropConfig(PhysicalDisplayId displayId)254*38e8c45fSAndroid Build Coastguard Worker bool getKernelIdleTimerSyspropConfig(PhysicalDisplayId displayId) {
255*38e8c45fSAndroid Build Coastguard Worker     const bool displaySupportKernelIdleTimer =
256*38e8c45fSAndroid Build Coastguard Worker             base::GetBoolProperty("debug.sf.support_kernel_idle_timer_"s +
257*38e8c45fSAndroid Build Coastguard Worker                                           std::to_string(displayId.value),
258*38e8c45fSAndroid Build Coastguard Worker                                   false);
259*38e8c45fSAndroid Build Coastguard Worker 
260*38e8c45fSAndroid Build Coastguard Worker     return displaySupportKernelIdleTimer || sysprop::support_kernel_idle_timer(false);
261*38e8c45fSAndroid Build Coastguard Worker }
262*38e8c45fSAndroid Build Coastguard Worker 
isAbove4k30(const ui::DisplayMode & outMode)263*38e8c45fSAndroid Build Coastguard Worker bool isAbove4k30(const ui::DisplayMode& outMode) {
264*38e8c45fSAndroid Build Coastguard Worker     using fps_approx_ops::operator>;
265*38e8c45fSAndroid Build Coastguard Worker     Fps refreshRate = Fps::fromValue(outMode.peakRefreshRate);
266*38e8c45fSAndroid Build Coastguard Worker     return outMode.resolution.getWidth() >= FOUR_K_WIDTH &&
267*38e8c45fSAndroid Build Coastguard Worker             outMode.resolution.getHeight() >= FOUR_K_HEIGHT && refreshRate > 30_Hz;
268*38e8c45fSAndroid Build Coastguard Worker }
269*38e8c45fSAndroid Build Coastguard Worker 
excludeDolbyVisionIf4k30Present(const std::vector<ui::Hdr> & displayHdrTypes,ui::DisplayMode & outMode)270*38e8c45fSAndroid Build Coastguard Worker void excludeDolbyVisionIf4k30Present(const std::vector<ui::Hdr>& displayHdrTypes,
271*38e8c45fSAndroid Build Coastguard Worker                                      ui::DisplayMode& outMode) {
272*38e8c45fSAndroid Build Coastguard Worker     if (isAbove4k30(outMode) &&
273*38e8c45fSAndroid Build Coastguard Worker         std::any_of(displayHdrTypes.begin(), displayHdrTypes.end(),
274*38e8c45fSAndroid Build Coastguard Worker                     [](ui::Hdr type) { return type == ui::Hdr::DOLBY_VISION_4K30; })) {
275*38e8c45fSAndroid Build Coastguard Worker         for (ui::Hdr type : displayHdrTypes) {
276*38e8c45fSAndroid Build Coastguard Worker             if (type != ui::Hdr::DOLBY_VISION_4K30 && type != ui::Hdr::DOLBY_VISION) {
277*38e8c45fSAndroid Build Coastguard Worker                 outMode.supportedHdrTypes.push_back(type);
278*38e8c45fSAndroid Build Coastguard Worker             }
279*38e8c45fSAndroid Build Coastguard Worker         }
280*38e8c45fSAndroid Build Coastguard Worker     } else {
281*38e8c45fSAndroid Build Coastguard Worker         for (ui::Hdr type : displayHdrTypes) {
282*38e8c45fSAndroid Build Coastguard Worker             if (type != ui::Hdr::DOLBY_VISION_4K30) {
283*38e8c45fSAndroid Build Coastguard Worker                 outMode.supportedHdrTypes.push_back(type);
284*38e8c45fSAndroid Build Coastguard Worker             }
285*38e8c45fSAndroid Build Coastguard Worker         }
286*38e8c45fSAndroid Build Coastguard Worker     }
287*38e8c45fSAndroid Build Coastguard Worker }
288*38e8c45fSAndroid Build Coastguard Worker 
filterOut4k30(const HdrCapabilities & displayHdrCapabilities)289*38e8c45fSAndroid Build Coastguard Worker HdrCapabilities filterOut4k30(const HdrCapabilities& displayHdrCapabilities) {
290*38e8c45fSAndroid Build Coastguard Worker     std::vector<ui::Hdr> hdrTypes;
291*38e8c45fSAndroid Build Coastguard Worker     for (ui::Hdr type : displayHdrCapabilities.getSupportedHdrTypes()) {
292*38e8c45fSAndroid Build Coastguard Worker         if (type != ui::Hdr::DOLBY_VISION_4K30) {
293*38e8c45fSAndroid Build Coastguard Worker             hdrTypes.push_back(type);
294*38e8c45fSAndroid Build Coastguard Worker         }
295*38e8c45fSAndroid Build Coastguard Worker     }
296*38e8c45fSAndroid Build Coastguard Worker     return {hdrTypes, displayHdrCapabilities.getDesiredMaxLuminance(),
297*38e8c45fSAndroid Build Coastguard Worker             displayHdrCapabilities.getDesiredMaxAverageLuminance(),
298*38e8c45fSAndroid Build Coastguard Worker             displayHdrCapabilities.getDesiredMinLuminance()};
299*38e8c45fSAndroid Build Coastguard Worker }
300*38e8c45fSAndroid Build Coastguard Worker 
getLayerIdFromSurfaceControl(sp<SurfaceControl> surfaceControl)301*38e8c45fSAndroid Build Coastguard Worker uint32_t getLayerIdFromSurfaceControl(sp<SurfaceControl> surfaceControl) {
302*38e8c45fSAndroid Build Coastguard Worker     if (!surfaceControl) {
303*38e8c45fSAndroid Build Coastguard Worker         return UNASSIGNED_LAYER_ID;
304*38e8c45fSAndroid Build Coastguard Worker     }
305*38e8c45fSAndroid Build Coastguard Worker     return LayerHandle::getLayerId(surfaceControl->getHandle());
306*38e8c45fSAndroid Build Coastguard Worker }
307*38e8c45fSAndroid Build Coastguard Worker 
308*38e8c45fSAndroid Build Coastguard Worker /**
309*38e8c45fSAndroid Build Coastguard Worker  * Returns true if the file at path exists and is newer than duration.
310*38e8c45fSAndroid Build Coastguard Worker  */
fileNewerThan(const std::string & path,std::chrono::minutes duration)311*38e8c45fSAndroid Build Coastguard Worker bool fileNewerThan(const std::string& path, std::chrono::minutes duration) {
312*38e8c45fSAndroid Build Coastguard Worker     using Clock = std::filesystem::file_time_type::clock;
313*38e8c45fSAndroid Build Coastguard Worker     std::error_code error;
314*38e8c45fSAndroid Build Coastguard Worker     std::filesystem::file_time_type updateTime = std::filesystem::last_write_time(path, error);
315*38e8c45fSAndroid Build Coastguard Worker     if (error) {
316*38e8c45fSAndroid Build Coastguard Worker         return false;
317*38e8c45fSAndroid Build Coastguard Worker     }
318*38e8c45fSAndroid Build Coastguard Worker     return duration > (Clock::now() - updateTime);
319*38e8c45fSAndroid Build Coastguard Worker }
320*38e8c45fSAndroid Build Coastguard Worker 
isFrameIntervalOnCadence(TimePoint expectedPresentTime,TimePoint lastExpectedPresentTimestamp,Fps lastFrameInterval,Period timeout,Duration threshold)321*38e8c45fSAndroid Build Coastguard Worker bool isFrameIntervalOnCadence(TimePoint expectedPresentTime, TimePoint lastExpectedPresentTimestamp,
322*38e8c45fSAndroid Build Coastguard Worker                               Fps lastFrameInterval, Period timeout, Duration threshold) {
323*38e8c45fSAndroid Build Coastguard Worker     if (lastFrameInterval.getPeriodNsecs() == 0) {
324*38e8c45fSAndroid Build Coastguard Worker         return false;
325*38e8c45fSAndroid Build Coastguard Worker     }
326*38e8c45fSAndroid Build Coastguard Worker 
327*38e8c45fSAndroid Build Coastguard Worker     const auto expectedPresentTimeDeltaNs =
328*38e8c45fSAndroid Build Coastguard Worker             expectedPresentTime.ns() - lastExpectedPresentTimestamp.ns();
329*38e8c45fSAndroid Build Coastguard Worker 
330*38e8c45fSAndroid Build Coastguard Worker     if (expectedPresentTimeDeltaNs > timeout.ns()) {
331*38e8c45fSAndroid Build Coastguard Worker         return false;
332*38e8c45fSAndroid Build Coastguard Worker     }
333*38e8c45fSAndroid Build Coastguard Worker 
334*38e8c45fSAndroid Build Coastguard Worker     const auto expectedPresentPeriods = static_cast<nsecs_t>(
335*38e8c45fSAndroid Build Coastguard Worker             std::round(static_cast<float>(expectedPresentTimeDeltaNs) /
336*38e8c45fSAndroid Build Coastguard Worker                        static_cast<float>(lastFrameInterval.getPeriodNsecs())));
337*38e8c45fSAndroid Build Coastguard Worker     const auto calculatedPeriodsOutNs = lastFrameInterval.getPeriodNsecs() * expectedPresentPeriods;
338*38e8c45fSAndroid Build Coastguard Worker     const auto calculatedExpectedPresentTimeNs =
339*38e8c45fSAndroid Build Coastguard Worker             lastExpectedPresentTimestamp.ns() + calculatedPeriodsOutNs;
340*38e8c45fSAndroid Build Coastguard Worker     const auto presentTimeDelta =
341*38e8c45fSAndroid Build Coastguard Worker             std::abs(expectedPresentTime.ns() - calculatedExpectedPresentTimeNs);
342*38e8c45fSAndroid Build Coastguard Worker     return presentTimeDelta < threshold.ns();
343*38e8c45fSAndroid Build Coastguard Worker }
344*38e8c45fSAndroid Build Coastguard Worker 
isExpectedPresentWithinTimeout(TimePoint expectedPresentTime,TimePoint lastExpectedPresentTimestamp,std::optional<Period> timeoutOpt,Duration threshold)345*38e8c45fSAndroid Build Coastguard Worker bool isExpectedPresentWithinTimeout(TimePoint expectedPresentTime,
346*38e8c45fSAndroid Build Coastguard Worker                                     TimePoint lastExpectedPresentTimestamp,
347*38e8c45fSAndroid Build Coastguard Worker                                     std::optional<Period> timeoutOpt, Duration threshold) {
348*38e8c45fSAndroid Build Coastguard Worker     if (!timeoutOpt) {
349*38e8c45fSAndroid Build Coastguard Worker         // Always within timeout if timeoutOpt is absent and don't send hint
350*38e8c45fSAndroid Build Coastguard Worker         // for the timeout
351*38e8c45fSAndroid Build Coastguard Worker         return true;
352*38e8c45fSAndroid Build Coastguard Worker     }
353*38e8c45fSAndroid Build Coastguard Worker 
354*38e8c45fSAndroid Build Coastguard Worker     if (timeoutOpt->ns() == 0) {
355*38e8c45fSAndroid Build Coastguard Worker         // Always outside timeout if timeoutOpt is 0 and always send
356*38e8c45fSAndroid Build Coastguard Worker         // the hint for the timeout.
357*38e8c45fSAndroid Build Coastguard Worker         return false;
358*38e8c45fSAndroid Build Coastguard Worker     }
359*38e8c45fSAndroid Build Coastguard Worker 
360*38e8c45fSAndroid Build Coastguard Worker     if (expectedPresentTime.ns() < lastExpectedPresentTimestamp.ns() + timeoutOpt->ns()) {
361*38e8c45fSAndroid Build Coastguard Worker         return true;
362*38e8c45fSAndroid Build Coastguard Worker     }
363*38e8c45fSAndroid Build Coastguard Worker 
364*38e8c45fSAndroid Build Coastguard Worker     // Check if within the threshold as it can be just outside the timeout
365*38e8c45fSAndroid Build Coastguard Worker     return std::abs(expectedPresentTime.ns() -
366*38e8c45fSAndroid Build Coastguard Worker                     (lastExpectedPresentTimestamp.ns() + timeoutOpt->ns())) < threshold.ns();
367*38e8c45fSAndroid Build Coastguard Worker }
368*38e8c45fSAndroid Build Coastguard Worker }  // namespace anonymous
369*38e8c45fSAndroid Build Coastguard Worker 
370*38e8c45fSAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
371*38e8c45fSAndroid Build Coastguard Worker 
372*38e8c45fSAndroid Build Coastguard Worker const String16 sHardwareTest("android.permission.HARDWARE_TEST");
373*38e8c45fSAndroid Build Coastguard Worker const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
374*38e8c45fSAndroid Build Coastguard Worker const String16 sRotateSurfaceFlinger("android.permission.ROTATE_SURFACE_FLINGER");
375*38e8c45fSAndroid Build Coastguard Worker const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
376*38e8c45fSAndroid Build Coastguard Worker const String16 sControlDisplayBrightness("android.permission.CONTROL_DISPLAY_BRIGHTNESS");
377*38e8c45fSAndroid Build Coastguard Worker const String16 sObservePictureProfiles("android.permission.OBSERVE_PICTURE_PROFILES");
378*38e8c45fSAndroid Build Coastguard Worker const String16 sDump("android.permission.DUMP");
379*38e8c45fSAndroid Build Coastguard Worker const String16 sCaptureBlackoutContent("android.permission.CAPTURE_BLACKOUT_CONTENT");
380*38e8c45fSAndroid Build Coastguard Worker const String16 sInternalSystemWindow("android.permission.INTERNAL_SYSTEM_WINDOW");
381*38e8c45fSAndroid Build Coastguard Worker const String16 sWakeupSurfaceFlinger("android.permission.WAKEUP_SURFACE_FLINGER");
382*38e8c45fSAndroid Build Coastguard Worker 
383*38e8c45fSAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
384*38e8c45fSAndroid Build Coastguard Worker int64_t SurfaceFlinger::dispSyncPresentTimeOffset;
385*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::useHwcForRgbToYuv;
386*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::hasSyncFramework;
387*38e8c45fSAndroid Build Coastguard Worker int64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers;
388*38e8c45fSAndroid Build Coastguard Worker int64_t SurfaceFlinger::minAcquiredBuffers = 1;
389*38e8c45fSAndroid Build Coastguard Worker uint32_t SurfaceFlinger::maxGraphicsWidth;
390*38e8c45fSAndroid Build Coastguard Worker uint32_t SurfaceFlinger::maxGraphicsHeight;
391*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::useContextPriority;
392*38e8c45fSAndroid Build Coastguard Worker Dataspace SurfaceFlinger::defaultCompositionDataspace = Dataspace::V0_SRGB;
393*38e8c45fSAndroid Build Coastguard Worker ui::PixelFormat SurfaceFlinger::defaultCompositionPixelFormat = ui::PixelFormat::RGBA_8888;
394*38e8c45fSAndroid Build Coastguard Worker Dataspace SurfaceFlinger::wideColorGamutCompositionDataspace = Dataspace::V0_SRGB;
395*38e8c45fSAndroid Build Coastguard Worker ui::PixelFormat SurfaceFlinger::wideColorGamutCompositionPixelFormat = ui::PixelFormat::RGBA_8888;
396*38e8c45fSAndroid Build Coastguard Worker LatchUnsignaledConfig SurfaceFlinger::enableLatchUnsignaledConfig;
397*38e8c45fSAndroid Build Coastguard Worker 
decodeDisplayColorSetting(DisplayColorSetting displayColorSetting)398*38e8c45fSAndroid Build Coastguard Worker std::string decodeDisplayColorSetting(DisplayColorSetting displayColorSetting) {
399*38e8c45fSAndroid Build Coastguard Worker     switch(displayColorSetting) {
400*38e8c45fSAndroid Build Coastguard Worker         case DisplayColorSetting::kManaged:
401*38e8c45fSAndroid Build Coastguard Worker             return std::string("Managed");
402*38e8c45fSAndroid Build Coastguard Worker         case DisplayColorSetting::kUnmanaged:
403*38e8c45fSAndroid Build Coastguard Worker             return std::string("Unmanaged");
404*38e8c45fSAndroid Build Coastguard Worker         case DisplayColorSetting::kEnhanced:
405*38e8c45fSAndroid Build Coastguard Worker             return std::string("Enhanced");
406*38e8c45fSAndroid Build Coastguard Worker         default:
407*38e8c45fSAndroid Build Coastguard Worker             return std::string("Unknown ") +
408*38e8c45fSAndroid Build Coastguard Worker                 std::to_string(static_cast<int>(displayColorSetting));
409*38e8c45fSAndroid Build Coastguard Worker     }
410*38e8c45fSAndroid Build Coastguard Worker }
411*38e8c45fSAndroid Build Coastguard Worker 
callingThreadHasPermission(const String16 & permission)412*38e8c45fSAndroid Build Coastguard Worker bool callingThreadHasPermission(const String16& permission) {
413*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
414*38e8c45fSAndroid Build Coastguard Worker     const int pid = ipc->getCallingPid();
415*38e8c45fSAndroid Build Coastguard Worker     const int uid = ipc->getCallingUid();
416*38e8c45fSAndroid Build Coastguard Worker     return uid == AID_GRAPHICS || uid == AID_SYSTEM ||
417*38e8c45fSAndroid Build Coastguard Worker             PermissionCache::checkPermission(permission, pid, uid);
418*38e8c45fSAndroid Build Coastguard Worker }
419*38e8c45fSAndroid Build Coastguard Worker 
420*38e8c45fSAndroid Build Coastguard Worker ui::Transform::RotationFlags SurfaceFlinger::sActiveDisplayRotationFlags = ui::Transform::ROT_0;
421*38e8c45fSAndroid Build Coastguard Worker 
SurfaceFlinger(Factory & factory,SkipInitializationTag)422*38e8c45fSAndroid Build Coastguard Worker SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
423*38e8c45fSAndroid Build Coastguard Worker       : mFactory(factory),
424*38e8c45fSAndroid Build Coastguard Worker         mPid(getpid()),
425*38e8c45fSAndroid Build Coastguard Worker         mTimeStats(std::make_shared<impl::TimeStats>()),
426*38e8c45fSAndroid Build Coastguard Worker         mFrameTracer(mFactory.createFrameTracer()),
427*38e8c45fSAndroid Build Coastguard Worker         mFrameTimeline(mFactory.createFrameTimeline(mTimeStats, mPid)),
428*38e8c45fSAndroid Build Coastguard Worker         mCompositionEngine(mFactory.createCompositionEngine()),
429*38e8c45fSAndroid Build Coastguard Worker         mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)),
430*38e8c45fSAndroid Build Coastguard Worker         mTunnelModeEnabledReporter(sp<TunnelModeEnabledReporter>::make()),
431*38e8c45fSAndroid Build Coastguard Worker         mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)),
432*38e8c45fSAndroid Build Coastguard Worker         mInternalDisplayDensity(
433*38e8c45fSAndroid Build Coastguard Worker                 getDensityFromProperty("ro.sf.lcd_density", !mEmulatedDisplayDensity)),
434*38e8c45fSAndroid Build Coastguard Worker         mPowerAdvisor(std::make_unique<
435*38e8c45fSAndroid Build Coastguard Worker                       adpf::impl::PowerAdvisor>([this] { disableExpensiveRendering(); },
436*38e8c45fSAndroid Build Coastguard Worker                                                 std::chrono::milliseconds(
437*38e8c45fSAndroid Build Coastguard Worker                                                         sysprop::display_update_imminent_timeout_ms(
438*38e8c45fSAndroid Build Coastguard Worker                                                                 80)))),
439*38e8c45fSAndroid Build Coastguard Worker         mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make()),
440*38e8c45fSAndroid Build Coastguard Worker         mSkipPowerOnForQuiescent(base::GetBoolProperty("ro.boot.quiescent"s, false)) {
441*38e8c45fSAndroid Build Coastguard Worker     ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str());
442*38e8c45fSAndroid Build Coastguard Worker }
443*38e8c45fSAndroid Build Coastguard Worker 
SurfaceFlinger(Factory & factory)444*38e8c45fSAndroid Build Coastguard Worker SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {
445*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
446*38e8c45fSAndroid Build Coastguard Worker     ALOGI("SurfaceFlinger is starting");
447*38e8c45fSAndroid Build Coastguard Worker 
448*38e8c45fSAndroid Build Coastguard Worker     hasSyncFramework = running_without_sync_framework(true);
449*38e8c45fSAndroid Build Coastguard Worker 
450*38e8c45fSAndroid Build Coastguard Worker     dispSyncPresentTimeOffset = present_time_offset_from_vsync_ns(0);
451*38e8c45fSAndroid Build Coastguard Worker 
452*38e8c45fSAndroid Build Coastguard Worker     useHwcForRgbToYuv = force_hwc_copy_for_virtual_displays(false);
453*38e8c45fSAndroid Build Coastguard Worker 
454*38e8c45fSAndroid Build Coastguard Worker     maxFrameBufferAcquiredBuffers = max_frame_buffer_acquired_buffers(2);
455*38e8c45fSAndroid Build Coastguard Worker     minAcquiredBuffers =
456*38e8c45fSAndroid Build Coastguard Worker             SurfaceFlingerProperties::min_acquired_buffers().value_or(minAcquiredBuffers);
457*38e8c45fSAndroid Build Coastguard Worker 
458*38e8c45fSAndroid Build Coastguard Worker     maxGraphicsWidth = std::max(max_graphics_width(0), 0);
459*38e8c45fSAndroid Build Coastguard Worker     maxGraphicsHeight = std::max(max_graphics_height(0), 0);
460*38e8c45fSAndroid Build Coastguard Worker 
461*38e8c45fSAndroid Build Coastguard Worker     mSupportsWideColor = has_wide_color_display(false);
462*38e8c45fSAndroid Build Coastguard Worker     mDefaultCompositionDataspace =
463*38e8c45fSAndroid Build Coastguard Worker             static_cast<ui::Dataspace>(default_composition_dataspace(Dataspace::V0_SRGB));
464*38e8c45fSAndroid Build Coastguard Worker     mWideColorGamutCompositionDataspace = static_cast<ui::Dataspace>(wcg_composition_dataspace(
465*38e8c45fSAndroid Build Coastguard Worker             mSupportsWideColor ? Dataspace::DISPLAY_P3 : Dataspace::V0_SRGB));
466*38e8c45fSAndroid Build Coastguard Worker     defaultCompositionDataspace = mDefaultCompositionDataspace;
467*38e8c45fSAndroid Build Coastguard Worker     wideColorGamutCompositionDataspace = mWideColorGamutCompositionDataspace;
468*38e8c45fSAndroid Build Coastguard Worker     defaultCompositionPixelFormat = static_cast<ui::PixelFormat>(
469*38e8c45fSAndroid Build Coastguard Worker             default_composition_pixel_format(ui::PixelFormat::RGBA_8888));
470*38e8c45fSAndroid Build Coastguard Worker     wideColorGamutCompositionPixelFormat =
471*38e8c45fSAndroid Build Coastguard Worker             static_cast<ui::PixelFormat>(wcg_composition_pixel_format(ui::PixelFormat::RGBA_8888));
472*38e8c45fSAndroid Build Coastguard Worker 
473*38e8c45fSAndroid Build Coastguard Worker     mLayerCachingEnabled =
474*38e8c45fSAndroid Build Coastguard Worker             base::GetBoolProperty("debug.sf.enable_layer_caching"s,
475*38e8c45fSAndroid Build Coastguard Worker                                   sysprop::SurfaceFlingerProperties::enable_layer_caching()
476*38e8c45fSAndroid Build Coastguard Worker                                           .value_or(false));
477*38e8c45fSAndroid Build Coastguard Worker 
478*38e8c45fSAndroid Build Coastguard Worker     useContextPriority = use_context_priority(true);
479*38e8c45fSAndroid Build Coastguard Worker 
480*38e8c45fSAndroid Build Coastguard Worker     mInternalDisplayPrimaries = sysprop::getDisplayNativePrimaries();
481*38e8c45fSAndroid Build Coastguard Worker 
482*38e8c45fSAndroid Build Coastguard Worker     // debugging stuff...
483*38e8c45fSAndroid Build Coastguard Worker     char value[PROPERTY_VALUE_MAX];
484*38e8c45fSAndroid Build Coastguard Worker 
485*38e8c45fSAndroid Build Coastguard Worker     property_get("ro.build.type", value, "user");
486*38e8c45fSAndroid Build Coastguard Worker     mIsUserBuild = strcmp(value, "user") == 0;
487*38e8c45fSAndroid Build Coastguard Worker 
488*38e8c45fSAndroid Build Coastguard Worker     mDebugFlashDelay = base::GetUintProperty("debug.sf.showupdates"s, 0u);
489*38e8c45fSAndroid Build Coastguard Worker 
490*38e8c45fSAndroid Build Coastguard Worker     mBackpressureGpuComposition = base::GetBoolProperty("debug.sf.enable_gl_backpressure"s, true);
491*38e8c45fSAndroid Build Coastguard Worker     ALOGI_IF(mBackpressureGpuComposition, "Enabling backpressure for GPU composition");
492*38e8c45fSAndroid Build Coastguard Worker 
493*38e8c45fSAndroid Build Coastguard Worker     property_get("ro.surface_flinger.supports_background_blur", value, "0");
494*38e8c45fSAndroid Build Coastguard Worker     bool supportsBlurs = atoi(value);
495*38e8c45fSAndroid Build Coastguard Worker     mSupportsBlur = supportsBlurs;
496*38e8c45fSAndroid Build Coastguard Worker     ALOGI_IF(!mSupportsBlur, "Disabling blur effects, they are not supported.");
497*38e8c45fSAndroid Build Coastguard Worker 
498*38e8c45fSAndroid Build Coastguard Worker     property_get("debug.sf.luma_sampling", value, "1");
499*38e8c45fSAndroid Build Coastguard Worker     mLumaSampling = atoi(value);
500*38e8c45fSAndroid Build Coastguard Worker 
501*38e8c45fSAndroid Build Coastguard Worker     property_get("debug.sf.disable_client_composition_cache", value, "0");
502*38e8c45fSAndroid Build Coastguard Worker     mDisableClientCompositionCache = atoi(value);
503*38e8c45fSAndroid Build Coastguard Worker 
504*38e8c45fSAndroid Build Coastguard Worker     property_get("debug.sf.predict_hwc_composition_strategy", value, "1");
505*38e8c45fSAndroid Build Coastguard Worker     mPredictCompositionStrategy = atoi(value);
506*38e8c45fSAndroid Build Coastguard Worker 
507*38e8c45fSAndroid Build Coastguard Worker     property_get("debug.sf.treat_170m_as_sRGB", value, "0");
508*38e8c45fSAndroid Build Coastguard Worker     mTreat170mAsSrgb = atoi(value);
509*38e8c45fSAndroid Build Coastguard Worker 
510*38e8c45fSAndroid Build Coastguard Worker     property_get("debug.sf.dim_in_gamma_in_enhanced_screenshots", value, 0);
511*38e8c45fSAndroid Build Coastguard Worker     mDimInGammaSpaceForEnhancedScreenshots = atoi(value);
512*38e8c45fSAndroid Build Coastguard Worker 
513*38e8c45fSAndroid Build Coastguard Worker     mIgnoreHwcPhysicalDisplayOrientation =
514*38e8c45fSAndroid Build Coastguard Worker             base::GetBoolProperty("debug.sf.ignore_hwc_physical_display_orientation"s, false);
515*38e8c45fSAndroid Build Coastguard Worker 
516*38e8c45fSAndroid Build Coastguard Worker     // We should be reading 'persist.sys.sf.color_saturation' here
517*38e8c45fSAndroid Build Coastguard Worker     // but since /data may be encrypted, we need to wait until after vold
518*38e8c45fSAndroid Build Coastguard Worker     // comes online to attempt to read the property. The property is
519*38e8c45fSAndroid Build Coastguard Worker     // instead read after the boot animation
520*38e8c45fSAndroid Build Coastguard Worker 
521*38e8c45fSAndroid Build Coastguard Worker     if (base::GetBoolProperty("debug.sf.treble_testing_override"s, false)) {
522*38e8c45fSAndroid Build Coastguard Worker         // Without the override SurfaceFlinger cannot connect to HIDL
523*38e8c45fSAndroid Build Coastguard Worker         // services that are not listed in the manifests.  Considered
524*38e8c45fSAndroid Build Coastguard Worker         // deriving the setting from the set service name, but it
525*38e8c45fSAndroid Build Coastguard Worker         // would be brittle if the name that's not 'default' is used
526*38e8c45fSAndroid Build Coastguard Worker         // for production purposes later on.
527*38e8c45fSAndroid Build Coastguard Worker         ALOGI("Enabling Treble testing override");
528*38e8c45fSAndroid Build Coastguard Worker         android::hardware::details::setTrebleTestingOverride(true);
529*38e8c45fSAndroid Build Coastguard Worker     }
530*38e8c45fSAndroid Build Coastguard Worker 
531*38e8c45fSAndroid Build Coastguard Worker     // TODO (b/270966065) Update the HWC based refresh rate overlay to support spinner
532*38e8c45fSAndroid Build Coastguard Worker     mRefreshRateOverlaySpinner = property_get_bool("debug.sf.show_refresh_rate_overlay_spinner", 0);
533*38e8c45fSAndroid Build Coastguard Worker     mRefreshRateOverlayRenderRate =
534*38e8c45fSAndroid Build Coastguard Worker             property_get_bool("debug.sf.show_refresh_rate_overlay_render_rate", 0);
535*38e8c45fSAndroid Build Coastguard Worker     mRefreshRateOverlayShowInMiddle =
536*38e8c45fSAndroid Build Coastguard Worker             property_get_bool("debug.sf.show_refresh_rate_overlay_in_middle", 0);
537*38e8c45fSAndroid Build Coastguard Worker 
538*38e8c45fSAndroid Build Coastguard Worker     if (!mIsUserBuild && base::GetBoolProperty("debug.sf.enable_transaction_tracing"s, true)) {
539*38e8c45fSAndroid Build Coastguard Worker         mTransactionTracing.emplace();
540*38e8c45fSAndroid Build Coastguard Worker         mLayerTracing.setTransactionTracing(*mTransactionTracing);
541*38e8c45fSAndroid Build Coastguard Worker     }
542*38e8c45fSAndroid Build Coastguard Worker 
543*38e8c45fSAndroid Build Coastguard Worker     mIgnoreHdrCameraLayers = ignore_hdr_camera_layers(false);
544*38e8c45fSAndroid Build Coastguard Worker 
545*38e8c45fSAndroid Build Coastguard Worker     // These are set by the HWC implementation to indicate that they will use the workarounds.
546*38e8c45fSAndroid Build Coastguard Worker     mIsHdcpViaNegVsync = base::GetBoolProperty("debug.sf.hwc_hdcp_via_neg_vsync"s, false);
547*38e8c45fSAndroid Build Coastguard Worker }
548*38e8c45fSAndroid Build Coastguard Worker 
getLatchUnsignaledConfig()549*38e8c45fSAndroid Build Coastguard Worker LatchUnsignaledConfig SurfaceFlinger::getLatchUnsignaledConfig() {
550*38e8c45fSAndroid Build Coastguard Worker     if (base::GetBoolProperty("debug.sf.auto_latch_unsignaled"s, true)) {
551*38e8c45fSAndroid Build Coastguard Worker         return LatchUnsignaledConfig::AutoSingleLayer;
552*38e8c45fSAndroid Build Coastguard Worker     }
553*38e8c45fSAndroid Build Coastguard Worker 
554*38e8c45fSAndroid Build Coastguard Worker     return LatchUnsignaledConfig::Disabled;
555*38e8c45fSAndroid Build Coastguard Worker }
556*38e8c45fSAndroid Build Coastguard Worker 
557*38e8c45fSAndroid Build Coastguard Worker SurfaceFlinger::~SurfaceFlinger() = default;
558*38e8c45fSAndroid Build Coastguard Worker 
binderDied(const wp<IBinder> &)559*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::binderDied(const wp<IBinder>&) {
560*38e8c45fSAndroid Build Coastguard Worker     // the window manager died on us. prepare its eulogy.
561*38e8c45fSAndroid Build Coastguard Worker     mBootFinished = false;
562*38e8c45fSAndroid Build Coastguard Worker 
563*38e8c45fSAndroid Build Coastguard Worker     static_cast<void>(mScheduler->schedule([this]() FTL_FAKE_GUARD(kMainThreadContext) {
564*38e8c45fSAndroid Build Coastguard Worker         // Sever the link to inputflinger since it's gone as well.
565*38e8c45fSAndroid Build Coastguard Worker         mInputFlinger.clear();
566*38e8c45fSAndroid Build Coastguard Worker 
567*38e8c45fSAndroid Build Coastguard Worker         initializeDisplays();
568*38e8c45fSAndroid Build Coastguard Worker     }));
569*38e8c45fSAndroid Build Coastguard Worker 
570*38e8c45fSAndroid Build Coastguard Worker     mInitBootPropsFuture.callOnce([this] {
571*38e8c45fSAndroid Build Coastguard Worker         return std::async(std::launch::async, &SurfaceFlinger::initBootProperties, this);
572*38e8c45fSAndroid Build Coastguard Worker     });
573*38e8c45fSAndroid Build Coastguard Worker 
574*38e8c45fSAndroid Build Coastguard Worker     mInitBootPropsFuture.wait();
575*38e8c45fSAndroid Build Coastguard Worker }
576*38e8c45fSAndroid Build Coastguard Worker 
run()577*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::run() {
578*38e8c45fSAndroid Build Coastguard Worker     mScheduler->run();
579*38e8c45fSAndroid Build Coastguard Worker }
580*38e8c45fSAndroid Build Coastguard Worker 
createVirtualDisplay(const std::string & displayName,bool isSecure,const std::string & uniqueId,float requestedRefreshRate)581*38e8c45fSAndroid Build Coastguard Worker sp<IBinder> SurfaceFlinger::createVirtualDisplay(const std::string& displayName, bool isSecure,
582*38e8c45fSAndroid Build Coastguard Worker                                                  const std::string& uniqueId,
583*38e8c45fSAndroid Build Coastguard Worker                                                  float requestedRefreshRate) {
584*38e8c45fSAndroid Build Coastguard Worker     // SurfaceComposerAIDL checks for some permissions, but adding an additional check here.
585*38e8c45fSAndroid Build Coastguard Worker     // This is to ensure that only root, system, and graphics can request to create a secure
586*38e8c45fSAndroid Build Coastguard Worker     // display. Secure displays can show secure content so we add an additional restriction on it.
587*38e8c45fSAndroid Build Coastguard Worker     const uid_t uid = IPCThreadState::self()->getCallingUid();
588*38e8c45fSAndroid Build Coastguard Worker     if (isSecure && uid != AID_ROOT && uid != AID_GRAPHICS && uid != AID_SYSTEM) {
589*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Only privileged processes can create a secure display");
590*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
591*38e8c45fSAndroid Build Coastguard Worker     }
592*38e8c45fSAndroid Build Coastguard Worker 
593*38e8c45fSAndroid Build Coastguard Worker     class DisplayToken : public BBinder {
594*38e8c45fSAndroid Build Coastguard Worker         sp<SurfaceFlinger> flinger;
595*38e8c45fSAndroid Build Coastguard Worker         virtual ~DisplayToken() {
596*38e8c45fSAndroid Build Coastguard Worker              // no more references, this display must be terminated
597*38e8c45fSAndroid Build Coastguard Worker              Mutex::Autolock _l(flinger->mStateLock);
598*38e8c45fSAndroid Build Coastguard Worker              flinger->mCurrentState.displays.removeItem(wp<IBinder>::fromExisting(this));
599*38e8c45fSAndroid Build Coastguard Worker              flinger->setTransactionFlags(eDisplayTransactionNeeded);
600*38e8c45fSAndroid Build Coastguard Worker          }
601*38e8c45fSAndroid Build Coastguard Worker      public:
602*38e8c45fSAndroid Build Coastguard Worker         explicit DisplayToken(const sp<SurfaceFlinger>& flinger)
603*38e8c45fSAndroid Build Coastguard Worker             : flinger(flinger) {
604*38e8c45fSAndroid Build Coastguard Worker         }
605*38e8c45fSAndroid Build Coastguard Worker     };
606*38e8c45fSAndroid Build Coastguard Worker 
607*38e8c45fSAndroid Build Coastguard Worker     sp<BBinder> token = sp<DisplayToken>::make(sp<SurfaceFlinger>::fromExisting(this));
608*38e8c45fSAndroid Build Coastguard Worker 
609*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock _l(mStateLock);
610*38e8c45fSAndroid Build Coastguard Worker     // Display ID is assigned when virtual display is allocated by HWC.
611*38e8c45fSAndroid Build Coastguard Worker     DisplayDeviceState state;
612*38e8c45fSAndroid Build Coastguard Worker     state.isSecure = isSecure;
613*38e8c45fSAndroid Build Coastguard Worker     // Set display as protected when marked as secure to ensure no behavior change
614*38e8c45fSAndroid Build Coastguard Worker     // TODO (b/314820005): separate as a different arg when creating the display.
615*38e8c45fSAndroid Build Coastguard Worker     state.isProtected = isSecure;
616*38e8c45fSAndroid Build Coastguard Worker     state.displayName = displayName;
617*38e8c45fSAndroid Build Coastguard Worker     state.uniqueId = uniqueId;
618*38e8c45fSAndroid Build Coastguard Worker     state.requestedRefreshRate = Fps::fromValue(requestedRefreshRate);
619*38e8c45fSAndroid Build Coastguard Worker     mCurrentState.displays.add(token, state);
620*38e8c45fSAndroid Build Coastguard Worker     return token;
621*38e8c45fSAndroid Build Coastguard Worker }
622*38e8c45fSAndroid Build Coastguard Worker 
destroyVirtualDisplay(const sp<IBinder> & displayToken)623*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::destroyVirtualDisplay(const sp<IBinder>& displayToken) {
624*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
625*38e8c45fSAndroid Build Coastguard Worker 
626*38e8c45fSAndroid Build Coastguard Worker     const ssize_t index = mCurrentState.displays.indexOfKey(displayToken);
627*38e8c45fSAndroid Build Coastguard Worker     if (index < 0) {
628*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: Invalid display token %p", __func__, displayToken.get());
629*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
630*38e8c45fSAndroid Build Coastguard Worker     }
631*38e8c45fSAndroid Build Coastguard Worker 
632*38e8c45fSAndroid Build Coastguard Worker     const DisplayDeviceState& state = mCurrentState.displays.valueAt(index);
633*38e8c45fSAndroid Build Coastguard Worker     if (state.physical) {
634*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: Invalid operation on physical display", __func__);
635*38e8c45fSAndroid Build Coastguard Worker         return INVALID_OPERATION;
636*38e8c45fSAndroid Build Coastguard Worker     }
637*38e8c45fSAndroid Build Coastguard Worker     mCurrentState.displays.removeItemsAt(index);
638*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eDisplayTransactionNeeded);
639*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
640*38e8c45fSAndroid Build Coastguard Worker }
641*38e8c45fSAndroid Build Coastguard Worker 
enableHalVirtualDisplays(bool enable)642*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::enableHalVirtualDisplays(bool enable) {
643*38e8c45fSAndroid Build Coastguard Worker     auto& generator = mVirtualDisplayIdGenerators.hal;
644*38e8c45fSAndroid Build Coastguard Worker     if (!generator && enable) {
645*38e8c45fSAndroid Build Coastguard Worker         ALOGI("Enabling HAL virtual displays");
646*38e8c45fSAndroid Build Coastguard Worker         generator.emplace(getHwComposer().getMaxVirtualDisplayCount());
647*38e8c45fSAndroid Build Coastguard Worker     } else if (generator && !enable) {
648*38e8c45fSAndroid Build Coastguard Worker         ALOGW_IF(generator->inUse(), "Disabling HAL virtual displays while in use");
649*38e8c45fSAndroid Build Coastguard Worker         generator.reset();
650*38e8c45fSAndroid Build Coastguard Worker     }
651*38e8c45fSAndroid Build Coastguard Worker }
652*38e8c45fSAndroid Build Coastguard Worker 
acquireVirtualDisplay(ui::Size resolution,ui::PixelFormat format,const std::string & uniqueId)653*38e8c45fSAndroid Build Coastguard Worker VirtualDisplayId SurfaceFlinger::acquireVirtualDisplay(ui::Size resolution, ui::PixelFormat format,
654*38e8c45fSAndroid Build Coastguard Worker                                                        const std::string& uniqueId) {
655*38e8c45fSAndroid Build Coastguard Worker     if (auto& generator = mVirtualDisplayIdGenerators.hal) {
656*38e8c45fSAndroid Build Coastguard Worker         if (const auto id = generator->generateId()) {
657*38e8c45fSAndroid Build Coastguard Worker             if (getHwComposer().allocateVirtualDisplay(*id, resolution, &format)) {
658*38e8c45fSAndroid Build Coastguard Worker                 acquireVirtualDisplaySnapshot(*id, uniqueId);
659*38e8c45fSAndroid Build Coastguard Worker                 return *id;
660*38e8c45fSAndroid Build Coastguard Worker             }
661*38e8c45fSAndroid Build Coastguard Worker 
662*38e8c45fSAndroid Build Coastguard Worker             generator->releaseId(*id);
663*38e8c45fSAndroid Build Coastguard Worker         } else {
664*38e8c45fSAndroid Build Coastguard Worker             ALOGW("%s: Exhausted HAL virtual displays", __func__);
665*38e8c45fSAndroid Build Coastguard Worker         }
666*38e8c45fSAndroid Build Coastguard Worker 
667*38e8c45fSAndroid Build Coastguard Worker         ALOGW("%s: Falling back to GPU virtual display", __func__);
668*38e8c45fSAndroid Build Coastguard Worker     }
669*38e8c45fSAndroid Build Coastguard Worker 
670*38e8c45fSAndroid Build Coastguard Worker     const auto id = mVirtualDisplayIdGenerators.gpu.generateId();
671*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!id, "Failed to generate ID for GPU virtual display");
672*38e8c45fSAndroid Build Coastguard Worker     acquireVirtualDisplaySnapshot(*id, uniqueId);
673*38e8c45fSAndroid Build Coastguard Worker     return *id;
674*38e8c45fSAndroid Build Coastguard Worker }
675*38e8c45fSAndroid Build Coastguard Worker 
releaseVirtualDisplay(VirtualDisplayId displayId)676*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::releaseVirtualDisplay(VirtualDisplayId displayId) {
677*38e8c45fSAndroid Build Coastguard Worker     if (const auto id = HalVirtualDisplayId::tryCast(displayId)) {
678*38e8c45fSAndroid Build Coastguard Worker         if (auto& generator = mVirtualDisplayIdGenerators.hal) {
679*38e8c45fSAndroid Build Coastguard Worker             generator->releaseId(*id);
680*38e8c45fSAndroid Build Coastguard Worker             releaseVirtualDisplaySnapshot(*id);
681*38e8c45fSAndroid Build Coastguard Worker         }
682*38e8c45fSAndroid Build Coastguard Worker         return;
683*38e8c45fSAndroid Build Coastguard Worker     }
684*38e8c45fSAndroid Build Coastguard Worker 
685*38e8c45fSAndroid Build Coastguard Worker     const auto id = GpuVirtualDisplayId::tryCast(displayId);
686*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!id);
687*38e8c45fSAndroid Build Coastguard Worker     mVirtualDisplayIdGenerators.gpu.releaseId(*id);
688*38e8c45fSAndroid Build Coastguard Worker     releaseVirtualDisplaySnapshot(*id);
689*38e8c45fSAndroid Build Coastguard Worker }
690*38e8c45fSAndroid Build Coastguard Worker 
releaseVirtualDisplaySnapshot(VirtualDisplayId displayId)691*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::releaseVirtualDisplaySnapshot(VirtualDisplayId displayId) {
692*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard lock(mVirtualDisplaysMutex);
693*38e8c45fSAndroid Build Coastguard Worker     if (!mVirtualDisplays.erase(displayId)) {
694*38e8c45fSAndroid Build Coastguard Worker         ALOGW("%s: Virtual display snapshot was not removed", __func__);
695*38e8c45fSAndroid Build Coastguard Worker     }
696*38e8c45fSAndroid Build Coastguard Worker }
697*38e8c45fSAndroid Build Coastguard Worker 
getPhysicalDisplayIdsLocked() const698*38e8c45fSAndroid Build Coastguard Worker std::vector<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIdsLocked() const {
699*38e8c45fSAndroid Build Coastguard Worker     std::vector<PhysicalDisplayId> displayIds;
700*38e8c45fSAndroid Build Coastguard Worker     displayIds.reserve(mPhysicalDisplays.size());
701*38e8c45fSAndroid Build Coastguard Worker 
702*38e8c45fSAndroid Build Coastguard Worker     const auto defaultDisplayId = getDefaultDisplayDeviceLocked()->getPhysicalId();
703*38e8c45fSAndroid Build Coastguard Worker     displayIds.push_back(defaultDisplayId);
704*38e8c45fSAndroid Build Coastguard Worker 
705*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [id, display] : mPhysicalDisplays) {
706*38e8c45fSAndroid Build Coastguard Worker         if (id != defaultDisplayId) {
707*38e8c45fSAndroid Build Coastguard Worker             displayIds.push_back(id);
708*38e8c45fSAndroid Build Coastguard Worker         }
709*38e8c45fSAndroid Build Coastguard Worker     }
710*38e8c45fSAndroid Build Coastguard Worker 
711*38e8c45fSAndroid Build Coastguard Worker     return displayIds;
712*38e8c45fSAndroid Build Coastguard Worker }
713*38e8c45fSAndroid Build Coastguard Worker 
getPhysicalDisplayIdLocked(const sp<display::DisplayToken> & displayToken) const714*38e8c45fSAndroid Build Coastguard Worker std::optional<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIdLocked(
715*38e8c45fSAndroid Build Coastguard Worker         const sp<display::DisplayToken>& displayToken) const {
716*38e8c45fSAndroid Build Coastguard Worker     return ftl::find_if(mPhysicalDisplays, PhysicalDisplay::hasToken(displayToken))
717*38e8c45fSAndroid Build Coastguard Worker             .transform(&ftl::to_key<PhysicalDisplays>);
718*38e8c45fSAndroid Build Coastguard Worker }
719*38e8c45fSAndroid Build Coastguard Worker 
getPhysicalDisplayToken(PhysicalDisplayId displayId) const720*38e8c45fSAndroid Build Coastguard Worker sp<IBinder> SurfaceFlinger::getPhysicalDisplayToken(PhysicalDisplayId displayId) const {
721*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
722*38e8c45fSAndroid Build Coastguard Worker     return getPhysicalDisplayTokenLocked(displayId);
723*38e8c45fSAndroid Build Coastguard Worker }
724*38e8c45fSAndroid Build Coastguard Worker 
getHwComposer() const725*38e8c45fSAndroid Build Coastguard Worker HWComposer& SurfaceFlinger::getHwComposer() const {
726*38e8c45fSAndroid Build Coastguard Worker     return mCompositionEngine->getHwComposer();
727*38e8c45fSAndroid Build Coastguard Worker }
728*38e8c45fSAndroid Build Coastguard Worker 
getRenderEngine() const729*38e8c45fSAndroid Build Coastguard Worker renderengine::RenderEngine& SurfaceFlinger::getRenderEngine() const {
730*38e8c45fSAndroid Build Coastguard Worker     return *mRenderEngine;
731*38e8c45fSAndroid Build Coastguard Worker }
732*38e8c45fSAndroid Build Coastguard Worker 
getCompositionEngine() const733*38e8c45fSAndroid Build Coastguard Worker compositionengine::CompositionEngine& SurfaceFlinger::getCompositionEngine() const {
734*38e8c45fSAndroid Build Coastguard Worker     return *mCompositionEngine.get();
735*38e8c45fSAndroid Build Coastguard Worker }
736*38e8c45fSAndroid Build Coastguard Worker 
bootFinished()737*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::bootFinished() {
738*38e8c45fSAndroid Build Coastguard Worker     if (mBootFinished == true) {
739*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Extra call to bootFinished");
740*38e8c45fSAndroid Build Coastguard Worker         return;
741*38e8c45fSAndroid Build Coastguard Worker     }
742*38e8c45fSAndroid Build Coastguard Worker     mBootFinished = true;
743*38e8c45fSAndroid Build Coastguard Worker     FlagManager::getMutableInstance().markBootCompleted();
744*38e8c45fSAndroid Build Coastguard Worker 
745*38e8c45fSAndroid Build Coastguard Worker     ::tracing_perfetto::registerWithPerfetto();
746*38e8c45fSAndroid Build Coastguard Worker     mInitBootPropsFuture.wait();
747*38e8c45fSAndroid Build Coastguard Worker     mRenderEnginePrimeCacheFuture.wait();
748*38e8c45fSAndroid Build Coastguard Worker 
749*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t now = systemTime();
750*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t duration = now - mBootTime;
751*38e8c45fSAndroid Build Coastguard Worker     ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
752*38e8c45fSAndroid Build Coastguard Worker 
753*38e8c45fSAndroid Build Coastguard Worker     mFrameTracer->initialize();
754*38e8c45fSAndroid Build Coastguard Worker     mFrameTimeline->onBootFinished();
755*38e8c45fSAndroid Build Coastguard Worker     getRenderEngine().setEnableTracing(FlagManager::getInstance().use_skia_tracing());
756*38e8c45fSAndroid Build Coastguard Worker 
757*38e8c45fSAndroid Build Coastguard Worker     // wait patiently for the window manager death
758*38e8c45fSAndroid Build Coastguard Worker     const String16 name("window");
759*38e8c45fSAndroid Build Coastguard Worker     mWindowManager = defaultServiceManager()->waitForService(name);
760*38e8c45fSAndroid Build Coastguard Worker     if (mWindowManager != 0) {
761*38e8c45fSAndroid Build Coastguard Worker         mWindowManager->linkToDeath(sp<IBinder::DeathRecipient>::fromExisting(this));
762*38e8c45fSAndroid Build Coastguard Worker     }
763*38e8c45fSAndroid Build Coastguard Worker 
764*38e8c45fSAndroid Build Coastguard Worker     // stop boot animation
765*38e8c45fSAndroid Build Coastguard Worker     // formerly we would just kill the process, but we now ask it to exit so it
766*38e8c45fSAndroid Build Coastguard Worker     // can choose where to stop the animation.
767*38e8c45fSAndroid Build Coastguard Worker     property_set("service.bootanim.exit", "1");
768*38e8c45fSAndroid Build Coastguard Worker 
769*38e8c45fSAndroid Build Coastguard Worker     const int LOGTAG_SF_STOP_BOOTANIM = 60110;
770*38e8c45fSAndroid Build Coastguard Worker     LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
771*38e8c45fSAndroid Build Coastguard Worker                    ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
772*38e8c45fSAndroid Build Coastguard Worker 
773*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> input(defaultServiceManager()->waitForService(String16("inputflinger")));
774*38e8c45fSAndroid Build Coastguard Worker 
775*38e8c45fSAndroid Build Coastguard Worker     static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) {
776*38e8c45fSAndroid Build Coastguard Worker         if (input == nullptr) {
777*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Failed to link to input service");
778*38e8c45fSAndroid Build Coastguard Worker         } else {
779*38e8c45fSAndroid Build Coastguard Worker             mInputFlinger = interface_cast<os::IInputFlinger>(input);
780*38e8c45fSAndroid Build Coastguard Worker         }
781*38e8c45fSAndroid Build Coastguard Worker 
782*38e8c45fSAndroid Build Coastguard Worker         readPersistentProperties();
783*38e8c45fSAndroid Build Coastguard Worker         const bool hintSessionEnabled = FlagManager::getInstance().use_adpf_cpu_hint();
784*38e8c45fSAndroid Build Coastguard Worker         mPowerAdvisor->enablePowerHintSession(hintSessionEnabled);
785*38e8c45fSAndroid Build Coastguard Worker         const bool hintSessionUsed = mPowerAdvisor->usePowerHintSession();
786*38e8c45fSAndroid Build Coastguard Worker         // Ordering is important here, as onBootFinished signals to PowerAdvisor that concurrency
787*38e8c45fSAndroid Build Coastguard Worker         // is safe because its variables are initialized.
788*38e8c45fSAndroid Build Coastguard Worker         mPowerAdvisor->onBootFinished();
789*38e8c45fSAndroid Build Coastguard Worker         ALOGD("Power hint is %s",
790*38e8c45fSAndroid Build Coastguard Worker               hintSessionUsed ? "supported" : (hintSessionEnabled ? "unsupported" : "disabled"));
791*38e8c45fSAndroid Build Coastguard Worker         if (hintSessionUsed) {
792*38e8c45fSAndroid Build Coastguard Worker             std::optional<pid_t> renderEngineTid = getRenderEngine().getRenderEngineTid();
793*38e8c45fSAndroid Build Coastguard Worker             std::vector<int32_t> tidList;
794*38e8c45fSAndroid Build Coastguard Worker             tidList.emplace_back(gettid());
795*38e8c45fSAndroid Build Coastguard Worker             if (renderEngineTid.has_value()) {
796*38e8c45fSAndroid Build Coastguard Worker                 tidList.emplace_back(*renderEngineTid);
797*38e8c45fSAndroid Build Coastguard Worker             }
798*38e8c45fSAndroid Build Coastguard Worker             if (!mPowerAdvisor->startPowerHintSession(std::move(tidList))) {
799*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("Cannot start power hint session");
800*38e8c45fSAndroid Build Coastguard Worker             }
801*38e8c45fSAndroid Build Coastguard Worker         }
802*38e8c45fSAndroid Build Coastguard Worker 
803*38e8c45fSAndroid Build Coastguard Worker         mBootStage = BootStage::FINISHED;
804*38e8c45fSAndroid Build Coastguard Worker 
805*38e8c45fSAndroid Build Coastguard Worker         if (base::GetBoolProperty("sf.debug.show_refresh_rate_overlay"s, false)) {
806*38e8c45fSAndroid Build Coastguard Worker             ftl::FakeGuard guard(mStateLock);
807*38e8c45fSAndroid Build Coastguard Worker             enableRefreshRateOverlay(true);
808*38e8c45fSAndroid Build Coastguard Worker         }
809*38e8c45fSAndroid Build Coastguard Worker     }));
810*38e8c45fSAndroid Build Coastguard Worker }
811*38e8c45fSAndroid Build Coastguard Worker 
shouldUseGraphiteIfCompiledAndSupported()812*38e8c45fSAndroid Build Coastguard Worker bool shouldUseGraphiteIfCompiledAndSupported() {
813*38e8c45fSAndroid Build Coastguard Worker     return FlagManager::getInstance().graphite_renderengine() ||
814*38e8c45fSAndroid Build Coastguard Worker             (FlagManager::getInstance().graphite_renderengine_preview_rollout() &&
815*38e8c45fSAndroid Build Coastguard Worker              base::GetBoolProperty(PROPERTY_DEBUG_RENDERENGINE_GRAPHITE_PREVIEW_OPTIN, false));
816*38e8c45fSAndroid Build Coastguard Worker }
817*38e8c45fSAndroid Build Coastguard Worker 
chooseRenderEngineType(renderengine::RenderEngineCreationArgs::Builder & builder)818*38e8c45fSAndroid Build Coastguard Worker void chooseRenderEngineType(renderengine::RenderEngineCreationArgs::Builder& builder) {
819*38e8c45fSAndroid Build Coastguard Worker     char prop[PROPERTY_VALUE_MAX];
820*38e8c45fSAndroid Build Coastguard Worker     property_get(PROPERTY_DEBUG_RENDERENGINE_BACKEND, prop, "");
821*38e8c45fSAndroid Build Coastguard Worker 
822*38e8c45fSAndroid Build Coastguard Worker     // TODO: b/293371537 - Once GraphiteVk is deemed relatively stable, log a warning that
823*38e8c45fSAndroid Build Coastguard Worker     // PROPERTY_DEBUG_RENDERENGINE_BACKEND is deprecated
824*38e8c45fSAndroid Build Coastguard Worker     if (strcmp(prop, "skiagl") == 0) {
825*38e8c45fSAndroid Build Coastguard Worker         builder.setThreaded(renderengine::RenderEngine::Threaded::NO)
826*38e8c45fSAndroid Build Coastguard Worker                 .setGraphicsApi(renderengine::RenderEngine::GraphicsApi::GL);
827*38e8c45fSAndroid Build Coastguard Worker     } else if (strcmp(prop, "skiaglthreaded") == 0) {
828*38e8c45fSAndroid Build Coastguard Worker         builder.setThreaded(renderengine::RenderEngine::Threaded::YES)
829*38e8c45fSAndroid Build Coastguard Worker                 .setGraphicsApi(renderengine::RenderEngine::GraphicsApi::GL);
830*38e8c45fSAndroid Build Coastguard Worker     } else if (strcmp(prop, "skiavk") == 0) {
831*38e8c45fSAndroid Build Coastguard Worker         builder.setThreaded(renderengine::RenderEngine::Threaded::NO)
832*38e8c45fSAndroid Build Coastguard Worker                 .setGraphicsApi(renderengine::RenderEngine::GraphicsApi::VK);
833*38e8c45fSAndroid Build Coastguard Worker     } else if (strcmp(prop, "skiavkthreaded") == 0) {
834*38e8c45fSAndroid Build Coastguard Worker         builder.setThreaded(renderengine::RenderEngine::Threaded::YES)
835*38e8c45fSAndroid Build Coastguard Worker                 .setGraphicsApi(renderengine::RenderEngine::GraphicsApi::VK);
836*38e8c45fSAndroid Build Coastguard Worker     } else {
837*38e8c45fSAndroid Build Coastguard Worker         const auto kVulkan = renderengine::RenderEngine::GraphicsApi::VK;
838*38e8c45fSAndroid Build Coastguard Worker // TODO: b/341728634 - Clean up conditional compilation.
839*38e8c45fSAndroid Build Coastguard Worker // Note: this guard in particular must check e.g.
840*38e8c45fSAndroid Build Coastguard Worker // COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS_GRAPHITE_RENDERENGINE directly (instead of calling e.g.
841*38e8c45fSAndroid Build Coastguard Worker // COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS(GRAPHITE_RENDERENGINE)) because that macro is undefined
842*38e8c45fSAndroid Build Coastguard Worker // in the libsurfaceflingerflags_test variant of com_android_graphics_surfaceflinger_flags.h, which
843*38e8c45fSAndroid Build Coastguard Worker // is used by layertracegenerator (which also needs SurfaceFlinger.cpp). :)
844*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS_GRAPHITE_RENDERENGINE || \
845*38e8c45fSAndroid Build Coastguard Worker         COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS_FORCE_COMPILE_GRAPHITE_RENDERENGINE
846*38e8c45fSAndroid Build Coastguard Worker         const bool useGraphite = shouldUseGraphiteIfCompiledAndSupported() &&
847*38e8c45fSAndroid Build Coastguard Worker                 renderengine::RenderEngine::canSupport(kVulkan);
848*38e8c45fSAndroid Build Coastguard Worker #else
849*38e8c45fSAndroid Build Coastguard Worker         const bool useGraphite = false;
850*38e8c45fSAndroid Build Coastguard Worker         if (shouldUseGraphiteIfCompiledAndSupported()) {
851*38e8c45fSAndroid Build Coastguard Worker             ALOGE("RenderEngine's Graphite Skia backend was requested, but it is not compiled in "
852*38e8c45fSAndroid Build Coastguard Worker                   "this build! Falling back to Ganesh backend selection logic.");
853*38e8c45fSAndroid Build Coastguard Worker         }
854*38e8c45fSAndroid Build Coastguard Worker #endif
855*38e8c45fSAndroid Build Coastguard Worker         const bool useVulkan = useGraphite ||
856*38e8c45fSAndroid Build Coastguard Worker                 (FlagManager::getInstance().vulkan_renderengine() &&
857*38e8c45fSAndroid Build Coastguard Worker                  renderengine::RenderEngine::canSupport(kVulkan));
858*38e8c45fSAndroid Build Coastguard Worker 
859*38e8c45fSAndroid Build Coastguard Worker         builder.setSkiaBackend(useGraphite ? renderengine::RenderEngine::SkiaBackend::GRAPHITE
860*38e8c45fSAndroid Build Coastguard Worker                                            : renderengine::RenderEngine::SkiaBackend::GANESH);
861*38e8c45fSAndroid Build Coastguard Worker         builder.setGraphicsApi(useVulkan ? kVulkan : renderengine::RenderEngine::GraphicsApi::GL);
862*38e8c45fSAndroid Build Coastguard Worker     }
863*38e8c45fSAndroid Build Coastguard Worker }
864*38e8c45fSAndroid Build Coastguard Worker 
865*38e8c45fSAndroid Build Coastguard Worker /**
866*38e8c45fSAndroid Build Coastguard Worker  * Choose a suggested blurring algorithm if supportsBlur is true. By default Kawase will be
867*38e8c45fSAndroid Build Coastguard Worker  * suggested as it's faster than a full Gaussian blur and looks close enough.
868*38e8c45fSAndroid Build Coastguard Worker  */
chooseBlurAlgorithm(bool supportsBlur)869*38e8c45fSAndroid Build Coastguard Worker renderengine::RenderEngine::BlurAlgorithm chooseBlurAlgorithm(bool supportsBlur) {
870*38e8c45fSAndroid Build Coastguard Worker     if (!supportsBlur) {
871*38e8c45fSAndroid Build Coastguard Worker         return renderengine::RenderEngine::BlurAlgorithm::NONE;
872*38e8c45fSAndroid Build Coastguard Worker     }
873*38e8c45fSAndroid Build Coastguard Worker 
874*38e8c45fSAndroid Build Coastguard Worker     auto const algorithm = base::GetProperty(PROPERTY_DEBUG_RENDERENGINE_BLUR_ALGORITHM, "");
875*38e8c45fSAndroid Build Coastguard Worker     if (algorithm == "gaussian") {
876*38e8c45fSAndroid Build Coastguard Worker         return renderengine::RenderEngine::BlurAlgorithm::GAUSSIAN;
877*38e8c45fSAndroid Build Coastguard Worker     } else if (algorithm == "kawase2") {
878*38e8c45fSAndroid Build Coastguard Worker         return renderengine::RenderEngine::BlurAlgorithm::KAWASE_DUAL_FILTER;
879*38e8c45fSAndroid Build Coastguard Worker     } else {
880*38e8c45fSAndroid Build Coastguard Worker         if (FlagManager::getInstance().window_blur_kawase2()) {
881*38e8c45fSAndroid Build Coastguard Worker             return renderengine::RenderEngine::BlurAlgorithm::KAWASE_DUAL_FILTER;
882*38e8c45fSAndroid Build Coastguard Worker         }
883*38e8c45fSAndroid Build Coastguard Worker         return renderengine::RenderEngine::BlurAlgorithm::KAWASE;
884*38e8c45fSAndroid Build Coastguard Worker     }
885*38e8c45fSAndroid Build Coastguard Worker }
886*38e8c45fSAndroid Build Coastguard Worker 
init()887*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {
888*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
889*38e8c45fSAndroid Build Coastguard Worker     ALOGI(  "SurfaceFlinger's main thread ready to run. "
890*38e8c45fSAndroid Build Coastguard Worker             "Initializing graphics H/W...");
891*38e8c45fSAndroid Build Coastguard Worker     addTransactionReadyFilters();
892*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
893*38e8c45fSAndroid Build Coastguard Worker 
894*38e8c45fSAndroid Build Coastguard Worker     // Get a RenderEngine for the given display / config (can't fail)
895*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/77156734): We need to stop casting and use HAL types when possible.
896*38e8c45fSAndroid Build Coastguard Worker     // Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
897*38e8c45fSAndroid Build Coastguard Worker     auto builder = renderengine::RenderEngineCreationArgs::Builder()
898*38e8c45fSAndroid Build Coastguard Worker                            .setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
899*38e8c45fSAndroid Build Coastguard Worker                            .setImageCacheSize(maxFrameBufferAcquiredBuffers)
900*38e8c45fSAndroid Build Coastguard Worker                            .setEnableProtectedContext(enable_protected_contents(false))
901*38e8c45fSAndroid Build Coastguard Worker                            .setPrecacheToneMapperShaderOnly(false)
902*38e8c45fSAndroid Build Coastguard Worker                            .setBlurAlgorithm(chooseBlurAlgorithm(mSupportsBlur))
903*38e8c45fSAndroid Build Coastguard Worker                            .setContextPriority(
904*38e8c45fSAndroid Build Coastguard Worker                                    useContextPriority
905*38e8c45fSAndroid Build Coastguard Worker                                            ? renderengine::RenderEngine::ContextPriority::REALTIME
906*38e8c45fSAndroid Build Coastguard Worker                                            : renderengine::RenderEngine::ContextPriority::MEDIUM);
907*38e8c45fSAndroid Build Coastguard Worker     chooseRenderEngineType(builder);
908*38e8c45fSAndroid Build Coastguard Worker     mRenderEngine = renderengine::RenderEngine::create(builder.build());
909*38e8c45fSAndroid Build Coastguard Worker     mCompositionEngine->setRenderEngine(mRenderEngine.get());
910*38e8c45fSAndroid Build Coastguard Worker     mMaxRenderTargetSize =
911*38e8c45fSAndroid Build Coastguard Worker             std::min(getRenderEngine().getMaxTextureSize(), getRenderEngine().getMaxViewportDims());
912*38e8c45fSAndroid Build Coastguard Worker 
913*38e8c45fSAndroid Build Coastguard Worker     // Set SF main policy after initializing RenderEngine which has its own policy.
914*38e8c45fSAndroid Build Coastguard Worker     if (!SetTaskProfiles(0, {"SFMainPolicy"})) {
915*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Failed to set main task profile");
916*38e8c45fSAndroid Build Coastguard Worker     }
917*38e8c45fSAndroid Build Coastguard Worker 
918*38e8c45fSAndroid Build Coastguard Worker     mCompositionEngine->setTimeStats(mTimeStats);
919*38e8c45fSAndroid Build Coastguard Worker 
920*38e8c45fSAndroid Build Coastguard Worker     mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));
921*38e8c45fSAndroid Build Coastguard Worker     auto& composer = mCompositionEngine->getHwComposer();
922*38e8c45fSAndroid Build Coastguard Worker     composer.setCallback(*this);
923*38e8c45fSAndroid Build Coastguard Worker     mDisplayModeController.setHwComposer(&composer);
924*38e8c45fSAndroid Build Coastguard Worker 
925*38e8c45fSAndroid Build Coastguard Worker     ClientCache::getInstance().setRenderEngine(&getRenderEngine());
926*38e8c45fSAndroid Build Coastguard Worker 
927*38e8c45fSAndroid Build Coastguard Worker     mHasReliablePresentFences =
928*38e8c45fSAndroid Build Coastguard Worker             !getHwComposer().hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
929*38e8c45fSAndroid Build Coastguard Worker 
930*38e8c45fSAndroid Build Coastguard Worker     enableLatchUnsignaledConfig = getLatchUnsignaledConfig();
931*38e8c45fSAndroid Build Coastguard Worker 
932*38e8c45fSAndroid Build Coastguard Worker     if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) {
933*38e8c45fSAndroid Build Coastguard Worker         enableHalVirtualDisplays(true);
934*38e8c45fSAndroid Build Coastguard Worker     }
935*38e8c45fSAndroid Build Coastguard Worker 
936*38e8c45fSAndroid Build Coastguard Worker     // Process hotplug for displays connected at boot.
937*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!configureLocked(),
938*38e8c45fSAndroid Build Coastguard Worker                         "Initial display configuration failed: HWC did not hotplug");
939*38e8c45fSAndroid Build Coastguard Worker 
940*38e8c45fSAndroid Build Coastguard Worker     mActiveDisplayId = getPrimaryDisplayIdLocked();
941*38e8c45fSAndroid Build Coastguard Worker 
942*38e8c45fSAndroid Build Coastguard Worker     // Commit primary display.
943*38e8c45fSAndroid Build Coastguard Worker     sp<const DisplayDevice> display;
944*38e8c45fSAndroid Build Coastguard Worker     if (const auto indexOpt = mCurrentState.getDisplayIndex(mActiveDisplayId)) {
945*38e8c45fSAndroid Build Coastguard Worker         const auto& displays = mCurrentState.displays;
946*38e8c45fSAndroid Build Coastguard Worker 
947*38e8c45fSAndroid Build Coastguard Worker         const auto& token = displays.keyAt(*indexOpt);
948*38e8c45fSAndroid Build Coastguard Worker         const auto& state = displays.valueAt(*indexOpt);
949*38e8c45fSAndroid Build Coastguard Worker 
950*38e8c45fSAndroid Build Coastguard Worker         processDisplayAdded(token, state);
951*38e8c45fSAndroid Build Coastguard Worker         mDrawingState.displays.add(token, state);
952*38e8c45fSAndroid Build Coastguard Worker 
953*38e8c45fSAndroid Build Coastguard Worker         display = getDefaultDisplayDeviceLocked();
954*38e8c45fSAndroid Build Coastguard Worker     }
955*38e8c45fSAndroid Build Coastguard Worker 
956*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!display, "Failed to configure the primary display");
957*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(display->getPhysicalId()),
958*38e8c45fSAndroid Build Coastguard Worker                         "Primary display is disconnected");
959*38e8c45fSAndroid Build Coastguard Worker 
960*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/241285876): The Scheduler needlessly depends on creating the CompositionEngine part of
961*38e8c45fSAndroid Build Coastguard Worker     // the DisplayDevice, hence the above commit of the primary display. Remove that special case by
962*38e8c45fSAndroid Build Coastguard Worker     // initializing the Scheduler after configureLocked, once decoupled from DisplayDevice.
963*38e8c45fSAndroid Build Coastguard Worker     initScheduler(display);
964*38e8c45fSAndroid Build Coastguard Worker 
965*38e8c45fSAndroid Build Coastguard Worker     // Start listening after creating the Scheduler, since the listener calls into it.
966*38e8c45fSAndroid Build Coastguard Worker     mDisplayModeController.setActiveModeListener(
967*38e8c45fSAndroid Build Coastguard Worker             display::DisplayModeController::ActiveModeListener::make(
968*38e8c45fSAndroid Build Coastguard Worker                     [this](PhysicalDisplayId displayId, Fps vsyncRate, Fps renderRate) {
969*38e8c45fSAndroid Build Coastguard Worker                         // This callback cannot lock mStateLock, as some callers already lock it.
970*38e8c45fSAndroid Build Coastguard Worker                         // Instead, switch context to the main thread.
971*38e8c45fSAndroid Build Coastguard Worker                         static_cast<void>(mScheduler->schedule([=,
972*38e8c45fSAndroid Build Coastguard Worker                                                                 this]() FTL_FAKE_GUARD(mStateLock) {
973*38e8c45fSAndroid Build Coastguard Worker                             if (const auto display = getDisplayDeviceLocked(displayId)) {
974*38e8c45fSAndroid Build Coastguard Worker                                 display->updateRefreshRateOverlayRate(vsyncRate, renderRate);
975*38e8c45fSAndroid Build Coastguard Worker                             }
976*38e8c45fSAndroid Build Coastguard Worker                         }));
977*38e8c45fSAndroid Build Coastguard Worker                     }));
978*38e8c45fSAndroid Build Coastguard Worker 
979*38e8c45fSAndroid Build Coastguard Worker     mLayerTracing.setTakeLayersSnapshotProtoFunction(
980*38e8c45fSAndroid Build Coastguard Worker             [&](uint32_t traceFlags,
981*38e8c45fSAndroid Build Coastguard Worker                 const LayerTracing::OnLayersSnapshotCallback& onLayersSnapshot) {
982*38e8c45fSAndroid Build Coastguard Worker                 // Do not wait the future to avoid deadlocks
983*38e8c45fSAndroid Build Coastguard Worker                 // between main and Perfetto threads (b/313130597)
984*38e8c45fSAndroid Build Coastguard Worker                 static_cast<void>(mScheduler->schedule(
985*38e8c45fSAndroid Build Coastguard Worker                         [&, traceFlags, onLayersSnapshot]() FTL_FAKE_GUARD(mStateLock)
986*38e8c45fSAndroid Build Coastguard Worker                                 FTL_FAKE_GUARD(kMainThreadContext) {
987*38e8c45fSAndroid Build Coastguard Worker                                     auto snapshot =
988*38e8c45fSAndroid Build Coastguard Worker                                             takeLayersSnapshotProto(traceFlags, TimePoint::now(),
989*38e8c45fSAndroid Build Coastguard Worker                                                                     mLastCommittedVsyncId, true);
990*38e8c45fSAndroid Build Coastguard Worker                                     onLayersSnapshot(std::move(snapshot));
991*38e8c45fSAndroid Build Coastguard Worker                                 }));
992*38e8c45fSAndroid Build Coastguard Worker             });
993*38e8c45fSAndroid Build Coastguard Worker 
994*38e8c45fSAndroid Build Coastguard Worker     // Commit secondary display(s).
995*38e8c45fSAndroid Build Coastguard Worker     processDisplayChangesLocked();
996*38e8c45fSAndroid Build Coastguard Worker 
997*38e8c45fSAndroid Build Coastguard Worker     // initialize our drawing state
998*38e8c45fSAndroid Build Coastguard Worker     mDrawingState = mCurrentState;
999*38e8c45fSAndroid Build Coastguard Worker 
1000*38e8c45fSAndroid Build Coastguard Worker     onActiveDisplayChangedLocked(nullptr, *display);
1001*38e8c45fSAndroid Build Coastguard Worker 
1002*38e8c45fSAndroid Build Coastguard Worker     static_cast<void>(mScheduler->schedule(
1003*38e8c45fSAndroid Build Coastguard Worker             [this]() FTL_FAKE_GUARD(kMainThreadContext) { initializeDisplays(); }));
1004*38e8c45fSAndroid Build Coastguard Worker 
1005*38e8c45fSAndroid Build Coastguard Worker     mPowerAdvisor->init();
1006*38e8c45fSAndroid Build Coastguard Worker 
1007*38e8c45fSAndroid Build Coastguard Worker     if (base::GetBoolProperty("service.sf.prime_shader_cache"s, true)) {
1008*38e8c45fSAndroid Build Coastguard Worker         if (setSchedFifo(false) != NO_ERROR) {
1009*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Can't set SCHED_OTHER for primeCache");
1010*38e8c45fSAndroid Build Coastguard Worker         }
1011*38e8c45fSAndroid Build Coastguard Worker 
1012*38e8c45fSAndroid Build Coastguard Worker         mRenderEnginePrimeCacheFuture.callOnce([this] {
1013*38e8c45fSAndroid Build Coastguard Worker             renderengine::PrimeCacheConfig config;
1014*38e8c45fSAndroid Build Coastguard Worker             config.cacheHolePunchLayer =
1015*38e8c45fSAndroid Build Coastguard Worker                     base::GetBoolProperty("debug.sf.prime_shader_cache.hole_punch"s, true);
1016*38e8c45fSAndroid Build Coastguard Worker             config.cacheSolidLayers =
1017*38e8c45fSAndroid Build Coastguard Worker                     base::GetBoolProperty("debug.sf.prime_shader_cache.solid_layers"s, true);
1018*38e8c45fSAndroid Build Coastguard Worker             config.cacheSolidDimmedLayers =
1019*38e8c45fSAndroid Build Coastguard Worker                     base::GetBoolProperty("debug.sf.prime_shader_cache.solid_dimmed_layers"s, true);
1020*38e8c45fSAndroid Build Coastguard Worker             config.cacheImageLayers =
1021*38e8c45fSAndroid Build Coastguard Worker                     base::GetBoolProperty("debug.sf.prime_shader_cache.image_layers"s, true);
1022*38e8c45fSAndroid Build Coastguard Worker             config.cacheImageDimmedLayers =
1023*38e8c45fSAndroid Build Coastguard Worker                     base::GetBoolProperty("debug.sf.prime_shader_cache.image_dimmed_layers"s, true);
1024*38e8c45fSAndroid Build Coastguard Worker             config.cacheClippedLayers =
1025*38e8c45fSAndroid Build Coastguard Worker                     base::GetBoolProperty("debug.sf.prime_shader_cache.clipped_layers"s, true);
1026*38e8c45fSAndroid Build Coastguard Worker             config.cacheShadowLayers =
1027*38e8c45fSAndroid Build Coastguard Worker                     base::GetBoolProperty("debug.sf.prime_shader_cache.shadow_layers"s, true);
1028*38e8c45fSAndroid Build Coastguard Worker             config.cachePIPImageLayers =
1029*38e8c45fSAndroid Build Coastguard Worker                     base::GetBoolProperty("debug.sf.prime_shader_cache.pip_image_layers"s, true);
1030*38e8c45fSAndroid Build Coastguard Worker             config.cacheTransparentImageDimmedLayers = base::
1031*38e8c45fSAndroid Build Coastguard Worker                     GetBoolProperty("debug.sf.prime_shader_cache.transparent_image_dimmed_layers"s,
1032*38e8c45fSAndroid Build Coastguard Worker                                     true);
1033*38e8c45fSAndroid Build Coastguard Worker             config.cacheClippedDimmedImageLayers = base::
1034*38e8c45fSAndroid Build Coastguard Worker                     GetBoolProperty("debug.sf.prime_shader_cache.clipped_dimmed_image_layers"s,
1035*38e8c45fSAndroid Build Coastguard Worker                                     true);
1036*38e8c45fSAndroid Build Coastguard Worker             // ro.surface_flinger.prime_chader_cache.ultrahdr exists as a previous ro property
1037*38e8c45fSAndroid Build Coastguard Worker             // which we maintain for backwards compatibility.
1038*38e8c45fSAndroid Build Coastguard Worker             config.cacheUltraHDR =
1039*38e8c45fSAndroid Build Coastguard Worker                     base::GetBoolProperty("ro.surface_flinger.prime_shader_cache.ultrahdr"s, false);
1040*38e8c45fSAndroid Build Coastguard Worker             config.cacheEdgeExtension =
1041*38e8c45fSAndroid Build Coastguard Worker                     base::GetBoolProperty("debug.sf.prime_shader_cache.edge_extension_shader"s,
1042*38e8c45fSAndroid Build Coastguard Worker                                           true);
1043*38e8c45fSAndroid Build Coastguard Worker             return getRenderEngine().primeCache(config);
1044*38e8c45fSAndroid Build Coastguard Worker         });
1045*38e8c45fSAndroid Build Coastguard Worker 
1046*38e8c45fSAndroid Build Coastguard Worker         if (setSchedFifo(true) != NO_ERROR) {
1047*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Can't set SCHED_FIFO after primeCache");
1048*38e8c45fSAndroid Build Coastguard Worker         }
1049*38e8c45fSAndroid Build Coastguard Worker     }
1050*38e8c45fSAndroid Build Coastguard Worker 
1051*38e8c45fSAndroid Build Coastguard Worker     // Avoid blocking the main thread on `init` to set properties.
1052*38e8c45fSAndroid Build Coastguard Worker     mInitBootPropsFuture.callOnce([this] {
1053*38e8c45fSAndroid Build Coastguard Worker         return std::async(std::launch::async, &SurfaceFlinger::initBootProperties, this);
1054*38e8c45fSAndroid Build Coastguard Worker     });
1055*38e8c45fSAndroid Build Coastguard Worker 
1056*38e8c45fSAndroid Build Coastguard Worker     initTransactionTraceWriter();
1057*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Done initializing");
1058*38e8c45fSAndroid Build Coastguard Worker }
1059*38e8c45fSAndroid Build Coastguard Worker 
1060*38e8c45fSAndroid Build Coastguard Worker // During boot, offload `initBootProperties` to another thread. `property_set` depends on
1061*38e8c45fSAndroid Build Coastguard Worker // `property_service`, which may be delayed by slow operations like `mount_all --late` in
1062*38e8c45fSAndroid Build Coastguard Worker // the `init` process. See b/34499826 and b/63844978.
initBootProperties()1063*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::initBootProperties() {
1064*38e8c45fSAndroid Build Coastguard Worker     property_set("service.sf.present_timestamp", mHasReliablePresentFences ? "1" : "0");
1065*38e8c45fSAndroid Build Coastguard Worker 
1066*38e8c45fSAndroid Build Coastguard Worker     if (base::GetBoolProperty("debug.sf.boot_animation"s, true)) {
1067*38e8c45fSAndroid Build Coastguard Worker         // Reset and (if needed) start BootAnimation.
1068*38e8c45fSAndroid Build Coastguard Worker         property_set("service.bootanim.exit", "0");
1069*38e8c45fSAndroid Build Coastguard Worker         property_set("service.bootanim.progress", "0");
1070*38e8c45fSAndroid Build Coastguard Worker         property_set("ctl.start", "bootanim");
1071*38e8c45fSAndroid Build Coastguard Worker     }
1072*38e8c45fSAndroid Build Coastguard Worker }
1073*38e8c45fSAndroid Build Coastguard Worker 
initTransactionTraceWriter()1074*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::initTransactionTraceWriter() {
1075*38e8c45fSAndroid Build Coastguard Worker     if (!mTransactionTracing) {
1076*38e8c45fSAndroid Build Coastguard Worker         return;
1077*38e8c45fSAndroid Build Coastguard Worker     }
1078*38e8c45fSAndroid Build Coastguard Worker     TransactionTraceWriter::getInstance().setWriterFunction(
1079*38e8c45fSAndroid Build Coastguard Worker             [&](const std::string& filename, bool overwrite) {
1080*38e8c45fSAndroid Build Coastguard Worker                 auto writeFn = [&]() {
1081*38e8c45fSAndroid Build Coastguard Worker                     if (!overwrite && fileNewerThan(filename, std::chrono::minutes{10})) {
1082*38e8c45fSAndroid Build Coastguard Worker                         ALOGD("TransactionTraceWriter: file=%s already exists", filename.c_str());
1083*38e8c45fSAndroid Build Coastguard Worker                         return;
1084*38e8c45fSAndroid Build Coastguard Worker                     }
1085*38e8c45fSAndroid Build Coastguard Worker                     ALOGD("TransactionTraceWriter: writing file=%s", filename.c_str());
1086*38e8c45fSAndroid Build Coastguard Worker                     mTransactionTracing->writeToFile(filename);
1087*38e8c45fSAndroid Build Coastguard Worker                     mTransactionTracing->flush();
1088*38e8c45fSAndroid Build Coastguard Worker                 };
1089*38e8c45fSAndroid Build Coastguard Worker                 if (std::this_thread::get_id() == mMainThreadId) {
1090*38e8c45fSAndroid Build Coastguard Worker                     writeFn();
1091*38e8c45fSAndroid Build Coastguard Worker                 } else {
1092*38e8c45fSAndroid Build Coastguard Worker                     mScheduler->schedule(writeFn).get();
1093*38e8c45fSAndroid Build Coastguard Worker                 }
1094*38e8c45fSAndroid Build Coastguard Worker             });
1095*38e8c45fSAndroid Build Coastguard Worker }
1096*38e8c45fSAndroid Build Coastguard Worker 
readPersistentProperties()1097*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::readPersistentProperties() {
1098*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock _l(mStateLock);
1099*38e8c45fSAndroid Build Coastguard Worker 
1100*38e8c45fSAndroid Build Coastguard Worker     char value[PROPERTY_VALUE_MAX];
1101*38e8c45fSAndroid Build Coastguard Worker 
1102*38e8c45fSAndroid Build Coastguard Worker     property_get("persist.sys.sf.color_saturation", value, "1.0");
1103*38e8c45fSAndroid Build Coastguard Worker     mGlobalSaturationFactor = atof(value);
1104*38e8c45fSAndroid Build Coastguard Worker     updateColorMatrixLocked();
1105*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Saturation is set to %.2f", mGlobalSaturationFactor);
1106*38e8c45fSAndroid Build Coastguard Worker 
1107*38e8c45fSAndroid Build Coastguard Worker     property_get("persist.sys.sf.native_mode", value, "0");
1108*38e8c45fSAndroid Build Coastguard Worker     mDisplayColorSetting = static_cast<DisplayColorSetting>(atoi(value));
1109*38e8c45fSAndroid Build Coastguard Worker 
1110*38e8c45fSAndroid Build Coastguard Worker     mForceColorMode =
1111*38e8c45fSAndroid Build Coastguard Worker             static_cast<ui::ColorMode>(base::GetIntProperty("persist.sys.sf.color_mode"s, 0));
1112*38e8c45fSAndroid Build Coastguard Worker }
1113*38e8c45fSAndroid Build Coastguard Worker 
getSupportedFrameTimestamps(std::vector<FrameEvent> * outSupported) const1114*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getSupportedFrameTimestamps(
1115*38e8c45fSAndroid Build Coastguard Worker         std::vector<FrameEvent>* outSupported) const {
1116*38e8c45fSAndroid Build Coastguard Worker     *outSupported = {
1117*38e8c45fSAndroid Build Coastguard Worker         FrameEvent::REQUESTED_PRESENT,
1118*38e8c45fSAndroid Build Coastguard Worker         FrameEvent::ACQUIRE,
1119*38e8c45fSAndroid Build Coastguard Worker         FrameEvent::LATCH,
1120*38e8c45fSAndroid Build Coastguard Worker         FrameEvent::FIRST_REFRESH_START,
1121*38e8c45fSAndroid Build Coastguard Worker         FrameEvent::LAST_REFRESH_START,
1122*38e8c45fSAndroid Build Coastguard Worker         FrameEvent::GPU_COMPOSITION_DONE,
1123*38e8c45fSAndroid Build Coastguard Worker         FrameEvent::DEQUEUE_READY,
1124*38e8c45fSAndroid Build Coastguard Worker         FrameEvent::RELEASE,
1125*38e8c45fSAndroid Build Coastguard Worker     };
1126*38e8c45fSAndroid Build Coastguard Worker 
1127*38e8c45fSAndroid Build Coastguard Worker     if (mHasReliablePresentFences) {
1128*38e8c45fSAndroid Build Coastguard Worker         outSupported->push_back(FrameEvent::DISPLAY_PRESENT);
1129*38e8c45fSAndroid Build Coastguard Worker     }
1130*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1131*38e8c45fSAndroid Build Coastguard Worker }
1132*38e8c45fSAndroid Build Coastguard Worker 
getDisplayState(const sp<IBinder> & displayToken,ui::DisplayState * state)1133*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getDisplayState(const sp<IBinder>& displayToken, ui::DisplayState* state) {
1134*38e8c45fSAndroid Build Coastguard Worker     if (!displayToken || !state) {
1135*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
1136*38e8c45fSAndroid Build Coastguard Worker     }
1137*38e8c45fSAndroid Build Coastguard Worker 
1138*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
1139*38e8c45fSAndroid Build Coastguard Worker 
1140*38e8c45fSAndroid Build Coastguard Worker     const auto display = getDisplayDeviceLocked(displayToken);
1141*38e8c45fSAndroid Build Coastguard Worker     if (!display) {
1142*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
1143*38e8c45fSAndroid Build Coastguard Worker     }
1144*38e8c45fSAndroid Build Coastguard Worker 
1145*38e8c45fSAndroid Build Coastguard Worker     state->layerStack = display->getLayerStack();
1146*38e8c45fSAndroid Build Coastguard Worker     state->orientation = display->getOrientation();
1147*38e8c45fSAndroid Build Coastguard Worker 
1148*38e8c45fSAndroid Build Coastguard Worker     const Rect layerStackRect = display->getLayerStackSpaceRect();
1149*38e8c45fSAndroid Build Coastguard Worker     state->layerStackSpaceRect =
1150*38e8c45fSAndroid Build Coastguard Worker             layerStackRect.isValid() ? layerStackRect.getSize() : display->getSize();
1151*38e8c45fSAndroid Build Coastguard Worker 
1152*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1153*38e8c45fSAndroid Build Coastguard Worker }
1154*38e8c45fSAndroid Build Coastguard Worker 
getStaticDisplayInfo(int64_t displayId,ui::StaticDisplayInfo * info)1155*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getStaticDisplayInfo(int64_t displayId, ui::StaticDisplayInfo* info) {
1156*38e8c45fSAndroid Build Coastguard Worker     if (!info) {
1157*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
1158*38e8c45fSAndroid Build Coastguard Worker     }
1159*38e8c45fSAndroid Build Coastguard Worker 
1160*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
1161*38e8c45fSAndroid Build Coastguard Worker     const auto id = DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(displayId));
1162*38e8c45fSAndroid Build Coastguard Worker     const auto displayOpt = mPhysicalDisplays.get(*id).and_then(getDisplayDeviceAndSnapshot());
1163*38e8c45fSAndroid Build Coastguard Worker 
1164*38e8c45fSAndroid Build Coastguard Worker     if (!displayOpt) {
1165*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
1166*38e8c45fSAndroid Build Coastguard Worker     }
1167*38e8c45fSAndroid Build Coastguard Worker 
1168*38e8c45fSAndroid Build Coastguard Worker     const auto& [display, snapshotRef] = *displayOpt;
1169*38e8c45fSAndroid Build Coastguard Worker     const auto& snapshot = snapshotRef.get();
1170*38e8c45fSAndroid Build Coastguard Worker 
1171*38e8c45fSAndroid Build Coastguard Worker     info->connectionType = snapshot.connectionType();
1172*38e8c45fSAndroid Build Coastguard Worker     info->deviceProductInfo = snapshot.deviceProductInfo();
1173*38e8c45fSAndroid Build Coastguard Worker 
1174*38e8c45fSAndroid Build Coastguard Worker     if (mEmulatedDisplayDensity) {
1175*38e8c45fSAndroid Build Coastguard Worker         info->density = mEmulatedDisplayDensity;
1176*38e8c45fSAndroid Build Coastguard Worker     } else {
1177*38e8c45fSAndroid Build Coastguard Worker         info->density = info->connectionType == ui::DisplayConnectionType::Internal
1178*38e8c45fSAndroid Build Coastguard Worker                 ? mInternalDisplayDensity
1179*38e8c45fSAndroid Build Coastguard Worker                 : FALLBACK_DENSITY;
1180*38e8c45fSAndroid Build Coastguard Worker     }
1181*38e8c45fSAndroid Build Coastguard Worker     info->density /= ACONFIGURATION_DENSITY_MEDIUM;
1182*38e8c45fSAndroid Build Coastguard Worker 
1183*38e8c45fSAndroid Build Coastguard Worker     info->secure = display->isSecure();
1184*38e8c45fSAndroid Build Coastguard Worker     info->installOrientation = display->getPhysicalOrientation();
1185*38e8c45fSAndroid Build Coastguard Worker 
1186*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1187*38e8c45fSAndroid Build Coastguard Worker }
1188*38e8c45fSAndroid Build Coastguard Worker 
getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo * & info,const sp<DisplayDevice> & display,const display::DisplaySnapshot & snapshot)1189*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo*& info,
1190*38e8c45fSAndroid Build Coastguard Worker                                                    const sp<DisplayDevice>& display,
1191*38e8c45fSAndroid Build Coastguard Worker                                                    const display::DisplaySnapshot& snapshot) {
1192*38e8c45fSAndroid Build Coastguard Worker     const auto& displayModes = snapshot.displayModes();
1193*38e8c45fSAndroid Build Coastguard Worker     info->supportedDisplayModes.clear();
1194*38e8c45fSAndroid Build Coastguard Worker     info->supportedDisplayModes.reserve(displayModes.size());
1195*38e8c45fSAndroid Build Coastguard Worker 
1196*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [id, mode] : displayModes) {
1197*38e8c45fSAndroid Build Coastguard Worker         ui::DisplayMode outMode;
1198*38e8c45fSAndroid Build Coastguard Worker         outMode.id = ftl::to_underlying(id);
1199*38e8c45fSAndroid Build Coastguard Worker 
1200*38e8c45fSAndroid Build Coastguard Worker         auto [width, height] = mode->getResolution();
1201*38e8c45fSAndroid Build Coastguard Worker         auto [xDpi, yDpi] = mode->getDpi();
1202*38e8c45fSAndroid Build Coastguard Worker 
1203*38e8c45fSAndroid Build Coastguard Worker         if (const auto physicalOrientation = display->getPhysicalOrientation();
1204*38e8c45fSAndroid Build Coastguard Worker             physicalOrientation == ui::ROTATION_90 || physicalOrientation == ui::ROTATION_270) {
1205*38e8c45fSAndroid Build Coastguard Worker             std::swap(width, height);
1206*38e8c45fSAndroid Build Coastguard Worker             std::swap(xDpi, yDpi);
1207*38e8c45fSAndroid Build Coastguard Worker         }
1208*38e8c45fSAndroid Build Coastguard Worker 
1209*38e8c45fSAndroid Build Coastguard Worker         outMode.resolution = ui::Size(width, height);
1210*38e8c45fSAndroid Build Coastguard Worker 
1211*38e8c45fSAndroid Build Coastguard Worker         outMode.xDpi = xDpi;
1212*38e8c45fSAndroid Build Coastguard Worker         outMode.yDpi = yDpi;
1213*38e8c45fSAndroid Build Coastguard Worker 
1214*38e8c45fSAndroid Build Coastguard Worker         const auto peakFps = mode->getPeakFps();
1215*38e8c45fSAndroid Build Coastguard Worker         outMode.peakRefreshRate = peakFps.getValue();
1216*38e8c45fSAndroid Build Coastguard Worker         outMode.vsyncRate = mode->getVsyncRate().getValue();
1217*38e8c45fSAndroid Build Coastguard Worker 
1218*38e8c45fSAndroid Build Coastguard Worker         const auto vsyncConfigSet = mScheduler->getVsyncConfiguration().getConfigsForRefreshRate(
1219*38e8c45fSAndroid Build Coastguard Worker                 Fps::fromValue(outMode.peakRefreshRate));
1220*38e8c45fSAndroid Build Coastguard Worker         outMode.appVsyncOffset = vsyncConfigSet.late.appOffset;
1221*38e8c45fSAndroid Build Coastguard Worker         outMode.sfVsyncOffset = vsyncConfigSet.late.sfOffset;
1222*38e8c45fSAndroid Build Coastguard Worker         outMode.group = mode->getGroup();
1223*38e8c45fSAndroid Build Coastguard Worker 
1224*38e8c45fSAndroid Build Coastguard Worker         // This is how far in advance a buffer must be queued for
1225*38e8c45fSAndroid Build Coastguard Worker         // presentation at a given time.  If you want a buffer to appear
1226*38e8c45fSAndroid Build Coastguard Worker         // on the screen at time N, you must submit the buffer before
1227*38e8c45fSAndroid Build Coastguard Worker         // (N - presentationDeadline).
1228*38e8c45fSAndroid Build Coastguard Worker         //
1229*38e8c45fSAndroid Build Coastguard Worker         // Normally it's one full refresh period (to give SF a chance to
1230*38e8c45fSAndroid Build Coastguard Worker         // latch the buffer), but this can be reduced by configuring a
1231*38e8c45fSAndroid Build Coastguard Worker         // VsyncController offset.  Any additional delays introduced by the hardware
1232*38e8c45fSAndroid Build Coastguard Worker         // composer or panel must be accounted for here.
1233*38e8c45fSAndroid Build Coastguard Worker         //
1234*38e8c45fSAndroid Build Coastguard Worker         // We add an additional 1ms to allow for processing time and
1235*38e8c45fSAndroid Build Coastguard Worker         // differences between the ideal and actual refresh rate.
1236*38e8c45fSAndroid Build Coastguard Worker         outMode.presentationDeadline = peakFps.getPeriodNsecs() - outMode.sfVsyncOffset + 1000000;
1237*38e8c45fSAndroid Build Coastguard Worker         excludeDolbyVisionIf4k30Present(display->getHdrCapabilities().getSupportedHdrTypes(),
1238*38e8c45fSAndroid Build Coastguard Worker                                         outMode);
1239*38e8c45fSAndroid Build Coastguard Worker         info->supportedDisplayModes.push_back(outMode);
1240*38e8c45fSAndroid Build Coastguard Worker     }
1241*38e8c45fSAndroid Build Coastguard Worker 
1242*38e8c45fSAndroid Build Coastguard Worker     info->supportedColorModes = snapshot.filterColorModes(mSupportsWideColor);
1243*38e8c45fSAndroid Build Coastguard Worker 
1244*38e8c45fSAndroid Build Coastguard Worker     const PhysicalDisplayId displayId = snapshot.displayId();
1245*38e8c45fSAndroid Build Coastguard Worker 
1246*38e8c45fSAndroid Build Coastguard Worker     const auto mode = display->refreshRateSelector().getActiveMode();
1247*38e8c45fSAndroid Build Coastguard Worker     info->activeDisplayModeId = ftl::to_underlying(mode.modePtr->getId());
1248*38e8c45fSAndroid Build Coastguard Worker     info->renderFrameRate = mode.fps.getValue();
1249*38e8c45fSAndroid Build Coastguard Worker     info->hasArrSupport = mode.modePtr->getVrrConfig() && FlagManager::getInstance().vrr_config();
1250*38e8c45fSAndroid Build Coastguard Worker 
1251*38e8c45fSAndroid Build Coastguard Worker     const auto [normal, high] = display->refreshRateSelector().getFrameRateCategoryRates();
1252*38e8c45fSAndroid Build Coastguard Worker     ui::FrameRateCategoryRate frameRateCategoryRate(normal.getValue(), high.getValue());
1253*38e8c45fSAndroid Build Coastguard Worker     info->frameRateCategoryRate = frameRateCategoryRate;
1254*38e8c45fSAndroid Build Coastguard Worker 
1255*38e8c45fSAndroid Build Coastguard Worker     info->supportedRefreshRates = display->refreshRateSelector().getSupportedFrameRates();
1256*38e8c45fSAndroid Build Coastguard Worker     info->activeColorMode = display->getCompositionDisplay()->getState().colorMode;
1257*38e8c45fSAndroid Build Coastguard Worker     info->hdrCapabilities = filterOut4k30(display->getHdrCapabilities());
1258*38e8c45fSAndroid Build Coastguard Worker 
1259*38e8c45fSAndroid Build Coastguard Worker     info->autoLowLatencyModeSupported =
1260*38e8c45fSAndroid Build Coastguard Worker             getHwComposer().hasDisplayCapability(displayId,
1261*38e8c45fSAndroid Build Coastguard Worker                                                  DisplayCapability::AUTO_LOW_LATENCY_MODE);
1262*38e8c45fSAndroid Build Coastguard Worker     info->gameContentTypeSupported =
1263*38e8c45fSAndroid Build Coastguard Worker             getHwComposer().supportsContentType(displayId, hal::ContentType::GAME);
1264*38e8c45fSAndroid Build Coastguard Worker 
1265*38e8c45fSAndroid Build Coastguard Worker     info->preferredBootDisplayMode = static_cast<ui::DisplayModeId>(-1);
1266*38e8c45fSAndroid Build Coastguard Worker 
1267*38e8c45fSAndroid Build Coastguard Worker     if (getHwComposer().hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
1268*38e8c45fSAndroid Build Coastguard Worker         if (const auto hwcId = getHwComposer().getPreferredBootDisplayMode(displayId)) {
1269*38e8c45fSAndroid Build Coastguard Worker             if (const auto modeId = snapshot.translateModeId(*hwcId)) {
1270*38e8c45fSAndroid Build Coastguard Worker                 info->preferredBootDisplayMode = ftl::to_underlying(*modeId);
1271*38e8c45fSAndroid Build Coastguard Worker             }
1272*38e8c45fSAndroid Build Coastguard Worker         }
1273*38e8c45fSAndroid Build Coastguard Worker     }
1274*38e8c45fSAndroid Build Coastguard Worker }
1275*38e8c45fSAndroid Build Coastguard Worker 
getDynamicDisplayInfoFromId(int64_t physicalDisplayId,ui::DynamicDisplayInfo * info)1276*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getDynamicDisplayInfoFromId(int64_t physicalDisplayId,
1277*38e8c45fSAndroid Build Coastguard Worker                                                      ui::DynamicDisplayInfo* info) {
1278*38e8c45fSAndroid Build Coastguard Worker     if (!info) {
1279*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
1280*38e8c45fSAndroid Build Coastguard Worker     }
1281*38e8c45fSAndroid Build Coastguard Worker 
1282*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
1283*38e8c45fSAndroid Build Coastguard Worker 
1284*38e8c45fSAndroid Build Coastguard Worker     const auto id_ =
1285*38e8c45fSAndroid Build Coastguard Worker             DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(physicalDisplayId));
1286*38e8c45fSAndroid Build Coastguard Worker     const auto displayOpt = mPhysicalDisplays.get(*id_).and_then(getDisplayDeviceAndSnapshot());
1287*38e8c45fSAndroid Build Coastguard Worker 
1288*38e8c45fSAndroid Build Coastguard Worker     if (!displayOpt) {
1289*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
1290*38e8c45fSAndroid Build Coastguard Worker     }
1291*38e8c45fSAndroid Build Coastguard Worker 
1292*38e8c45fSAndroid Build Coastguard Worker     const auto& [display, snapshotRef] = *displayOpt;
1293*38e8c45fSAndroid Build Coastguard Worker     getDynamicDisplayInfoInternal(info, display, snapshotRef.get());
1294*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1295*38e8c45fSAndroid Build Coastguard Worker }
1296*38e8c45fSAndroid Build Coastguard Worker 
getDynamicDisplayInfoFromToken(const sp<IBinder> & displayToken,ui::DynamicDisplayInfo * info)1297*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getDynamicDisplayInfoFromToken(const sp<IBinder>& displayToken,
1298*38e8c45fSAndroid Build Coastguard Worker                                                         ui::DynamicDisplayInfo* info) {
1299*38e8c45fSAndroid Build Coastguard Worker     if (!displayToken || !info) {
1300*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
1301*38e8c45fSAndroid Build Coastguard Worker     }
1302*38e8c45fSAndroid Build Coastguard Worker 
1303*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
1304*38e8c45fSAndroid Build Coastguard Worker 
1305*38e8c45fSAndroid Build Coastguard Worker     const auto displayOpt = ftl::find_if(mPhysicalDisplays, PhysicalDisplay::hasToken(displayToken))
1306*38e8c45fSAndroid Build Coastguard Worker                                     .transform(&ftl::to_mapped_ref<PhysicalDisplays>)
1307*38e8c45fSAndroid Build Coastguard Worker                                     .and_then(getDisplayDeviceAndSnapshot());
1308*38e8c45fSAndroid Build Coastguard Worker 
1309*38e8c45fSAndroid Build Coastguard Worker     if (!displayOpt) {
1310*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
1311*38e8c45fSAndroid Build Coastguard Worker     }
1312*38e8c45fSAndroid Build Coastguard Worker 
1313*38e8c45fSAndroid Build Coastguard Worker     const auto& [display, snapshotRef] = *displayOpt;
1314*38e8c45fSAndroid Build Coastguard Worker     getDynamicDisplayInfoInternal(info, display, snapshotRef.get());
1315*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1316*38e8c45fSAndroid Build Coastguard Worker }
1317*38e8c45fSAndroid Build Coastguard Worker 
getDisplayStats(const sp<IBinder> & displayToken,DisplayStatInfo * outStats)1318*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& displayToken,
1319*38e8c45fSAndroid Build Coastguard Worker                                          DisplayStatInfo* outStats) {
1320*38e8c45fSAndroid Build Coastguard Worker     if (!outStats) {
1321*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
1322*38e8c45fSAndroid Build Coastguard Worker     }
1323*38e8c45fSAndroid Build Coastguard Worker 
1324*38e8c45fSAndroid Build Coastguard Worker     // TODO: b/277364366 - Require a display token from clients and remove fallback to pacesetter.
1325*38e8c45fSAndroid Build Coastguard Worker     std::optional<PhysicalDisplayId> displayIdOpt;
1326*38e8c45fSAndroid Build Coastguard Worker     if (displayToken) {
1327*38e8c45fSAndroid Build Coastguard Worker         Mutex::Autolock lock(mStateLock);
1328*38e8c45fSAndroid Build Coastguard Worker         displayIdOpt = getPhysicalDisplayIdLocked(displayToken);
1329*38e8c45fSAndroid Build Coastguard Worker         if (!displayIdOpt) {
1330*38e8c45fSAndroid Build Coastguard Worker             ALOGW("%s: Invalid physical display token %p", __func__, displayToken.get());
1331*38e8c45fSAndroid Build Coastguard Worker             return NAME_NOT_FOUND;
1332*38e8c45fSAndroid Build Coastguard Worker         }
1333*38e8c45fSAndroid Build Coastguard Worker     }
1334*38e8c45fSAndroid Build Coastguard Worker 
1335*38e8c45fSAndroid Build Coastguard Worker     const auto schedule = mScheduler->getVsyncSchedule(displayIdOpt);
1336*38e8c45fSAndroid Build Coastguard Worker     if (!schedule) {
1337*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: Missing VSYNC schedule for display %s!", __func__,
1338*38e8c45fSAndroid Build Coastguard Worker               to_string(*displayIdOpt).c_str());
1339*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
1340*38e8c45fSAndroid Build Coastguard Worker     }
1341*38e8c45fSAndroid Build Coastguard Worker     outStats->vsyncTime = schedule->vsyncDeadlineAfter(TimePoint::now()).ns();
1342*38e8c45fSAndroid Build Coastguard Worker     outStats->vsyncPeriod = schedule->period().ns();
1343*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1344*38e8c45fSAndroid Build Coastguard Worker }
1345*38e8c45fSAndroid Build Coastguard Worker 
setDesiredMode(display::DisplayModeRequest && desiredMode)1346*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& desiredMode) {
1347*38e8c45fSAndroid Build Coastguard Worker     const auto mode = desiredMode.mode;
1348*38e8c45fSAndroid Build Coastguard Worker     const auto displayId = mode.modePtr->getPhysicalDisplayId();
1349*38e8c45fSAndroid Build Coastguard Worker 
1350*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str());
1351*38e8c45fSAndroid Build Coastguard Worker 
1352*38e8c45fSAndroid Build Coastguard Worker     const bool emitEvent = desiredMode.emitEvent;
1353*38e8c45fSAndroid Build Coastguard Worker 
1354*38e8c45fSAndroid Build Coastguard Worker     using DesiredModeAction = display::DisplayModeController::DesiredModeAction;
1355*38e8c45fSAndroid Build Coastguard Worker 
1356*38e8c45fSAndroid Build Coastguard Worker     switch (mDisplayModeController.setDesiredMode(displayId, std::move(desiredMode))) {
1357*38e8c45fSAndroid Build Coastguard Worker         case DesiredModeAction::InitiateDisplayModeSwitch: {
1358*38e8c45fSAndroid Build Coastguard Worker             const auto selectorPtr = mDisplayModeController.selectorPtrFor(displayId);
1359*38e8c45fSAndroid Build Coastguard Worker             if (!selectorPtr) break;
1360*38e8c45fSAndroid Build Coastguard Worker 
1361*38e8c45fSAndroid Build Coastguard Worker             const Fps renderRate = selectorPtr->getActiveMode().fps;
1362*38e8c45fSAndroid Build Coastguard Worker 
1363*38e8c45fSAndroid Build Coastguard Worker             // DisplayModeController::setDesiredMode updated the render rate, so inform Scheduler.
1364*38e8c45fSAndroid Build Coastguard Worker             mScheduler->setRenderRate(displayId, renderRate, true /* applyImmediately */);
1365*38e8c45fSAndroid Build Coastguard Worker 
1366*38e8c45fSAndroid Build Coastguard Worker             // Schedule a new frame to initiate the display mode switch.
1367*38e8c45fSAndroid Build Coastguard Worker             scheduleComposite(FrameHint::kNone);
1368*38e8c45fSAndroid Build Coastguard Worker 
1369*38e8c45fSAndroid Build Coastguard Worker             // Start receiving vsync samples now, so that we can detect a period
1370*38e8c45fSAndroid Build Coastguard Worker             // switch.
1371*38e8c45fSAndroid Build Coastguard Worker             mScheduler->resyncToHardwareVsync(displayId, true /* allowToEnable */,
1372*38e8c45fSAndroid Build Coastguard Worker                                               mode.modePtr.get());
1373*38e8c45fSAndroid Build Coastguard Worker 
1374*38e8c45fSAndroid Build Coastguard Worker             // As we called to set period, we will call to onRefreshRateChangeCompleted once
1375*38e8c45fSAndroid Build Coastguard Worker             // VsyncController model is locked.
1376*38e8c45fSAndroid Build Coastguard Worker             mScheduler->modulateVsync(displayId, &VsyncModulator::onRefreshRateChangeInitiated);
1377*38e8c45fSAndroid Build Coastguard Worker 
1378*38e8c45fSAndroid Build Coastguard Worker             mScheduler->updatePhaseConfiguration(displayId, mode.fps);
1379*38e8c45fSAndroid Build Coastguard Worker             mScheduler->setModeChangePending(true);
1380*38e8c45fSAndroid Build Coastguard Worker             break;
1381*38e8c45fSAndroid Build Coastguard Worker         }
1382*38e8c45fSAndroid Build Coastguard Worker         case DesiredModeAction::InitiateRenderRateSwitch:
1383*38e8c45fSAndroid Build Coastguard Worker             mScheduler->setRenderRate(displayId, mode.fps, /*applyImmediately*/ false);
1384*38e8c45fSAndroid Build Coastguard Worker             mScheduler->updatePhaseConfiguration(displayId, mode.fps);
1385*38e8c45fSAndroid Build Coastguard Worker 
1386*38e8c45fSAndroid Build Coastguard Worker             if (emitEvent) {
1387*38e8c45fSAndroid Build Coastguard Worker                 mScheduler->onDisplayModeChanged(displayId, mode,
1388*38e8c45fSAndroid Build Coastguard Worker                                                  /*clearContentRequirements*/ false);
1389*38e8c45fSAndroid Build Coastguard Worker             }
1390*38e8c45fSAndroid Build Coastguard Worker             break;
1391*38e8c45fSAndroid Build Coastguard Worker         case DesiredModeAction::None:
1392*38e8c45fSAndroid Build Coastguard Worker             break;
1393*38e8c45fSAndroid Build Coastguard Worker     }
1394*38e8c45fSAndroid Build Coastguard Worker }
1395*38e8c45fSAndroid Build Coastguard Worker 
setActiveModeFromBackdoor(const sp<display::DisplayToken> & displayToken,DisplayModeId modeId,Fps minFps,Fps maxFps)1396*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setActiveModeFromBackdoor(const sp<display::DisplayToken>& displayToken,
1397*38e8c45fSAndroid Build Coastguard Worker                                                    DisplayModeId modeId, Fps minFps, Fps maxFps) {
1398*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
1399*38e8c45fSAndroid Build Coastguard Worker 
1400*38e8c45fSAndroid Build Coastguard Worker     if (!displayToken) {
1401*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
1402*38e8c45fSAndroid Build Coastguard Worker     }
1403*38e8c45fSAndroid Build Coastguard Worker 
1404*38e8c45fSAndroid Build Coastguard Worker     const char* const whence = __func__;
1405*38e8c45fSAndroid Build Coastguard Worker     auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) -> status_t {
1406*38e8c45fSAndroid Build Coastguard Worker         const auto displayOpt =
1407*38e8c45fSAndroid Build Coastguard Worker                 FTL_FAKE_GUARD(mStateLock,
1408*38e8c45fSAndroid Build Coastguard Worker                                ftl::find_if(mPhysicalDisplays,
1409*38e8c45fSAndroid Build Coastguard Worker                                             PhysicalDisplay::hasToken(displayToken))
1410*38e8c45fSAndroid Build Coastguard Worker                                        .transform(&ftl::to_mapped_ref<PhysicalDisplays>)
1411*38e8c45fSAndroid Build Coastguard Worker                                        .and_then(getDisplayDeviceAndSnapshot()));
1412*38e8c45fSAndroid Build Coastguard Worker         if (!displayOpt) {
1413*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s: Invalid physical display token %p", whence, displayToken.get());
1414*38e8c45fSAndroid Build Coastguard Worker             return NAME_NOT_FOUND;
1415*38e8c45fSAndroid Build Coastguard Worker         }
1416*38e8c45fSAndroid Build Coastguard Worker 
1417*38e8c45fSAndroid Build Coastguard Worker         const auto& [display, snapshotRef] = *displayOpt;
1418*38e8c45fSAndroid Build Coastguard Worker         const auto& snapshot = snapshotRef.get();
1419*38e8c45fSAndroid Build Coastguard Worker 
1420*38e8c45fSAndroid Build Coastguard Worker         const auto fpsOpt = snapshot.displayModes().get(modeId).transform(
1421*38e8c45fSAndroid Build Coastguard Worker                 [](const DisplayModePtr& mode) { return mode->getPeakFps(); });
1422*38e8c45fSAndroid Build Coastguard Worker 
1423*38e8c45fSAndroid Build Coastguard Worker         if (!fpsOpt) {
1424*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s: Invalid mode %d for display %s", whence, ftl::to_underlying(modeId),
1425*38e8c45fSAndroid Build Coastguard Worker                   to_string(snapshot.displayId()).c_str());
1426*38e8c45fSAndroid Build Coastguard Worker             return BAD_VALUE;
1427*38e8c45fSAndroid Build Coastguard Worker         }
1428*38e8c45fSAndroid Build Coastguard Worker 
1429*38e8c45fSAndroid Build Coastguard Worker         const Fps fps = *fpsOpt;
1430*38e8c45fSAndroid Build Coastguard Worker         const FpsRange physical = {fps, fps};
1431*38e8c45fSAndroid Build Coastguard Worker         const FpsRange render = {minFps.isValid() ? minFps : fps, maxFps.isValid() ? maxFps : fps};
1432*38e8c45fSAndroid Build Coastguard Worker         const FpsRanges ranges = {physical, render};
1433*38e8c45fSAndroid Build Coastguard Worker 
1434*38e8c45fSAndroid Build Coastguard Worker         // Keep the old switching type.
1435*38e8c45fSAndroid Build Coastguard Worker         const bool allowGroupSwitching =
1436*38e8c45fSAndroid Build Coastguard Worker                 display->refreshRateSelector().getCurrentPolicy().allowGroupSwitching;
1437*38e8c45fSAndroid Build Coastguard Worker 
1438*38e8c45fSAndroid Build Coastguard Worker         const scheduler::RefreshRateSelector::DisplayManagerPolicy policy{modeId, ranges, ranges,
1439*38e8c45fSAndroid Build Coastguard Worker                                                                           allowGroupSwitching};
1440*38e8c45fSAndroid Build Coastguard Worker 
1441*38e8c45fSAndroid Build Coastguard Worker         return setDesiredDisplayModeSpecsInternal(display, policy);
1442*38e8c45fSAndroid Build Coastguard Worker     });
1443*38e8c45fSAndroid Build Coastguard Worker 
1444*38e8c45fSAndroid Build Coastguard Worker     return future.get();
1445*38e8c45fSAndroid Build Coastguard Worker }
1446*38e8c45fSAndroid Build Coastguard Worker 
finalizeDisplayModeChange(PhysicalDisplayId displayId)1447*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::finalizeDisplayModeChange(PhysicalDisplayId displayId) {
1448*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str());
1449*38e8c45fSAndroid Build Coastguard Worker 
1450*38e8c45fSAndroid Build Coastguard Worker     const auto pendingModeOpt = mDisplayModeController.getPendingMode(displayId);
1451*38e8c45fSAndroid Build Coastguard Worker     if (!pendingModeOpt) {
1452*38e8c45fSAndroid Build Coastguard Worker         // There is no pending mode change. This can happen if the active
1453*38e8c45fSAndroid Build Coastguard Worker         // display changed and the mode change happened on a different display.
1454*38e8c45fSAndroid Build Coastguard Worker         return;
1455*38e8c45fSAndroid Build Coastguard Worker     }
1456*38e8c45fSAndroid Build Coastguard Worker 
1457*38e8c45fSAndroid Build Coastguard Worker     const auto& activeMode = pendingModeOpt->mode;
1458*38e8c45fSAndroid Build Coastguard Worker 
1459*38e8c45fSAndroid Build Coastguard Worker     if (const auto oldResolution =
1460*38e8c45fSAndroid Build Coastguard Worker                 mDisplayModeController.getActiveMode(displayId).modePtr->getResolution();
1461*38e8c45fSAndroid Build Coastguard Worker         oldResolution != activeMode.modePtr->getResolution()) {
1462*38e8c45fSAndroid Build Coastguard Worker         auto& state = mCurrentState.displays.editValueFor(getPhysicalDisplayTokenLocked(displayId));
1463*38e8c45fSAndroid Build Coastguard Worker         // We need to generate new sequenceId in order to recreate the display (and this
1464*38e8c45fSAndroid Build Coastguard Worker         // way the framebuffer).
1465*38e8c45fSAndroid Build Coastguard Worker         state.sequenceId = DisplayDeviceState{}.sequenceId;
1466*38e8c45fSAndroid Build Coastguard Worker         state.physical->activeMode = activeMode.modePtr.get();
1467*38e8c45fSAndroid Build Coastguard Worker         processDisplayChangesLocked();
1468*38e8c45fSAndroid Build Coastguard Worker 
1469*38e8c45fSAndroid Build Coastguard Worker         // processDisplayChangesLocked will update all necessary components so we're done here.
1470*38e8c45fSAndroid Build Coastguard Worker         return;
1471*38e8c45fSAndroid Build Coastguard Worker     }
1472*38e8c45fSAndroid Build Coastguard Worker 
1473*38e8c45fSAndroid Build Coastguard Worker     mDisplayModeController.finalizeModeChange(displayId, activeMode.modePtr->getId(),
1474*38e8c45fSAndroid Build Coastguard Worker                                               activeMode.modePtr->getVsyncRate(), activeMode.fps);
1475*38e8c45fSAndroid Build Coastguard Worker 
1476*38e8c45fSAndroid Build Coastguard Worker     mScheduler->updatePhaseConfiguration(displayId, activeMode.fps);
1477*38e8c45fSAndroid Build Coastguard Worker 
1478*38e8c45fSAndroid Build Coastguard Worker     if (pendingModeOpt->emitEvent) {
1479*38e8c45fSAndroid Build Coastguard Worker         mScheduler->onDisplayModeChanged(displayId, activeMode, /*clearContentRequirements*/ true);
1480*38e8c45fSAndroid Build Coastguard Worker     }
1481*38e8c45fSAndroid Build Coastguard Worker }
1482*38e8c45fSAndroid Build Coastguard Worker 
dropModeRequest(PhysicalDisplayId displayId)1483*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dropModeRequest(PhysicalDisplayId displayId) {
1484*38e8c45fSAndroid Build Coastguard Worker     mDisplayModeController.clearDesiredMode(displayId);
1485*38e8c45fSAndroid Build Coastguard Worker     if (displayId == mActiveDisplayId) {
1486*38e8c45fSAndroid Build Coastguard Worker         // TODO(b/255635711): Check for pending mode changes on other displays.
1487*38e8c45fSAndroid Build Coastguard Worker         mScheduler->setModeChangePending(false);
1488*38e8c45fSAndroid Build Coastguard Worker     }
1489*38e8c45fSAndroid Build Coastguard Worker }
1490*38e8c45fSAndroid Build Coastguard Worker 
applyActiveMode(PhysicalDisplayId displayId)1491*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::applyActiveMode(PhysicalDisplayId displayId) {
1492*38e8c45fSAndroid Build Coastguard Worker     const auto activeModeOpt = mDisplayModeController.getDesiredMode(displayId);
1493*38e8c45fSAndroid Build Coastguard Worker     auto activeModePtr = activeModeOpt->mode.modePtr;
1494*38e8c45fSAndroid Build Coastguard Worker     const auto renderFps = activeModeOpt->mode.fps;
1495*38e8c45fSAndroid Build Coastguard Worker 
1496*38e8c45fSAndroid Build Coastguard Worker     dropModeRequest(displayId);
1497*38e8c45fSAndroid Build Coastguard Worker 
1498*38e8c45fSAndroid Build Coastguard Worker     constexpr bool kAllowToEnable = true;
1499*38e8c45fSAndroid Build Coastguard Worker     mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable, std::move(activeModePtr).take());
1500*38e8c45fSAndroid Build Coastguard Worker 
1501*38e8c45fSAndroid Build Coastguard Worker     mScheduler->setRenderRate(displayId, renderFps, /*applyImmediately*/ true);
1502*38e8c45fSAndroid Build Coastguard Worker     mScheduler->updatePhaseConfiguration(displayId, renderFps);
1503*38e8c45fSAndroid Build Coastguard Worker }
1504*38e8c45fSAndroid Build Coastguard Worker 
initiateDisplayModeChanges()1505*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::initiateDisplayModeChanges() {
1506*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
1507*38e8c45fSAndroid Build Coastguard Worker 
1508*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [displayId, physical] : mPhysicalDisplays) {
1509*38e8c45fSAndroid Build Coastguard Worker         auto desiredModeOpt = mDisplayModeController.getDesiredMode(displayId);
1510*38e8c45fSAndroid Build Coastguard Worker         if (!desiredModeOpt) {
1511*38e8c45fSAndroid Build Coastguard Worker             continue;
1512*38e8c45fSAndroid Build Coastguard Worker         }
1513*38e8c45fSAndroid Build Coastguard Worker 
1514*38e8c45fSAndroid Build Coastguard Worker         const auto desiredModeId = desiredModeOpt->mode.modePtr->getId();
1515*38e8c45fSAndroid Build Coastguard Worker         const auto displayModePtrOpt = physical.snapshot().displayModes().get(desiredModeId);
1516*38e8c45fSAndroid Build Coastguard Worker 
1517*38e8c45fSAndroid Build Coastguard Worker         if (!displayModePtrOpt) {
1518*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Desired display mode is no longer supported. Mode ID = %d",
1519*38e8c45fSAndroid Build Coastguard Worker                   ftl::to_underlying(desiredModeId));
1520*38e8c45fSAndroid Build Coastguard Worker             continue;
1521*38e8c45fSAndroid Build Coastguard Worker         }
1522*38e8c45fSAndroid Build Coastguard Worker 
1523*38e8c45fSAndroid Build Coastguard Worker         ALOGV("%s changing active mode to %d(%s) for display %s", __func__,
1524*38e8c45fSAndroid Build Coastguard Worker               ftl::to_underlying(desiredModeId),
1525*38e8c45fSAndroid Build Coastguard Worker               to_string(displayModePtrOpt->get()->getVsyncRate()).c_str(),
1526*38e8c45fSAndroid Build Coastguard Worker               to_string(displayId).c_str());
1527*38e8c45fSAndroid Build Coastguard Worker 
1528*38e8c45fSAndroid Build Coastguard Worker         if ((!FlagManager::getInstance().connected_display() || !desiredModeOpt->force) &&
1529*38e8c45fSAndroid Build Coastguard Worker             mDisplayModeController.getActiveMode(displayId) == desiredModeOpt->mode) {
1530*38e8c45fSAndroid Build Coastguard Worker             applyActiveMode(displayId);
1531*38e8c45fSAndroid Build Coastguard Worker             continue;
1532*38e8c45fSAndroid Build Coastguard Worker         }
1533*38e8c45fSAndroid Build Coastguard Worker 
1534*38e8c45fSAndroid Build Coastguard Worker         const auto selectorPtr = mDisplayModeController.selectorPtrFor(displayId);
1535*38e8c45fSAndroid Build Coastguard Worker 
1536*38e8c45fSAndroid Build Coastguard Worker         // Desired active mode was set, it is different than the mode currently in use, however
1537*38e8c45fSAndroid Build Coastguard Worker         // allowed modes might have changed by the time we process the refresh.
1538*38e8c45fSAndroid Build Coastguard Worker         // Make sure the desired mode is still allowed
1539*38e8c45fSAndroid Build Coastguard Worker         if (!selectorPtr->isModeAllowed(desiredModeOpt->mode)) {
1540*38e8c45fSAndroid Build Coastguard Worker             dropModeRequest(displayId);
1541*38e8c45fSAndroid Build Coastguard Worker             continue;
1542*38e8c45fSAndroid Build Coastguard Worker         }
1543*38e8c45fSAndroid Build Coastguard Worker 
1544*38e8c45fSAndroid Build Coastguard Worker         // TODO(b/142753666) use constrains
1545*38e8c45fSAndroid Build Coastguard Worker         hal::VsyncPeriodChangeConstraints constraints;
1546*38e8c45fSAndroid Build Coastguard Worker         constraints.desiredTimeNanos = systemTime();
1547*38e8c45fSAndroid Build Coastguard Worker         constraints.seamlessRequired = false;
1548*38e8c45fSAndroid Build Coastguard Worker         hal::VsyncPeriodChangeTimeline outTimeline;
1549*38e8c45fSAndroid Build Coastguard Worker 
1550*38e8c45fSAndroid Build Coastguard Worker         const auto error =
1551*38e8c45fSAndroid Build Coastguard Worker                 mDisplayModeController.initiateModeChange(displayId, std::move(*desiredModeOpt),
1552*38e8c45fSAndroid Build Coastguard Worker                                                           constraints, outTimeline);
1553*38e8c45fSAndroid Build Coastguard Worker         if (error != display::DisplayModeController::ModeChangeResult::Changed) {
1554*38e8c45fSAndroid Build Coastguard Worker             dropModeRequest(displayId);
1555*38e8c45fSAndroid Build Coastguard Worker             if (FlagManager::getInstance().display_config_error_hal() &&
1556*38e8c45fSAndroid Build Coastguard Worker                 error == display::DisplayModeController::ModeChangeResult::Rejected) {
1557*38e8c45fSAndroid Build Coastguard Worker                 mScheduler->onDisplayModeRejected(displayId, desiredModeId);
1558*38e8c45fSAndroid Build Coastguard Worker             }
1559*38e8c45fSAndroid Build Coastguard Worker             continue;
1560*38e8c45fSAndroid Build Coastguard Worker         }
1561*38e8c45fSAndroid Build Coastguard Worker 
1562*38e8c45fSAndroid Build Coastguard Worker         selectorPtr->onModeChangeInitiated();
1563*38e8c45fSAndroid Build Coastguard Worker         mScheduler->onNewVsyncPeriodChangeTimeline(outTimeline);
1564*38e8c45fSAndroid Build Coastguard Worker 
1565*38e8c45fSAndroid Build Coastguard Worker         if (outTimeline.refreshRequired) {
1566*38e8c45fSAndroid Build Coastguard Worker             scheduleComposite(FrameHint::kNone);
1567*38e8c45fSAndroid Build Coastguard Worker         } else {
1568*38e8c45fSAndroid Build Coastguard Worker             // HWC has requested to apply the mode change immediately rather than on the next frame.
1569*38e8c45fSAndroid Build Coastguard Worker             finalizeDisplayModeChange(displayId);
1570*38e8c45fSAndroid Build Coastguard Worker 
1571*38e8c45fSAndroid Build Coastguard Worker             const auto desiredModeOpt = mDisplayModeController.getDesiredMode(displayId);
1572*38e8c45fSAndroid Build Coastguard Worker             if (desiredModeOpt &&
1573*38e8c45fSAndroid Build Coastguard Worker                 mDisplayModeController.getActiveMode(displayId) == desiredModeOpt->mode) {
1574*38e8c45fSAndroid Build Coastguard Worker                 applyActiveMode(displayId);
1575*38e8c45fSAndroid Build Coastguard Worker             }
1576*38e8c45fSAndroid Build Coastguard Worker         }
1577*38e8c45fSAndroid Build Coastguard Worker     }
1578*38e8c45fSAndroid Build Coastguard Worker }
1579*38e8c45fSAndroid Build Coastguard Worker 
disableExpensiveRendering()1580*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::disableExpensiveRendering() {
1581*38e8c45fSAndroid Build Coastguard Worker     const char* const whence = __func__;
1582*38e8c45fSAndroid Build Coastguard Worker     auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) {
1583*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_NAME(whence);
1584*38e8c45fSAndroid Build Coastguard Worker         if (mPowerAdvisor->isUsingExpensiveRendering()) {
1585*38e8c45fSAndroid Build Coastguard Worker             for (const auto& [_, display] : mDisplays) {
1586*38e8c45fSAndroid Build Coastguard Worker                 constexpr bool kDisable = false;
1587*38e8c45fSAndroid Build Coastguard Worker                 mPowerAdvisor->setExpensiveRenderingExpected(display->getId(), kDisable);
1588*38e8c45fSAndroid Build Coastguard Worker             }
1589*38e8c45fSAndroid Build Coastguard Worker         }
1590*38e8c45fSAndroid Build Coastguard Worker     });
1591*38e8c45fSAndroid Build Coastguard Worker 
1592*38e8c45fSAndroid Build Coastguard Worker     future.wait();
1593*38e8c45fSAndroid Build Coastguard Worker }
1594*38e8c45fSAndroid Build Coastguard Worker 
getDisplayNativePrimaries(const sp<IBinder> & displayToken,ui::DisplayPrimaries & primaries)1595*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getDisplayNativePrimaries(const sp<IBinder>& displayToken,
1596*38e8c45fSAndroid Build Coastguard Worker                                                    ui::DisplayPrimaries& primaries) {
1597*38e8c45fSAndroid Build Coastguard Worker     if (!displayToken) {
1598*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
1599*38e8c45fSAndroid Build Coastguard Worker     }
1600*38e8c45fSAndroid Build Coastguard Worker 
1601*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
1602*38e8c45fSAndroid Build Coastguard Worker 
1603*38e8c45fSAndroid Build Coastguard Worker     const auto display = ftl::find_if(mPhysicalDisplays, PhysicalDisplay::hasToken(displayToken))
1604*38e8c45fSAndroid Build Coastguard Worker                                  .transform(&ftl::to_mapped_ref<PhysicalDisplays>);
1605*38e8c45fSAndroid Build Coastguard Worker     if (!display) {
1606*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
1607*38e8c45fSAndroid Build Coastguard Worker     }
1608*38e8c45fSAndroid Build Coastguard Worker 
1609*38e8c45fSAndroid Build Coastguard Worker     if (!display.transform(&PhysicalDisplay::isInternal).value()) {
1610*38e8c45fSAndroid Build Coastguard Worker         return INVALID_OPERATION;
1611*38e8c45fSAndroid Build Coastguard Worker     }
1612*38e8c45fSAndroid Build Coastguard Worker 
1613*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/229846990): For now, assume that all internal displays have the same primaries.
1614*38e8c45fSAndroid Build Coastguard Worker     primaries = mInternalDisplayPrimaries;
1615*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1616*38e8c45fSAndroid Build Coastguard Worker }
1617*38e8c45fSAndroid Build Coastguard Worker 
setActiveColorMode(const sp<IBinder> & displayToken,ui::ColorMode mode)1618*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& displayToken, ui::ColorMode mode) {
1619*38e8c45fSAndroid Build Coastguard Worker     if (!displayToken) {
1620*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
1621*38e8c45fSAndroid Build Coastguard Worker     }
1622*38e8c45fSAndroid Build Coastguard Worker 
1623*38e8c45fSAndroid Build Coastguard Worker     const char* const whence = __func__;
1624*38e8c45fSAndroid Build Coastguard Worker     auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) -> status_t {
1625*38e8c45fSAndroid Build Coastguard Worker         const auto displayOpt =
1626*38e8c45fSAndroid Build Coastguard Worker                 ftl::find_if(mPhysicalDisplays, PhysicalDisplay::hasToken(displayToken))
1627*38e8c45fSAndroid Build Coastguard Worker                         .transform(&ftl::to_mapped_ref<PhysicalDisplays>)
1628*38e8c45fSAndroid Build Coastguard Worker                         .and_then(getDisplayDeviceAndSnapshot());
1629*38e8c45fSAndroid Build Coastguard Worker 
1630*38e8c45fSAndroid Build Coastguard Worker         if (!displayOpt) {
1631*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s: Invalid physical display token %p", whence, displayToken.get());
1632*38e8c45fSAndroid Build Coastguard Worker             return NAME_NOT_FOUND;
1633*38e8c45fSAndroid Build Coastguard Worker         }
1634*38e8c45fSAndroid Build Coastguard Worker 
1635*38e8c45fSAndroid Build Coastguard Worker         const auto& [display, snapshotRef] = *displayOpt;
1636*38e8c45fSAndroid Build Coastguard Worker         const auto& snapshot = snapshotRef.get();
1637*38e8c45fSAndroid Build Coastguard Worker 
1638*38e8c45fSAndroid Build Coastguard Worker         const auto modes = snapshot.filterColorModes(mSupportsWideColor);
1639*38e8c45fSAndroid Build Coastguard Worker         const bool exists = std::find(modes.begin(), modes.end(), mode) != modes.end();
1640*38e8c45fSAndroid Build Coastguard Worker 
1641*38e8c45fSAndroid Build Coastguard Worker         if (mode < ui::ColorMode::NATIVE || !exists) {
1642*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s: Invalid color mode %s (%d) for display %s", whence,
1643*38e8c45fSAndroid Build Coastguard Worker                   decodeColorMode(mode).c_str(), mode, to_string(snapshot.displayId()).c_str());
1644*38e8c45fSAndroid Build Coastguard Worker             return BAD_VALUE;
1645*38e8c45fSAndroid Build Coastguard Worker         }
1646*38e8c45fSAndroid Build Coastguard Worker 
1647*38e8c45fSAndroid Build Coastguard Worker         display->getCompositionDisplay()->setColorProfile(
1648*38e8c45fSAndroid Build Coastguard Worker                 {mode, Dataspace::UNKNOWN, RenderIntent::COLORIMETRIC});
1649*38e8c45fSAndroid Build Coastguard Worker 
1650*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
1651*38e8c45fSAndroid Build Coastguard Worker     });
1652*38e8c45fSAndroid Build Coastguard Worker 
1653*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/195698395): Propagate error.
1654*38e8c45fSAndroid Build Coastguard Worker     future.wait();
1655*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1656*38e8c45fSAndroid Build Coastguard Worker }
1657*38e8c45fSAndroid Build Coastguard Worker 
getBootDisplayModeSupport(bool * outSupport) const1658*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getBootDisplayModeSupport(bool* outSupport) const {
1659*38e8c45fSAndroid Build Coastguard Worker     auto future = mScheduler->schedule(
1660*38e8c45fSAndroid Build Coastguard Worker             [this] { return getHwComposer().hasCapability(Capability::BOOT_DISPLAY_CONFIG); });
1661*38e8c45fSAndroid Build Coastguard Worker 
1662*38e8c45fSAndroid Build Coastguard Worker     *outSupport = future.get();
1663*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1664*38e8c45fSAndroid Build Coastguard Worker }
1665*38e8c45fSAndroid Build Coastguard Worker 
getOverlaySupport(gui::OverlayProperties * outProperties) const1666*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getOverlaySupport(gui::OverlayProperties* outProperties) const {
1667*38e8c45fSAndroid Build Coastguard Worker     const auto& aidlProperties = getHwComposer().getOverlaySupport();
1668*38e8c45fSAndroid Build Coastguard Worker     // convert aidl OverlayProperties to gui::OverlayProperties
1669*38e8c45fSAndroid Build Coastguard Worker     outProperties->combinations.reserve(aidlProperties.combinations.size());
1670*38e8c45fSAndroid Build Coastguard Worker     for (const auto& combination : aidlProperties.combinations) {
1671*38e8c45fSAndroid Build Coastguard Worker         std::vector<int32_t> pixelFormats;
1672*38e8c45fSAndroid Build Coastguard Worker         pixelFormats.reserve(combination.pixelFormats.size());
1673*38e8c45fSAndroid Build Coastguard Worker         std::transform(combination.pixelFormats.cbegin(), combination.pixelFormats.cend(),
1674*38e8c45fSAndroid Build Coastguard Worker                        std::back_inserter(pixelFormats),
1675*38e8c45fSAndroid Build Coastguard Worker                        [](const auto& val) { return static_cast<int32_t>(val); });
1676*38e8c45fSAndroid Build Coastguard Worker         std::vector<int32_t> standards;
1677*38e8c45fSAndroid Build Coastguard Worker         standards.reserve(combination.standards.size());
1678*38e8c45fSAndroid Build Coastguard Worker         std::transform(combination.standards.cbegin(), combination.standards.cend(),
1679*38e8c45fSAndroid Build Coastguard Worker                        std::back_inserter(standards),
1680*38e8c45fSAndroid Build Coastguard Worker                        [](const auto& val) { return static_cast<int32_t>(val); });
1681*38e8c45fSAndroid Build Coastguard Worker         std::vector<int32_t> transfers;
1682*38e8c45fSAndroid Build Coastguard Worker         transfers.reserve(combination.transfers.size());
1683*38e8c45fSAndroid Build Coastguard Worker         std::transform(combination.transfers.cbegin(), combination.transfers.cend(),
1684*38e8c45fSAndroid Build Coastguard Worker                        std::back_inserter(transfers),
1685*38e8c45fSAndroid Build Coastguard Worker                        [](const auto& val) { return static_cast<int32_t>(val); });
1686*38e8c45fSAndroid Build Coastguard Worker         std::vector<int32_t> ranges;
1687*38e8c45fSAndroid Build Coastguard Worker         ranges.reserve(combination.ranges.size());
1688*38e8c45fSAndroid Build Coastguard Worker         std::transform(combination.ranges.cbegin(), combination.ranges.cend(),
1689*38e8c45fSAndroid Build Coastguard Worker                        std::back_inserter(ranges),
1690*38e8c45fSAndroid Build Coastguard Worker                        [](const auto& val) { return static_cast<int32_t>(val); });
1691*38e8c45fSAndroid Build Coastguard Worker         gui::OverlayProperties::SupportedBufferCombinations outCombination;
1692*38e8c45fSAndroid Build Coastguard Worker         outCombination.pixelFormats = std::move(pixelFormats);
1693*38e8c45fSAndroid Build Coastguard Worker         outCombination.standards = std::move(standards);
1694*38e8c45fSAndroid Build Coastguard Worker         outCombination.transfers = std::move(transfers);
1695*38e8c45fSAndroid Build Coastguard Worker         outCombination.ranges = std::move(ranges);
1696*38e8c45fSAndroid Build Coastguard Worker         outProperties->combinations.emplace_back(outCombination);
1697*38e8c45fSAndroid Build Coastguard Worker     }
1698*38e8c45fSAndroid Build Coastguard Worker     outProperties->supportMixedColorSpaces = aidlProperties.supportMixedColorSpaces;
1699*38e8c45fSAndroid Build Coastguard Worker     if (aidlProperties.lutProperties) {
1700*38e8c45fSAndroid Build Coastguard Worker         std::vector<gui::LutProperties> outLutProperties;
1701*38e8c45fSAndroid Build Coastguard Worker         for (auto properties : *aidlProperties.lutProperties) {
1702*38e8c45fSAndroid Build Coastguard Worker             if (!properties) {
1703*38e8c45fSAndroid Build Coastguard Worker                 gui::LutProperties currentProperties;
1704*38e8c45fSAndroid Build Coastguard Worker                 currentProperties.dimension =
1705*38e8c45fSAndroid Build Coastguard Worker                         static_cast<gui::LutProperties::Dimension>(properties->dimension);
1706*38e8c45fSAndroid Build Coastguard Worker                 currentProperties.size = properties->size;
1707*38e8c45fSAndroid Build Coastguard Worker                 currentProperties.samplingKeys.reserve(properties->samplingKeys.size());
1708*38e8c45fSAndroid Build Coastguard Worker                 std::transform(properties->samplingKeys.cbegin(), properties->samplingKeys.cend(),
1709*38e8c45fSAndroid Build Coastguard Worker                                std::back_inserter(currentProperties.samplingKeys),
1710*38e8c45fSAndroid Build Coastguard Worker                                [](const auto& val) {
1711*38e8c45fSAndroid Build Coastguard Worker                                    return static_cast<gui::LutProperties::SamplingKey>(val);
1712*38e8c45fSAndroid Build Coastguard Worker                                });
1713*38e8c45fSAndroid Build Coastguard Worker                 outLutProperties.push_back(std::move(currentProperties));
1714*38e8c45fSAndroid Build Coastguard Worker             }
1715*38e8c45fSAndroid Build Coastguard Worker         }
1716*38e8c45fSAndroid Build Coastguard Worker         outProperties->lutProperties.emplace(outLutProperties.begin(), outLutProperties.end());
1717*38e8c45fSAndroid Build Coastguard Worker     }
1718*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1719*38e8c45fSAndroid Build Coastguard Worker }
1720*38e8c45fSAndroid Build Coastguard Worker 
setBootDisplayMode(const sp<display::DisplayToken> & displayToken,DisplayModeId modeId)1721*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setBootDisplayMode(const sp<display::DisplayToken>& displayToken,
1722*38e8c45fSAndroid Build Coastguard Worker                                             DisplayModeId modeId) {
1723*38e8c45fSAndroid Build Coastguard Worker     const char* const whence = __func__;
1724*38e8c45fSAndroid Build Coastguard Worker     auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) -> status_t {
1725*38e8c45fSAndroid Build Coastguard Worker         const auto snapshotOpt =
1726*38e8c45fSAndroid Build Coastguard Worker                 ftl::find_if(mPhysicalDisplays, PhysicalDisplay::hasToken(displayToken))
1727*38e8c45fSAndroid Build Coastguard Worker                         .transform(&ftl::to_mapped_ref<PhysicalDisplays>)
1728*38e8c45fSAndroid Build Coastguard Worker                         .transform(&PhysicalDisplay::snapshotRef);
1729*38e8c45fSAndroid Build Coastguard Worker 
1730*38e8c45fSAndroid Build Coastguard Worker         if (!snapshotOpt) {
1731*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s: Invalid physical display token %p", whence, displayToken.get());
1732*38e8c45fSAndroid Build Coastguard Worker             return NAME_NOT_FOUND;
1733*38e8c45fSAndroid Build Coastguard Worker         }
1734*38e8c45fSAndroid Build Coastguard Worker 
1735*38e8c45fSAndroid Build Coastguard Worker         const auto& snapshot = snapshotOpt->get();
1736*38e8c45fSAndroid Build Coastguard Worker         const auto hwcIdOpt = snapshot.displayModes().get(modeId).transform(
1737*38e8c45fSAndroid Build Coastguard Worker                 [](const DisplayModePtr& mode) { return mode->getHwcId(); });
1738*38e8c45fSAndroid Build Coastguard Worker 
1739*38e8c45fSAndroid Build Coastguard Worker         if (!hwcIdOpt) {
1740*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s: Invalid mode %d for display %s", whence, ftl::to_underlying(modeId),
1741*38e8c45fSAndroid Build Coastguard Worker                   to_string(snapshot.displayId()).c_str());
1742*38e8c45fSAndroid Build Coastguard Worker             return BAD_VALUE;
1743*38e8c45fSAndroid Build Coastguard Worker         }
1744*38e8c45fSAndroid Build Coastguard Worker 
1745*38e8c45fSAndroid Build Coastguard Worker         return getHwComposer().setBootDisplayMode(snapshot.displayId(), *hwcIdOpt);
1746*38e8c45fSAndroid Build Coastguard Worker     });
1747*38e8c45fSAndroid Build Coastguard Worker     return future.get();
1748*38e8c45fSAndroid Build Coastguard Worker }
1749*38e8c45fSAndroid Build Coastguard Worker 
clearBootDisplayMode(const sp<IBinder> & displayToken)1750*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::clearBootDisplayMode(const sp<IBinder>& displayToken) {
1751*38e8c45fSAndroid Build Coastguard Worker     const char* const whence = __func__;
1752*38e8c45fSAndroid Build Coastguard Worker     auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) -> status_t {
1753*38e8c45fSAndroid Build Coastguard Worker         if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
1754*38e8c45fSAndroid Build Coastguard Worker             return getHwComposer().clearBootDisplayMode(*displayId);
1755*38e8c45fSAndroid Build Coastguard Worker         } else {
1756*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s: Invalid display token %p", whence, displayToken.get());
1757*38e8c45fSAndroid Build Coastguard Worker             return BAD_VALUE;
1758*38e8c45fSAndroid Build Coastguard Worker         }
1759*38e8c45fSAndroid Build Coastguard Worker     });
1760*38e8c45fSAndroid Build Coastguard Worker     return future.get();
1761*38e8c45fSAndroid Build Coastguard Worker }
1762*38e8c45fSAndroid Build Coastguard Worker 
getHdrConversionCapabilities(std::vector<gui::HdrConversionCapability> * hdrConversionCapabilities) const1763*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getHdrConversionCapabilities(
1764*38e8c45fSAndroid Build Coastguard Worker         std::vector<gui::HdrConversionCapability>* hdrConversionCapabilities) const {
1765*38e8c45fSAndroid Build Coastguard Worker     bool hdrOutputConversionSupport;
1766*38e8c45fSAndroid Build Coastguard Worker     getHdrOutputConversionSupport(&hdrOutputConversionSupport);
1767*38e8c45fSAndroid Build Coastguard Worker     if (hdrOutputConversionSupport == false) {
1768*38e8c45fSAndroid Build Coastguard Worker         ALOGE("hdrOutputConversion is not supported by this device.");
1769*38e8c45fSAndroid Build Coastguard Worker         return INVALID_OPERATION;
1770*38e8c45fSAndroid Build Coastguard Worker     }
1771*38e8c45fSAndroid Build Coastguard Worker     const auto aidlConversionCapability = getHwComposer().getHdrConversionCapabilities();
1772*38e8c45fSAndroid Build Coastguard Worker     for (auto capability : aidlConversionCapability) {
1773*38e8c45fSAndroid Build Coastguard Worker         gui::HdrConversionCapability tempCapability;
1774*38e8c45fSAndroid Build Coastguard Worker         tempCapability.sourceType = static_cast<int>(capability.sourceType);
1775*38e8c45fSAndroid Build Coastguard Worker         tempCapability.outputType = static_cast<int>(capability.outputType);
1776*38e8c45fSAndroid Build Coastguard Worker         tempCapability.addsLatency = capability.addsLatency;
1777*38e8c45fSAndroid Build Coastguard Worker         hdrConversionCapabilities->push_back(tempCapability);
1778*38e8c45fSAndroid Build Coastguard Worker     }
1779*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1780*38e8c45fSAndroid Build Coastguard Worker }
1781*38e8c45fSAndroid Build Coastguard Worker 
setHdrConversionStrategy(const gui::HdrConversionStrategy & hdrConversionStrategy,int32_t * outPreferredHdrOutputType)1782*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setHdrConversionStrategy(
1783*38e8c45fSAndroid Build Coastguard Worker         const gui::HdrConversionStrategy& hdrConversionStrategy,
1784*38e8c45fSAndroid Build Coastguard Worker         int32_t* outPreferredHdrOutputType) {
1785*38e8c45fSAndroid Build Coastguard Worker     bool hdrOutputConversionSupport;
1786*38e8c45fSAndroid Build Coastguard Worker     getHdrOutputConversionSupport(&hdrOutputConversionSupport);
1787*38e8c45fSAndroid Build Coastguard Worker     if (hdrOutputConversionSupport == false) {
1788*38e8c45fSAndroid Build Coastguard Worker         ALOGE("hdrOutputConversion is not supported by this device.");
1789*38e8c45fSAndroid Build Coastguard Worker         return INVALID_OPERATION;
1790*38e8c45fSAndroid Build Coastguard Worker     }
1791*38e8c45fSAndroid Build Coastguard Worker     auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) mutable -> status_t {
1792*38e8c45fSAndroid Build Coastguard Worker         using AidlHdrConversionStrategy =
1793*38e8c45fSAndroid Build Coastguard Worker                 aidl::android::hardware::graphics::common::HdrConversionStrategy;
1794*38e8c45fSAndroid Build Coastguard Worker         using GuiHdrConversionStrategyTag = gui::HdrConversionStrategy::Tag;
1795*38e8c45fSAndroid Build Coastguard Worker         AidlHdrConversionStrategy aidlConversionStrategy;
1796*38e8c45fSAndroid Build Coastguard Worker         status_t status;
1797*38e8c45fSAndroid Build Coastguard Worker         aidl::android::hardware::graphics::common::Hdr aidlPreferredHdrOutputType;
1798*38e8c45fSAndroid Build Coastguard Worker         switch (hdrConversionStrategy.getTag()) {
1799*38e8c45fSAndroid Build Coastguard Worker             case GuiHdrConversionStrategyTag::passthrough: {
1800*38e8c45fSAndroid Build Coastguard Worker                 aidlConversionStrategy.set<AidlHdrConversionStrategy::Tag::passthrough>(
1801*38e8c45fSAndroid Build Coastguard Worker                         hdrConversionStrategy.get<GuiHdrConversionStrategyTag::passthrough>());
1802*38e8c45fSAndroid Build Coastguard Worker                 status = getHwComposer().setHdrConversionStrategy(aidlConversionStrategy,
1803*38e8c45fSAndroid Build Coastguard Worker                                                                   &aidlPreferredHdrOutputType);
1804*38e8c45fSAndroid Build Coastguard Worker                 *outPreferredHdrOutputType = static_cast<int32_t>(aidlPreferredHdrOutputType);
1805*38e8c45fSAndroid Build Coastguard Worker                 return status;
1806*38e8c45fSAndroid Build Coastguard Worker             }
1807*38e8c45fSAndroid Build Coastguard Worker             case GuiHdrConversionStrategyTag::autoAllowedHdrTypes: {
1808*38e8c45fSAndroid Build Coastguard Worker                 auto autoHdrTypes =
1809*38e8c45fSAndroid Build Coastguard Worker                         hdrConversionStrategy
1810*38e8c45fSAndroid Build Coastguard Worker                                 .get<GuiHdrConversionStrategyTag::autoAllowedHdrTypes>();
1811*38e8c45fSAndroid Build Coastguard Worker                 std::vector<aidl::android::hardware::graphics::common::Hdr> aidlAutoHdrTypes;
1812*38e8c45fSAndroid Build Coastguard Worker                 for (auto type : autoHdrTypes) {
1813*38e8c45fSAndroid Build Coastguard Worker                     aidlAutoHdrTypes.push_back(
1814*38e8c45fSAndroid Build Coastguard Worker                             static_cast<aidl::android::hardware::graphics::common::Hdr>(type));
1815*38e8c45fSAndroid Build Coastguard Worker                 }
1816*38e8c45fSAndroid Build Coastguard Worker                 aidlConversionStrategy.set<AidlHdrConversionStrategy::Tag::autoAllowedHdrTypes>(
1817*38e8c45fSAndroid Build Coastguard Worker                         aidlAutoHdrTypes);
1818*38e8c45fSAndroid Build Coastguard Worker                 status = getHwComposer().setHdrConversionStrategy(aidlConversionStrategy,
1819*38e8c45fSAndroid Build Coastguard Worker                                                                   &aidlPreferredHdrOutputType);
1820*38e8c45fSAndroid Build Coastguard Worker                 *outPreferredHdrOutputType = static_cast<int32_t>(aidlPreferredHdrOutputType);
1821*38e8c45fSAndroid Build Coastguard Worker                 return status;
1822*38e8c45fSAndroid Build Coastguard Worker             }
1823*38e8c45fSAndroid Build Coastguard Worker             case GuiHdrConversionStrategyTag::forceHdrConversion: {
1824*38e8c45fSAndroid Build Coastguard Worker                 auto forceHdrConversion =
1825*38e8c45fSAndroid Build Coastguard Worker                         hdrConversionStrategy
1826*38e8c45fSAndroid Build Coastguard Worker                                 .get<GuiHdrConversionStrategyTag::forceHdrConversion>();
1827*38e8c45fSAndroid Build Coastguard Worker                 aidlConversionStrategy.set<AidlHdrConversionStrategy::Tag::forceHdrConversion>(
1828*38e8c45fSAndroid Build Coastguard Worker                         static_cast<aidl::android::hardware::graphics::common::Hdr>(
1829*38e8c45fSAndroid Build Coastguard Worker                                 forceHdrConversion));
1830*38e8c45fSAndroid Build Coastguard Worker                 status = getHwComposer().setHdrConversionStrategy(aidlConversionStrategy,
1831*38e8c45fSAndroid Build Coastguard Worker                                                                   &aidlPreferredHdrOutputType);
1832*38e8c45fSAndroid Build Coastguard Worker                 *outPreferredHdrOutputType = static_cast<int32_t>(aidlPreferredHdrOutputType);
1833*38e8c45fSAndroid Build Coastguard Worker                 return status;
1834*38e8c45fSAndroid Build Coastguard Worker             }
1835*38e8c45fSAndroid Build Coastguard Worker         }
1836*38e8c45fSAndroid Build Coastguard Worker     });
1837*38e8c45fSAndroid Build Coastguard Worker     return future.get();
1838*38e8c45fSAndroid Build Coastguard Worker }
1839*38e8c45fSAndroid Build Coastguard Worker 
getHdrOutputConversionSupport(bool * outSupport) const1840*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getHdrOutputConversionSupport(bool* outSupport) const {
1841*38e8c45fSAndroid Build Coastguard Worker     auto future = mScheduler->schedule([this] {
1842*38e8c45fSAndroid Build Coastguard Worker         return getHwComposer().hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG);
1843*38e8c45fSAndroid Build Coastguard Worker     });
1844*38e8c45fSAndroid Build Coastguard Worker 
1845*38e8c45fSAndroid Build Coastguard Worker     *outSupport = future.get();
1846*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1847*38e8c45fSAndroid Build Coastguard Worker }
1848*38e8c45fSAndroid Build Coastguard Worker 
setAutoLowLatencyMode(const sp<IBinder> & displayToken,bool on)1849*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) {
1850*38e8c45fSAndroid Build Coastguard Worker     const char* const whence = __func__;
1851*38e8c45fSAndroid Build Coastguard Worker     static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) {
1852*38e8c45fSAndroid Build Coastguard Worker         if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
1853*38e8c45fSAndroid Build Coastguard Worker             getHwComposer().setAutoLowLatencyMode(*displayId, on);
1854*38e8c45fSAndroid Build Coastguard Worker         } else {
1855*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s: Invalid display token %p", whence, displayToken.get());
1856*38e8c45fSAndroid Build Coastguard Worker         }
1857*38e8c45fSAndroid Build Coastguard Worker     }));
1858*38e8c45fSAndroid Build Coastguard Worker }
1859*38e8c45fSAndroid Build Coastguard Worker 
setGameContentType(const sp<IBinder> & displayToken,bool on)1860*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::setGameContentType(const sp<IBinder>& displayToken, bool on) {
1861*38e8c45fSAndroid Build Coastguard Worker     const char* const whence = __func__;
1862*38e8c45fSAndroid Build Coastguard Worker     static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) {
1863*38e8c45fSAndroid Build Coastguard Worker         if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
1864*38e8c45fSAndroid Build Coastguard Worker             const auto type = on ? hal::ContentType::GAME : hal::ContentType::NONE;
1865*38e8c45fSAndroid Build Coastguard Worker             getHwComposer().setContentType(*displayId, type);
1866*38e8c45fSAndroid Build Coastguard Worker         } else {
1867*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s: Invalid display token %p", whence, displayToken.get());
1868*38e8c45fSAndroid Build Coastguard Worker         }
1869*38e8c45fSAndroid Build Coastguard Worker     }));
1870*38e8c45fSAndroid Build Coastguard Worker }
1871*38e8c45fSAndroid Build Coastguard Worker 
getMaxLayerPictureProfiles(const sp<IBinder> & displayToken,int32_t * outMaxProfiles)1872*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getMaxLayerPictureProfiles(const sp<IBinder>& displayToken,
1873*38e8c45fSAndroid Build Coastguard Worker                                                     int32_t* outMaxProfiles) {
1874*38e8c45fSAndroid Build Coastguard Worker     const char* const whence = __func__;
1875*38e8c45fSAndroid Build Coastguard Worker     auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) {
1876*38e8c45fSAndroid Build Coastguard Worker         const ssize_t index = mCurrentState.displays.indexOfKey(displayToken);
1877*38e8c45fSAndroid Build Coastguard Worker         if (index < 0) {
1878*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s: Invalid display token %p", whence, displayToken.get());
1879*38e8c45fSAndroid Build Coastguard Worker             return 0;
1880*38e8c45fSAndroid Build Coastguard Worker         }
1881*38e8c45fSAndroid Build Coastguard Worker         const DisplayDeviceState& state = mCurrentState.displays.valueAt(index);
1882*38e8c45fSAndroid Build Coastguard Worker         return state.maxLayerPictureProfiles > 0 ? state.maxLayerPictureProfiles
1883*38e8c45fSAndroid Build Coastguard Worker                 : state.hasPictureProcessing     ? 1
1884*38e8c45fSAndroid Build Coastguard Worker                                                  : 0;
1885*38e8c45fSAndroid Build Coastguard Worker     });
1886*38e8c45fSAndroid Build Coastguard Worker     *outMaxProfiles = future.get();
1887*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1888*38e8c45fSAndroid Build Coastguard Worker }
1889*38e8c45fSAndroid Build Coastguard Worker 
overrideHdrTypes(const sp<IBinder> & displayToken,const std::vector<ui::Hdr> & hdrTypes)1890*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::overrideHdrTypes(const sp<IBinder>& displayToken,
1891*38e8c45fSAndroid Build Coastguard Worker                                           const std::vector<ui::Hdr>& hdrTypes) {
1892*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
1893*38e8c45fSAndroid Build Coastguard Worker 
1894*38e8c45fSAndroid Build Coastguard Worker     auto display = getDisplayDeviceLocked(displayToken);
1895*38e8c45fSAndroid Build Coastguard Worker     if (!display) {
1896*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: Invalid display token %p", __func__, displayToken.get());
1897*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
1898*38e8c45fSAndroid Build Coastguard Worker     }
1899*38e8c45fSAndroid Build Coastguard Worker 
1900*38e8c45fSAndroid Build Coastguard Worker     display->overrideHdrTypes(hdrTypes);
1901*38e8c45fSAndroid Build Coastguard Worker     mScheduler->dispatchHotplug(display->getPhysicalId(), scheduler::Scheduler::Hotplug::Connected);
1902*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1903*38e8c45fSAndroid Build Coastguard Worker }
1904*38e8c45fSAndroid Build Coastguard Worker 
onPullAtom(const int32_t atomId,std::vector<uint8_t> * pulledData,bool * success)1905*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::onPullAtom(const int32_t atomId, std::vector<uint8_t>* pulledData,
1906*38e8c45fSAndroid Build Coastguard Worker                                     bool* success) {
1907*38e8c45fSAndroid Build Coastguard Worker     *success = mTimeStats->onPullAtom(atomId, pulledData);
1908*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1909*38e8c45fSAndroid Build Coastguard Worker }
1910*38e8c45fSAndroid Build Coastguard Worker 
getDisplayedContentSamplingAttributes(const sp<IBinder> & displayToken,ui::PixelFormat * outFormat,ui::Dataspace * outDataspace,uint8_t * outComponentMask) const1911*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getDisplayedContentSamplingAttributes(const sp<IBinder>& displayToken,
1912*38e8c45fSAndroid Build Coastguard Worker                                                                ui::PixelFormat* outFormat,
1913*38e8c45fSAndroid Build Coastguard Worker                                                                ui::Dataspace* outDataspace,
1914*38e8c45fSAndroid Build Coastguard Worker                                                                uint8_t* outComponentMask) const {
1915*38e8c45fSAndroid Build Coastguard Worker     if (!outFormat || !outDataspace || !outComponentMask) {
1916*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
1917*38e8c45fSAndroid Build Coastguard Worker     }
1918*38e8c45fSAndroid Build Coastguard Worker 
1919*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
1920*38e8c45fSAndroid Build Coastguard Worker 
1921*38e8c45fSAndroid Build Coastguard Worker     const auto displayId = getPhysicalDisplayIdLocked(displayToken);
1922*38e8c45fSAndroid Build Coastguard Worker     if (!displayId) {
1923*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
1924*38e8c45fSAndroid Build Coastguard Worker     }
1925*38e8c45fSAndroid Build Coastguard Worker 
1926*38e8c45fSAndroid Build Coastguard Worker     return getHwComposer().getDisplayedContentSamplingAttributes(*displayId, outFormat,
1927*38e8c45fSAndroid Build Coastguard Worker                                                                  outDataspace, outComponentMask);
1928*38e8c45fSAndroid Build Coastguard Worker }
1929*38e8c45fSAndroid Build Coastguard Worker 
setDisplayContentSamplingEnabled(const sp<IBinder> & displayToken,bool enable,uint8_t componentMask,uint64_t maxFrames)1930*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken,
1931*38e8c45fSAndroid Build Coastguard Worker                                                           bool enable, uint8_t componentMask,
1932*38e8c45fSAndroid Build Coastguard Worker                                                           uint64_t maxFrames) {
1933*38e8c45fSAndroid Build Coastguard Worker     const char* const whence = __func__;
1934*38e8c45fSAndroid Build Coastguard Worker     auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) -> status_t {
1935*38e8c45fSAndroid Build Coastguard Worker         if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
1936*38e8c45fSAndroid Build Coastguard Worker             return getHwComposer().setDisplayContentSamplingEnabled(*displayId, enable,
1937*38e8c45fSAndroid Build Coastguard Worker                                                                     componentMask, maxFrames);
1938*38e8c45fSAndroid Build Coastguard Worker         } else {
1939*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s: Invalid display token %p", whence, displayToken.get());
1940*38e8c45fSAndroid Build Coastguard Worker             return NAME_NOT_FOUND;
1941*38e8c45fSAndroid Build Coastguard Worker         }
1942*38e8c45fSAndroid Build Coastguard Worker     });
1943*38e8c45fSAndroid Build Coastguard Worker 
1944*38e8c45fSAndroid Build Coastguard Worker     return future.get();
1945*38e8c45fSAndroid Build Coastguard Worker }
1946*38e8c45fSAndroid Build Coastguard Worker 
getDisplayedContentSample(const sp<IBinder> & displayToken,uint64_t maxFrames,uint64_t timestamp,DisplayedFrameStats * outStats) const1947*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getDisplayedContentSample(const sp<IBinder>& displayToken,
1948*38e8c45fSAndroid Build Coastguard Worker                                                    uint64_t maxFrames, uint64_t timestamp,
1949*38e8c45fSAndroid Build Coastguard Worker                                                    DisplayedFrameStats* outStats) const {
1950*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
1951*38e8c45fSAndroid Build Coastguard Worker 
1952*38e8c45fSAndroid Build Coastguard Worker     const auto displayId = getPhysicalDisplayIdLocked(displayToken);
1953*38e8c45fSAndroid Build Coastguard Worker     if (!displayId) {
1954*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
1955*38e8c45fSAndroid Build Coastguard Worker     }
1956*38e8c45fSAndroid Build Coastguard Worker 
1957*38e8c45fSAndroid Build Coastguard Worker     return getHwComposer().getDisplayedContentSample(*displayId, maxFrames, timestamp, outStats);
1958*38e8c45fSAndroid Build Coastguard Worker }
1959*38e8c45fSAndroid Build Coastguard Worker 
getProtectedContentSupport(bool * outSupported) const1960*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getProtectedContentSupport(bool* outSupported) const {
1961*38e8c45fSAndroid Build Coastguard Worker     if (!outSupported) {
1962*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
1963*38e8c45fSAndroid Build Coastguard Worker     }
1964*38e8c45fSAndroid Build Coastguard Worker     *outSupported = getRenderEngine().supportsProtectedContent();
1965*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1966*38e8c45fSAndroid Build Coastguard Worker }
1967*38e8c45fSAndroid Build Coastguard Worker 
isWideColorDisplay(const sp<IBinder> & displayToken,bool * outIsWideColorDisplay) const1968*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::isWideColorDisplay(const sp<IBinder>& displayToken,
1969*38e8c45fSAndroid Build Coastguard Worker                                             bool* outIsWideColorDisplay) const {
1970*38e8c45fSAndroid Build Coastguard Worker     if (!displayToken || !outIsWideColorDisplay) {
1971*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
1972*38e8c45fSAndroid Build Coastguard Worker     }
1973*38e8c45fSAndroid Build Coastguard Worker 
1974*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
1975*38e8c45fSAndroid Build Coastguard Worker     const auto display = getDisplayDeviceLocked(displayToken);
1976*38e8c45fSAndroid Build Coastguard Worker     if (!display) {
1977*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
1978*38e8c45fSAndroid Build Coastguard Worker     }
1979*38e8c45fSAndroid Build Coastguard Worker 
1980*38e8c45fSAndroid Build Coastguard Worker     *outIsWideColorDisplay =
1981*38e8c45fSAndroid Build Coastguard Worker             display->isPrimary() ? mSupportsWideColor : display->hasWideColorGamut();
1982*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1983*38e8c45fSAndroid Build Coastguard Worker }
1984*38e8c45fSAndroid Build Coastguard Worker 
getCompositionPreference(Dataspace * outDataspace,ui::PixelFormat * outPixelFormat,Dataspace * outWideColorGamutDataspace,ui::PixelFormat * outWideColorGamutPixelFormat) const1985*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getCompositionPreference(
1986*38e8c45fSAndroid Build Coastguard Worker         Dataspace* outDataspace, ui::PixelFormat* outPixelFormat,
1987*38e8c45fSAndroid Build Coastguard Worker         Dataspace* outWideColorGamutDataspace,
1988*38e8c45fSAndroid Build Coastguard Worker         ui::PixelFormat* outWideColorGamutPixelFormat) const {
1989*38e8c45fSAndroid Build Coastguard Worker     *outDataspace = mDefaultCompositionDataspace;
1990*38e8c45fSAndroid Build Coastguard Worker     *outPixelFormat = defaultCompositionPixelFormat;
1991*38e8c45fSAndroid Build Coastguard Worker     *outWideColorGamutDataspace = mWideColorGamutCompositionDataspace;
1992*38e8c45fSAndroid Build Coastguard Worker     *outWideColorGamutPixelFormat = wideColorGamutCompositionPixelFormat;
1993*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
1994*38e8c45fSAndroid Build Coastguard Worker }
1995*38e8c45fSAndroid Build Coastguard Worker 
addRegionSamplingListener(const Rect & samplingArea,const sp<IBinder> & stopLayerHandle,const sp<IRegionSamplingListener> & listener)1996*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::addRegionSamplingListener(const Rect& samplingArea,
1997*38e8c45fSAndroid Build Coastguard Worker                                                    const sp<IBinder>& stopLayerHandle,
1998*38e8c45fSAndroid Build Coastguard Worker                                                    const sp<IRegionSamplingListener>& listener) {
1999*38e8c45fSAndroid Build Coastguard Worker     if (!listener || samplingArea == Rect::INVALID_RECT || samplingArea.isEmpty()) {
2000*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
2001*38e8c45fSAndroid Build Coastguard Worker     }
2002*38e8c45fSAndroid Build Coastguard Worker 
2003*38e8c45fSAndroid Build Coastguard Worker     // LayerHandle::getLayer promotes the layer object in a binder thread but we will not destroy
2004*38e8c45fSAndroid Build Coastguard Worker     // the layer here since the caller has a strong ref to the layer's handle.
2005*38e8c45fSAndroid Build Coastguard Worker     const sp<Layer> stopLayer = LayerHandle::getLayer(stopLayerHandle);
2006*38e8c45fSAndroid Build Coastguard Worker     mRegionSamplingThread->addListener(samplingArea,
2007*38e8c45fSAndroid Build Coastguard Worker                                        stopLayer ? stopLayer->getSequence() : UNASSIGNED_LAYER_ID,
2008*38e8c45fSAndroid Build Coastguard Worker                                        listener);
2009*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
2010*38e8c45fSAndroid Build Coastguard Worker }
2011*38e8c45fSAndroid Build Coastguard Worker 
removeRegionSamplingListener(const sp<IRegionSamplingListener> & listener)2012*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::removeRegionSamplingListener(const sp<IRegionSamplingListener>& listener) {
2013*38e8c45fSAndroid Build Coastguard Worker     if (!listener) {
2014*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
2015*38e8c45fSAndroid Build Coastguard Worker     }
2016*38e8c45fSAndroid Build Coastguard Worker     mRegionSamplingThread->removeListener(listener);
2017*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
2018*38e8c45fSAndroid Build Coastguard Worker }
2019*38e8c45fSAndroid Build Coastguard Worker 
addFpsListener(int32_t taskId,const sp<gui::IFpsListener> & listener)2020*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::addFpsListener(int32_t taskId, const sp<gui::IFpsListener>& listener) {
2021*38e8c45fSAndroid Build Coastguard Worker     if (!listener) {
2022*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
2023*38e8c45fSAndroid Build Coastguard Worker     }
2024*38e8c45fSAndroid Build Coastguard Worker 
2025*38e8c45fSAndroid Build Coastguard Worker     mFpsReporter->addListener(listener, taskId);
2026*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
2027*38e8c45fSAndroid Build Coastguard Worker }
2028*38e8c45fSAndroid Build Coastguard Worker 
removeFpsListener(const sp<gui::IFpsListener> & listener)2029*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::removeFpsListener(const sp<gui::IFpsListener>& listener) {
2030*38e8c45fSAndroid Build Coastguard Worker     if (!listener) {
2031*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
2032*38e8c45fSAndroid Build Coastguard Worker     }
2033*38e8c45fSAndroid Build Coastguard Worker     mFpsReporter->removeListener(listener);
2034*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
2035*38e8c45fSAndroid Build Coastguard Worker }
2036*38e8c45fSAndroid Build Coastguard Worker 
addTunnelModeEnabledListener(const sp<gui::ITunnelModeEnabledListener> & listener)2037*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::addTunnelModeEnabledListener(
2038*38e8c45fSAndroid Build Coastguard Worker         const sp<gui::ITunnelModeEnabledListener>& listener) {
2039*38e8c45fSAndroid Build Coastguard Worker     if (!listener) {
2040*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
2041*38e8c45fSAndroid Build Coastguard Worker     }
2042*38e8c45fSAndroid Build Coastguard Worker 
2043*38e8c45fSAndroid Build Coastguard Worker     mTunnelModeEnabledReporter->addListener(listener);
2044*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
2045*38e8c45fSAndroid Build Coastguard Worker }
2046*38e8c45fSAndroid Build Coastguard Worker 
removeTunnelModeEnabledListener(const sp<gui::ITunnelModeEnabledListener> & listener)2047*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::removeTunnelModeEnabledListener(
2048*38e8c45fSAndroid Build Coastguard Worker         const sp<gui::ITunnelModeEnabledListener>& listener) {
2049*38e8c45fSAndroid Build Coastguard Worker     if (!listener) {
2050*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
2051*38e8c45fSAndroid Build Coastguard Worker     }
2052*38e8c45fSAndroid Build Coastguard Worker 
2053*38e8c45fSAndroid Build Coastguard Worker     mTunnelModeEnabledReporter->removeListener(listener);
2054*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
2055*38e8c45fSAndroid Build Coastguard Worker }
2056*38e8c45fSAndroid Build Coastguard Worker 
getDisplayBrightnessSupport(const sp<IBinder> & displayToken,bool * outSupport) const2057*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getDisplayBrightnessSupport(const sp<IBinder>& displayToken,
2058*38e8c45fSAndroid Build Coastguard Worker                                                      bool* outSupport) const {
2059*38e8c45fSAndroid Build Coastguard Worker     if (!displayToken || !outSupport) {
2060*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
2061*38e8c45fSAndroid Build Coastguard Worker     }
2062*38e8c45fSAndroid Build Coastguard Worker 
2063*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
2064*38e8c45fSAndroid Build Coastguard Worker 
2065*38e8c45fSAndroid Build Coastguard Worker     const auto displayId = getPhysicalDisplayIdLocked(displayToken);
2066*38e8c45fSAndroid Build Coastguard Worker     if (!displayId) {
2067*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
2068*38e8c45fSAndroid Build Coastguard Worker     }
2069*38e8c45fSAndroid Build Coastguard Worker     *outSupport = getHwComposer().hasDisplayCapability(*displayId, DisplayCapability::BRIGHTNESS);
2070*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
2071*38e8c45fSAndroid Build Coastguard Worker }
2072*38e8c45fSAndroid Build Coastguard Worker 
setDisplayBrightness(const sp<IBinder> & displayToken,const gui::DisplayBrightness & brightness)2073*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken,
2074*38e8c45fSAndroid Build Coastguard Worker                                               const gui::DisplayBrightness& brightness) {
2075*38e8c45fSAndroid Build Coastguard Worker     if (!displayToken) {
2076*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
2077*38e8c45fSAndroid Build Coastguard Worker     }
2078*38e8c45fSAndroid Build Coastguard Worker 
2079*38e8c45fSAndroid Build Coastguard Worker     const char* const whence = __func__;
2080*38e8c45fSAndroid Build Coastguard Worker     return ftl::Future(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) {
2081*38e8c45fSAndroid Build Coastguard Worker                // TODO(b/241285876): Validate that the display is physical instead of failing later.
2082*38e8c45fSAndroid Build Coastguard Worker                if (const auto display = getDisplayDeviceLocked(displayToken)) {
2083*38e8c45fSAndroid Build Coastguard Worker                    const bool supportsDisplayBrightnessCommand =
2084*38e8c45fSAndroid Build Coastguard Worker                            getHwComposer().getComposer()->isSupported(
2085*38e8c45fSAndroid Build Coastguard Worker                                    Hwc2::Composer::OptionalFeature::DisplayBrightnessCommand);
2086*38e8c45fSAndroid Build Coastguard Worker                    // If we support applying display brightness as a command, then we also support
2087*38e8c45fSAndroid Build Coastguard Worker                    // dimming SDR layers.
2088*38e8c45fSAndroid Build Coastguard Worker                    if (supportsDisplayBrightnessCommand) {
2089*38e8c45fSAndroid Build Coastguard Worker                        auto compositionDisplay = display->getCompositionDisplay();
2090*38e8c45fSAndroid Build Coastguard Worker                        float currentDimmingRatio =
2091*38e8c45fSAndroid Build Coastguard Worker                                compositionDisplay->editState().sdrWhitePointNits /
2092*38e8c45fSAndroid Build Coastguard Worker                                compositionDisplay->editState().displayBrightnessNits;
2093*38e8c45fSAndroid Build Coastguard Worker                        static constexpr float kDimmingThreshold = 0.02f;
2094*38e8c45fSAndroid Build Coastguard Worker                        if (brightness.sdrWhitePointNits == 0.f ||
2095*38e8c45fSAndroid Build Coastguard Worker                            abs(brightness.sdrWhitePointNits - brightness.displayBrightnessNits) /
2096*38e8c45fSAndroid Build Coastguard Worker                                            brightness.sdrWhitePointNits >=
2097*38e8c45fSAndroid Build Coastguard Worker                                    kDimmingThreshold) {
2098*38e8c45fSAndroid Build Coastguard Worker                            // to optimize, skip brightness setter if the brightness difference ratio
2099*38e8c45fSAndroid Build Coastguard Worker                            // is lower than threshold
2100*38e8c45fSAndroid Build Coastguard Worker                            compositionDisplay
2101*38e8c45fSAndroid Build Coastguard Worker                                    ->setDisplayBrightness(brightness.sdrWhitePointNits,
2102*38e8c45fSAndroid Build Coastguard Worker                                                           brightness.displayBrightnessNits);
2103*38e8c45fSAndroid Build Coastguard Worker                        } else {
2104*38e8c45fSAndroid Build Coastguard Worker                            compositionDisplay->setDisplayBrightness(brightness.sdrWhitePointNits,
2105*38e8c45fSAndroid Build Coastguard Worker                                                                     brightness.sdrWhitePointNits);
2106*38e8c45fSAndroid Build Coastguard Worker                        }
2107*38e8c45fSAndroid Build Coastguard Worker 
2108*38e8c45fSAndroid Build Coastguard Worker                        FTL_FAKE_GUARD(kMainThreadContext,
2109*38e8c45fSAndroid Build Coastguard Worker                                       display->stageBrightness(brightness.displayBrightness));
2110*38e8c45fSAndroid Build Coastguard Worker                        float currentHdrSdrRatio =
2111*38e8c45fSAndroid Build Coastguard Worker                                compositionDisplay->editState().displayBrightnessNits /
2112*38e8c45fSAndroid Build Coastguard Worker                                compositionDisplay->editState().sdrWhitePointNits;
2113*38e8c45fSAndroid Build Coastguard Worker                        FTL_FAKE_GUARD(kMainThreadContext,
2114*38e8c45fSAndroid Build Coastguard Worker                                       display->updateHdrSdrRatioOverlayRatio(currentHdrSdrRatio));
2115*38e8c45fSAndroid Build Coastguard Worker 
2116*38e8c45fSAndroid Build Coastguard Worker                        if (brightness.sdrWhitePointNits / brightness.displayBrightnessNits !=
2117*38e8c45fSAndroid Build Coastguard Worker                            currentDimmingRatio) {
2118*38e8c45fSAndroid Build Coastguard Worker                            scheduleComposite(FrameHint::kNone);
2119*38e8c45fSAndroid Build Coastguard Worker                        } else {
2120*38e8c45fSAndroid Build Coastguard Worker                            scheduleCommit(FrameHint::kNone);
2121*38e8c45fSAndroid Build Coastguard Worker                        }
2122*38e8c45fSAndroid Build Coastguard Worker                        return ftl::yield<status_t>(OK);
2123*38e8c45fSAndroid Build Coastguard Worker                    } else {
2124*38e8c45fSAndroid Build Coastguard Worker                        return getHwComposer()
2125*38e8c45fSAndroid Build Coastguard Worker                                .setDisplayBrightness(display->getPhysicalId(),
2126*38e8c45fSAndroid Build Coastguard Worker                                                      brightness.displayBrightness,
2127*38e8c45fSAndroid Build Coastguard Worker                                                      brightness.displayBrightnessNits,
2128*38e8c45fSAndroid Build Coastguard Worker                                                      Hwc2::Composer::DisplayBrightnessOptions{
2129*38e8c45fSAndroid Build Coastguard Worker                                                              .applyImmediately = true});
2130*38e8c45fSAndroid Build Coastguard Worker                    }
2131*38e8c45fSAndroid Build Coastguard Worker                } else {
2132*38e8c45fSAndroid Build Coastguard Worker                    ALOGE("%s: Invalid display token %p", whence, displayToken.get());
2133*38e8c45fSAndroid Build Coastguard Worker                    return ftl::yield<status_t>(NAME_NOT_FOUND);
2134*38e8c45fSAndroid Build Coastguard Worker                }
2135*38e8c45fSAndroid Build Coastguard Worker            }))
2136*38e8c45fSAndroid Build Coastguard Worker             .then([](ftl::Future<status_t> task) { return task; })
2137*38e8c45fSAndroid Build Coastguard Worker             .get();
2138*38e8c45fSAndroid Build Coastguard Worker }
2139*38e8c45fSAndroid Build Coastguard Worker 
addHdrLayerInfoListener(const sp<IBinder> & displayToken,const sp<gui::IHdrLayerInfoListener> & listener)2140*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::addHdrLayerInfoListener(const sp<IBinder>& displayToken,
2141*38e8c45fSAndroid Build Coastguard Worker                                                  const sp<gui::IHdrLayerInfoListener>& listener) {
2142*38e8c45fSAndroid Build Coastguard Worker     if (!displayToken) {
2143*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
2144*38e8c45fSAndroid Build Coastguard Worker     }
2145*38e8c45fSAndroid Build Coastguard Worker 
2146*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
2147*38e8c45fSAndroid Build Coastguard Worker 
2148*38e8c45fSAndroid Build Coastguard Worker     const auto display = getDisplayDeviceLocked(displayToken);
2149*38e8c45fSAndroid Build Coastguard Worker     if (!display) {
2150*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
2151*38e8c45fSAndroid Build Coastguard Worker     }
2152*38e8c45fSAndroid Build Coastguard Worker     const auto displayId = display->getId();
2153*38e8c45fSAndroid Build Coastguard Worker     sp<HdrLayerInfoReporter>& hdrInfoReporter = mHdrLayerInfoListeners[displayId];
2154*38e8c45fSAndroid Build Coastguard Worker     if (!hdrInfoReporter) {
2155*38e8c45fSAndroid Build Coastguard Worker         hdrInfoReporter = sp<HdrLayerInfoReporter>::make();
2156*38e8c45fSAndroid Build Coastguard Worker     }
2157*38e8c45fSAndroid Build Coastguard Worker     hdrInfoReporter->addListener(listener);
2158*38e8c45fSAndroid Build Coastguard Worker 
2159*38e8c45fSAndroid Build Coastguard Worker 
2160*38e8c45fSAndroid Build Coastguard Worker     mAddingHDRLayerInfoListener = true;
2161*38e8c45fSAndroid Build Coastguard Worker     return OK;
2162*38e8c45fSAndroid Build Coastguard Worker }
2163*38e8c45fSAndroid Build Coastguard Worker 
removeHdrLayerInfoListener(const sp<IBinder> & displayToken,const sp<gui::IHdrLayerInfoListener> & listener)2164*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::removeHdrLayerInfoListener(
2165*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener) {
2166*38e8c45fSAndroid Build Coastguard Worker     if (!displayToken) {
2167*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
2168*38e8c45fSAndroid Build Coastguard Worker     }
2169*38e8c45fSAndroid Build Coastguard Worker 
2170*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
2171*38e8c45fSAndroid Build Coastguard Worker 
2172*38e8c45fSAndroid Build Coastguard Worker     const auto display = getDisplayDeviceLocked(displayToken);
2173*38e8c45fSAndroid Build Coastguard Worker     if (!display) {
2174*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
2175*38e8c45fSAndroid Build Coastguard Worker     }
2176*38e8c45fSAndroid Build Coastguard Worker     const auto displayId = display->getId();
2177*38e8c45fSAndroid Build Coastguard Worker     sp<HdrLayerInfoReporter>& hdrInfoReporter = mHdrLayerInfoListeners[displayId];
2178*38e8c45fSAndroid Build Coastguard Worker     if (hdrInfoReporter) {
2179*38e8c45fSAndroid Build Coastguard Worker         hdrInfoReporter->removeListener(listener);
2180*38e8c45fSAndroid Build Coastguard Worker     }
2181*38e8c45fSAndroid Build Coastguard Worker     return OK;
2182*38e8c45fSAndroid Build Coastguard Worker }
2183*38e8c45fSAndroid Build Coastguard Worker 
notifyPowerBoost(int32_t boostId)2184*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::notifyPowerBoost(int32_t boostId) {
2185*38e8c45fSAndroid Build Coastguard Worker     using aidl::android::hardware::power::Boost;
2186*38e8c45fSAndroid Build Coastguard Worker     Boost powerBoost = static_cast<Boost>(boostId);
2187*38e8c45fSAndroid Build Coastguard Worker 
2188*38e8c45fSAndroid Build Coastguard Worker     if (powerBoost == Boost::INTERACTION) {
2189*38e8c45fSAndroid Build Coastguard Worker         mScheduler->onTouchHint();
2190*38e8c45fSAndroid Build Coastguard Worker     }
2191*38e8c45fSAndroid Build Coastguard Worker 
2192*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
2193*38e8c45fSAndroid Build Coastguard Worker }
2194*38e8c45fSAndroid Build Coastguard Worker 
getDisplayDecorationSupport(const sp<IBinder> & displayToken,std::optional<DisplayDecorationSupport> * outSupport) const2195*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getDisplayDecorationSupport(
2196*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& displayToken,
2197*38e8c45fSAndroid Build Coastguard Worker         std::optional<DisplayDecorationSupport>* outSupport) const {
2198*38e8c45fSAndroid Build Coastguard Worker     if (!displayToken || !outSupport) {
2199*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
2200*38e8c45fSAndroid Build Coastguard Worker     }
2201*38e8c45fSAndroid Build Coastguard Worker 
2202*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
2203*38e8c45fSAndroid Build Coastguard Worker 
2204*38e8c45fSAndroid Build Coastguard Worker     const auto displayId = getPhysicalDisplayIdLocked(displayToken);
2205*38e8c45fSAndroid Build Coastguard Worker     if (!displayId) {
2206*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
2207*38e8c45fSAndroid Build Coastguard Worker     }
2208*38e8c45fSAndroid Build Coastguard Worker     getHwComposer().getDisplayDecorationSupport(*displayId, outSupport);
2209*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
2210*38e8c45fSAndroid Build Coastguard Worker }
2211*38e8c45fSAndroid Build Coastguard Worker 
2212*38e8c45fSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
2213*38e8c45fSAndroid Build Coastguard Worker 
createDisplayEventConnection(gui::ISurfaceComposer::VsyncSource vsyncSource,EventRegistrationFlags eventRegistration,const sp<IBinder> & layerHandle)2214*38e8c45fSAndroid Build Coastguard Worker sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
2215*38e8c45fSAndroid Build Coastguard Worker         gui::ISurfaceComposer::VsyncSource vsyncSource, EventRegistrationFlags eventRegistration,
2216*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& layerHandle) {
2217*38e8c45fSAndroid Build Coastguard Worker     const auto cycle = [&] {
2218*38e8c45fSAndroid Build Coastguard Worker         if (FlagManager::getInstance().deprecate_vsync_sf()) {
2219*38e8c45fSAndroid Build Coastguard Worker             ALOGW_IF(vsyncSource == gui::ISurfaceComposer::VsyncSource::eVsyncSourceSurfaceFlinger,
2220*38e8c45fSAndroid Build Coastguard Worker                 "requested unsupported config eVsyncSourceSurfaceFlinger");
2221*38e8c45fSAndroid Build Coastguard Worker             return scheduler::Cycle::Render;
2222*38e8c45fSAndroid Build Coastguard Worker         }
2223*38e8c45fSAndroid Build Coastguard Worker 
2224*38e8c45fSAndroid Build Coastguard Worker         return vsyncSource == gui::ISurfaceComposer::VsyncSource::eVsyncSourceSurfaceFlinger
2225*38e8c45fSAndroid Build Coastguard Worker               ? scheduler::Cycle::LastComposite
2226*38e8c45fSAndroid Build Coastguard Worker               : scheduler::Cycle::Render;
2227*38e8c45fSAndroid Build Coastguard Worker     }();
2228*38e8c45fSAndroid Build Coastguard Worker     return mScheduler->createDisplayEventConnection(cycle, eventRegistration, layerHandle);
2229*38e8c45fSAndroid Build Coastguard Worker }
2230*38e8c45fSAndroid Build Coastguard Worker 
scheduleCommit(FrameHint hint,Duration workDurationSlack)2231*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::scheduleCommit(FrameHint hint, Duration workDurationSlack) {
2232*38e8c45fSAndroid Build Coastguard Worker     if (hint == FrameHint::kActive) {
2233*38e8c45fSAndroid Build Coastguard Worker         mScheduler->resetIdleTimer();
2234*38e8c45fSAndroid Build Coastguard Worker     }
2235*38e8c45fSAndroid Build Coastguard Worker     mPowerAdvisor->notifyDisplayUpdateImminentAndCpuReset();
2236*38e8c45fSAndroid Build Coastguard Worker     mScheduler->scheduleFrame(workDurationSlack);
2237*38e8c45fSAndroid Build Coastguard Worker }
2238*38e8c45fSAndroid Build Coastguard Worker 
scheduleComposite(FrameHint hint)2239*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::scheduleComposite(FrameHint hint) {
2240*38e8c45fSAndroid Build Coastguard Worker     mMustComposite = true;
2241*38e8c45fSAndroid Build Coastguard Worker     scheduleCommit(hint);
2242*38e8c45fSAndroid Build Coastguard Worker }
2243*38e8c45fSAndroid Build Coastguard Worker 
scheduleRepaint()2244*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::scheduleRepaint() {
2245*38e8c45fSAndroid Build Coastguard Worker     mGeometryDirty = true;
2246*38e8c45fSAndroid Build Coastguard Worker     scheduleComposite(FrameHint::kActive);
2247*38e8c45fSAndroid Build Coastguard Worker }
2248*38e8c45fSAndroid Build Coastguard Worker 
scheduleSample()2249*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::scheduleSample() {
2250*38e8c45fSAndroid Build Coastguard Worker     static_cast<void>(mScheduler->schedule([this] { sample(); }));
2251*38e8c45fSAndroid Build Coastguard Worker }
2252*38e8c45fSAndroid Build Coastguard Worker 
onComposerHalVsync(hal::HWDisplayId hwcDisplayId,int64_t timestamp,std::optional<hal::VsyncPeriodNanos> vsyncPeriod)2253*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onComposerHalVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp,
2254*38e8c45fSAndroid Build Coastguard Worker                                         std::optional<hal::VsyncPeriodNanos> vsyncPeriod) {
2255*38e8c45fSAndroid Build Coastguard Worker     if (FlagManager::getInstance().connected_display() && timestamp < 0 &&
2256*38e8c45fSAndroid Build Coastguard Worker         vsyncPeriod.has_value()) {
2257*38e8c45fSAndroid Build Coastguard Worker         if (mIsHdcpViaNegVsync && vsyncPeriod.value() == ~1) {
2258*38e8c45fSAndroid Build Coastguard Worker             const int32_t value = static_cast<int32_t>(-timestamp);
2259*38e8c45fSAndroid Build Coastguard Worker             // one byte is good enough to encode android.hardware.drm.HdcpLevel
2260*38e8c45fSAndroid Build Coastguard Worker             const int32_t maxLevel = (value >> 8) & 0xFF;
2261*38e8c45fSAndroid Build Coastguard Worker             const int32_t connectedLevel = value & 0xFF;
2262*38e8c45fSAndroid Build Coastguard Worker             ALOGD("%s: HDCP levels changed (connected=%d, max=%d) for hwcDisplayId %" PRIu64,
2263*38e8c45fSAndroid Build Coastguard Worker                   __func__, connectedLevel, maxLevel, hwcDisplayId);
2264*38e8c45fSAndroid Build Coastguard Worker             updateHdcpLevels(hwcDisplayId, connectedLevel, maxLevel);
2265*38e8c45fSAndroid Build Coastguard Worker             return;
2266*38e8c45fSAndroid Build Coastguard Worker         }
2267*38e8c45fSAndroid Build Coastguard Worker     }
2268*38e8c45fSAndroid Build Coastguard Worker 
2269*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_NAME(vsyncPeriod
2270*38e8c45fSAndroid Build Coastguard Worker                          ? ftl::Concat(__func__, ' ', hwcDisplayId, ' ', *vsyncPeriod, "ns").c_str()
2271*38e8c45fSAndroid Build Coastguard Worker                          : ftl::Concat(__func__, ' ', hwcDisplayId).c_str());
2272*38e8c45fSAndroid Build Coastguard Worker 
2273*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
2274*38e8c45fSAndroid Build Coastguard Worker     if (const auto displayIdOpt = getHwComposer().onVsync(hwcDisplayId, timestamp)) {
2275*38e8c45fSAndroid Build Coastguard Worker         if (mScheduler->addResyncSample(*displayIdOpt, timestamp, vsyncPeriod)) {
2276*38e8c45fSAndroid Build Coastguard Worker             // period flushed
2277*38e8c45fSAndroid Build Coastguard Worker             mScheduler->modulateVsync(displayIdOpt, &VsyncModulator::onRefreshRateChangeCompleted);
2278*38e8c45fSAndroid Build Coastguard Worker         }
2279*38e8c45fSAndroid Build Coastguard Worker     }
2280*38e8c45fSAndroid Build Coastguard Worker }
2281*38e8c45fSAndroid Build Coastguard Worker 
onComposerHalHotplugEvent(hal::HWDisplayId hwcDisplayId,DisplayHotplugEvent event)2282*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onComposerHalHotplugEvent(hal::HWDisplayId hwcDisplayId,
2283*38e8c45fSAndroid Build Coastguard Worker                                                DisplayHotplugEvent event) {
2284*38e8c45fSAndroid Build Coastguard Worker     if (event == DisplayHotplugEvent::CONNECTED || event == DisplayHotplugEvent::DISCONNECTED) {
2285*38e8c45fSAndroid Build Coastguard Worker         hal::Connection connection = (event == DisplayHotplugEvent::CONNECTED)
2286*38e8c45fSAndroid Build Coastguard Worker                 ? hal::Connection::CONNECTED
2287*38e8c45fSAndroid Build Coastguard Worker                 : hal::Connection::DISCONNECTED;
2288*38e8c45fSAndroid Build Coastguard Worker         {
2289*38e8c45fSAndroid Build Coastguard Worker             std::lock_guard<std::mutex> lock(mHotplugMutex);
2290*38e8c45fSAndroid Build Coastguard Worker             mPendingHotplugEvents.push_back(HotplugEvent{hwcDisplayId, connection});
2291*38e8c45fSAndroid Build Coastguard Worker         }
2292*38e8c45fSAndroid Build Coastguard Worker 
2293*38e8c45fSAndroid Build Coastguard Worker         if (mScheduler) {
2294*38e8c45fSAndroid Build Coastguard Worker             mScheduler->scheduleConfigure();
2295*38e8c45fSAndroid Build Coastguard Worker         }
2296*38e8c45fSAndroid Build Coastguard Worker 
2297*38e8c45fSAndroid Build Coastguard Worker         return;
2298*38e8c45fSAndroid Build Coastguard Worker     }
2299*38e8c45fSAndroid Build Coastguard Worker 
2300*38e8c45fSAndroid Build Coastguard Worker     if (event < DisplayHotplugEvent::ERROR_LINK_UNSTABLE) {
2301*38e8c45fSAndroid Build Coastguard Worker         // This needs to be kept in sync with DisplayHotplugEvent to prevent passing new errors.
2302*38e8c45fSAndroid Build Coastguard Worker         const auto errorCode = static_cast<int32_t>(event);
2303*38e8c45fSAndroid Build Coastguard Worker         ALOGW("%s: Unknown hotplug error %d for hwcDisplayId %" PRIu64, __func__, errorCode,
2304*38e8c45fSAndroid Build Coastguard Worker               hwcDisplayId);
2305*38e8c45fSAndroid Build Coastguard Worker         return;
2306*38e8c45fSAndroid Build Coastguard Worker     }
2307*38e8c45fSAndroid Build Coastguard Worker 
2308*38e8c45fSAndroid Build Coastguard Worker     if (event == DisplayHotplugEvent::ERROR_LINK_UNSTABLE &&
2309*38e8c45fSAndroid Build Coastguard Worker         !FlagManager::getInstance().display_config_error_hal()) {
2310*38e8c45fSAndroid Build Coastguard Worker         return;
2311*38e8c45fSAndroid Build Coastguard Worker     }
2312*38e8c45fSAndroid Build Coastguard Worker 
2313*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/311403559): use enum type instead of int
2314*38e8c45fSAndroid Build Coastguard Worker     const auto errorCode = static_cast<int32_t>(event);
2315*38e8c45fSAndroid Build Coastguard Worker     ALOGD("%s: Hotplug error %d for hwcDisplayId %" PRIu64, __func__, errorCode, hwcDisplayId);
2316*38e8c45fSAndroid Build Coastguard Worker     mScheduler->dispatchHotplugError(errorCode);
2317*38e8c45fSAndroid Build Coastguard Worker }
2318*38e8c45fSAndroid Build Coastguard Worker 
onComposerHalVsyncPeriodTimingChanged(hal::HWDisplayId,const hal::VsyncPeriodChangeTimeline & timeline)2319*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onComposerHalVsyncPeriodTimingChanged(
2320*38e8c45fSAndroid Build Coastguard Worker         hal::HWDisplayId, const hal::VsyncPeriodChangeTimeline& timeline) {
2321*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
2322*38e8c45fSAndroid Build Coastguard Worker     mScheduler->onNewVsyncPeriodChangeTimeline(timeline);
2323*38e8c45fSAndroid Build Coastguard Worker 
2324*38e8c45fSAndroid Build Coastguard Worker     if (timeline.refreshRequired) {
2325*38e8c45fSAndroid Build Coastguard Worker         scheduleComposite(FrameHint::kNone);
2326*38e8c45fSAndroid Build Coastguard Worker     }
2327*38e8c45fSAndroid Build Coastguard Worker }
2328*38e8c45fSAndroid Build Coastguard Worker 
onComposerHalSeamlessPossible(hal::HWDisplayId)2329*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onComposerHalSeamlessPossible(hal::HWDisplayId) {
2330*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/142753666): use constraints when calling to setActiveModeWithConstraints and
2331*38e8c45fSAndroid Build Coastguard Worker     // use this callback to know when to retry in case of SEAMLESS_NOT_POSSIBLE.
2332*38e8c45fSAndroid Build Coastguard Worker }
2333*38e8c45fSAndroid Build Coastguard Worker 
onComposerHalRefresh(hal::HWDisplayId)2334*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onComposerHalRefresh(hal::HWDisplayId) {
2335*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
2336*38e8c45fSAndroid Build Coastguard Worker     scheduleComposite(FrameHint::kNone);
2337*38e8c45fSAndroid Build Coastguard Worker }
2338*38e8c45fSAndroid Build Coastguard Worker 
onComposerHalVsyncIdle(hal::HWDisplayId)2339*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onComposerHalVsyncIdle(hal::HWDisplayId) {
2340*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
2341*38e8c45fSAndroid Build Coastguard Worker     mScheduler->forceNextResync();
2342*38e8c45fSAndroid Build Coastguard Worker }
2343*38e8c45fSAndroid Build Coastguard Worker 
onRefreshRateChangedDebug(const RefreshRateChangedDebugData & data)2344*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onRefreshRateChangedDebug(const RefreshRateChangedDebugData& data) {
2345*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
2346*38e8c45fSAndroid Build Coastguard Worker     const char* const whence = __func__;
2347*38e8c45fSAndroid Build Coastguard Worker     static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(
2348*38e8c45fSAndroid Build Coastguard Worker                                                    kMainThreadContext) {
2349*38e8c45fSAndroid Build Coastguard Worker         if (const auto displayIdOpt = getHwComposer().toPhysicalDisplayId(data.display)) {
2350*38e8c45fSAndroid Build Coastguard Worker             if (const auto display = getDisplayDeviceLocked(*displayIdOpt)) {
2351*38e8c45fSAndroid Build Coastguard Worker                 const Fps refreshRate = Fps::fromPeriodNsecs(
2352*38e8c45fSAndroid Build Coastguard Worker                         getHwComposer().getComposer()->isVrrSupported() ? data.refreshPeriodNanos
2353*38e8c45fSAndroid Build Coastguard Worker                                                                         : data.vsyncPeriodNanos);
2354*38e8c45fSAndroid Build Coastguard Worker                 SFTRACE_FORMAT("%s refresh rate = %d", whence, refreshRate.getIntValue());
2355*38e8c45fSAndroid Build Coastguard Worker 
2356*38e8c45fSAndroid Build Coastguard Worker                 const auto renderRate = mDisplayModeController.getActiveMode(*displayIdOpt).fps;
2357*38e8c45fSAndroid Build Coastguard Worker                 constexpr bool kSetByHwc = true;
2358*38e8c45fSAndroid Build Coastguard Worker                 display->updateRefreshRateOverlayRate(refreshRate, renderRate, kSetByHwc);
2359*38e8c45fSAndroid Build Coastguard Worker             }
2360*38e8c45fSAndroid Build Coastguard Worker         }
2361*38e8c45fSAndroid Build Coastguard Worker     }));
2362*38e8c45fSAndroid Build Coastguard Worker }
2363*38e8c45fSAndroid Build Coastguard Worker 
onComposerHalHdcpLevelsChanged(hal::HWDisplayId hwcDisplayId,const HdcpLevels & levels)2364*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onComposerHalHdcpLevelsChanged(hal::HWDisplayId hwcDisplayId,
2365*38e8c45fSAndroid Build Coastguard Worker                                                     const HdcpLevels& levels) {
2366*38e8c45fSAndroid Build Coastguard Worker     if (FlagManager::getInstance().hdcp_level_hal()) {
2367*38e8c45fSAndroid Build Coastguard Worker         // TODO(b/362270040): propagate enum constants
2368*38e8c45fSAndroid Build Coastguard Worker         const int32_t maxLevel = static_cast<int32_t>(levels.maxLevel);
2369*38e8c45fSAndroid Build Coastguard Worker         const int32_t connectedLevel = static_cast<int32_t>(levels.connectedLevel);
2370*38e8c45fSAndroid Build Coastguard Worker         ALOGD("%s: HDCP levels changed (connected=%d, max=%d) for hwcDisplayId %" PRIu64, __func__,
2371*38e8c45fSAndroid Build Coastguard Worker               connectedLevel, maxLevel, hwcDisplayId);
2372*38e8c45fSAndroid Build Coastguard Worker         updateHdcpLevels(hwcDisplayId, connectedLevel, maxLevel);
2373*38e8c45fSAndroid Build Coastguard Worker     }
2374*38e8c45fSAndroid Build Coastguard Worker }
2375*38e8c45fSAndroid Build Coastguard Worker 
configure()2376*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::configure() {
2377*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
2378*38e8c45fSAndroid Build Coastguard Worker     if (configureLocked()) {
2379*38e8c45fSAndroid Build Coastguard Worker         setTransactionFlags(eDisplayTransactionNeeded);
2380*38e8c45fSAndroid Build Coastguard Worker     }
2381*38e8c45fSAndroid Build Coastguard Worker }
2382*38e8c45fSAndroid Build Coastguard Worker 
updateLayerHistory(nsecs_t now)2383*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::updateLayerHistory(nsecs_t now) {
2384*38e8c45fSAndroid Build Coastguard Worker     for (const auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) {
2385*38e8c45fSAndroid Build Coastguard Worker         using Changes = frontend::RequestedLayerState::Changes;
2386*38e8c45fSAndroid Build Coastguard Worker         if (snapshot->path.isClone()) {
2387*38e8c45fSAndroid Build Coastguard Worker             continue;
2388*38e8c45fSAndroid Build Coastguard Worker         }
2389*38e8c45fSAndroid Build Coastguard Worker 
2390*38e8c45fSAndroid Build Coastguard Worker         const bool updateSmallDirty = FlagManager::getInstance().enable_small_area_detection() &&
2391*38e8c45fSAndroid Build Coastguard Worker                 ((snapshot->clientChanges & layer_state_t::eSurfaceDamageRegionChanged) ||
2392*38e8c45fSAndroid Build Coastguard Worker                  snapshot->changes.any(Changes::Geometry));
2393*38e8c45fSAndroid Build Coastguard Worker 
2394*38e8c45fSAndroid Build Coastguard Worker         const bool hasChanges =
2395*38e8c45fSAndroid Build Coastguard Worker                 snapshot->changes.any(Changes::FrameRate | Changes::Buffer | Changes::Animation |
2396*38e8c45fSAndroid Build Coastguard Worker                                       Changes::Geometry | Changes::Visibility) ||
2397*38e8c45fSAndroid Build Coastguard Worker                 (snapshot->clientChanges & layer_state_t::eDefaultFrameRateCompatibilityChanged) !=
2398*38e8c45fSAndroid Build Coastguard Worker                         0;
2399*38e8c45fSAndroid Build Coastguard Worker 
2400*38e8c45fSAndroid Build Coastguard Worker         if (!updateSmallDirty && !hasChanges) {
2401*38e8c45fSAndroid Build Coastguard Worker             continue;
2402*38e8c45fSAndroid Build Coastguard Worker         }
2403*38e8c45fSAndroid Build Coastguard Worker 
2404*38e8c45fSAndroid Build Coastguard Worker         auto it = mLegacyLayers.find(snapshot->sequence);
2405*38e8c45fSAndroid Build Coastguard Worker         LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
2406*38e8c45fSAndroid Build Coastguard Worker                                         "Couldn't find layer object for %s",
2407*38e8c45fSAndroid Build Coastguard Worker                                         snapshot->getDebugString().c_str());
2408*38e8c45fSAndroid Build Coastguard Worker 
2409*38e8c45fSAndroid Build Coastguard Worker         if (updateSmallDirty) {
2410*38e8c45fSAndroid Build Coastguard Worker             // Update small dirty flag while surface damage region or geometry changed
2411*38e8c45fSAndroid Build Coastguard Worker             it->second->setIsSmallDirty(snapshot.get());
2412*38e8c45fSAndroid Build Coastguard Worker         }
2413*38e8c45fSAndroid Build Coastguard Worker 
2414*38e8c45fSAndroid Build Coastguard Worker         if (!hasChanges) {
2415*38e8c45fSAndroid Build Coastguard Worker             continue;
2416*38e8c45fSAndroid Build Coastguard Worker         }
2417*38e8c45fSAndroid Build Coastguard Worker 
2418*38e8c45fSAndroid Build Coastguard Worker         const auto layerProps = scheduler::LayerProps{
2419*38e8c45fSAndroid Build Coastguard Worker                 .visible = snapshot->isVisible,
2420*38e8c45fSAndroid Build Coastguard Worker                 .bounds = snapshot->geomLayerBounds,
2421*38e8c45fSAndroid Build Coastguard Worker                 .transform = snapshot->geomLayerTransform,
2422*38e8c45fSAndroid Build Coastguard Worker                 .setFrameRateVote = snapshot->frameRate,
2423*38e8c45fSAndroid Build Coastguard Worker                 .frameRateSelectionPriority = snapshot->frameRateSelectionPriority,
2424*38e8c45fSAndroid Build Coastguard Worker                 .isSmallDirty = snapshot->isSmallDirty,
2425*38e8c45fSAndroid Build Coastguard Worker                 .isFrontBuffered = snapshot->isFrontBuffered(),
2426*38e8c45fSAndroid Build Coastguard Worker         };
2427*38e8c45fSAndroid Build Coastguard Worker 
2428*38e8c45fSAndroid Build Coastguard Worker         if (snapshot->changes.any(Changes::Geometry | Changes::Visibility)) {
2429*38e8c45fSAndroid Build Coastguard Worker             mScheduler->setLayerProperties(snapshot->sequence, layerProps);
2430*38e8c45fSAndroid Build Coastguard Worker         }
2431*38e8c45fSAndroid Build Coastguard Worker 
2432*38e8c45fSAndroid Build Coastguard Worker         if (snapshot->clientChanges & layer_state_t::eDefaultFrameRateCompatibilityChanged) {
2433*38e8c45fSAndroid Build Coastguard Worker             mScheduler->setDefaultFrameRateCompatibility(snapshot->sequence,
2434*38e8c45fSAndroid Build Coastguard Worker                                                          snapshot->defaultFrameRateCompatibility);
2435*38e8c45fSAndroid Build Coastguard Worker         }
2436*38e8c45fSAndroid Build Coastguard Worker 
2437*38e8c45fSAndroid Build Coastguard Worker         if (snapshot->changes.test(Changes::Animation)) {
2438*38e8c45fSAndroid Build Coastguard Worker             it->second->recordLayerHistoryAnimationTx(layerProps, now);
2439*38e8c45fSAndroid Build Coastguard Worker         }
2440*38e8c45fSAndroid Build Coastguard Worker 
2441*38e8c45fSAndroid Build Coastguard Worker         if (snapshot->changes.test(Changes::FrameRate)) {
2442*38e8c45fSAndroid Build Coastguard Worker             it->second->setFrameRateForLayerTree(snapshot->frameRate, layerProps, now);
2443*38e8c45fSAndroid Build Coastguard Worker         }
2444*38e8c45fSAndroid Build Coastguard Worker 
2445*38e8c45fSAndroid Build Coastguard Worker         if (snapshot->changes.test(Changes::Buffer)) {
2446*38e8c45fSAndroid Build Coastguard Worker             it->second->recordLayerHistoryBufferUpdate(layerProps, now);
2447*38e8c45fSAndroid Build Coastguard Worker         }
2448*38e8c45fSAndroid Build Coastguard Worker     }
2449*38e8c45fSAndroid Build Coastguard Worker }
2450*38e8c45fSAndroid Build Coastguard Worker 
updateLayerSnapshots(VsyncId vsyncId,nsecs_t frameTimeNs,bool flushTransactions,bool & outTransactionsAreEmpty)2451*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs,
2452*38e8c45fSAndroid Build Coastguard Worker                                           bool flushTransactions, bool& outTransactionsAreEmpty) {
2453*38e8c45fSAndroid Build Coastguard Worker     using Changes = frontend::RequestedLayerState::Changes;
2454*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
2455*38e8c45fSAndroid Build Coastguard Worker     frontend::Update update;
2456*38e8c45fSAndroid Build Coastguard Worker     if (flushTransactions) {
2457*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_NAME("TransactionHandler:flushTransactions");
2458*38e8c45fSAndroid Build Coastguard Worker         // Locking:
2459*38e8c45fSAndroid Build Coastguard Worker         // 1. to prevent onHandleDestroyed from being called while the state lock is held,
2460*38e8c45fSAndroid Build Coastguard Worker         // we must keep a copy of the transactions (specifically the composer
2461*38e8c45fSAndroid Build Coastguard Worker         // states) around outside the scope of the lock.
2462*38e8c45fSAndroid Build Coastguard Worker         // 2. Transactions and created layers do not share a lock. To prevent applying
2463*38e8c45fSAndroid Build Coastguard Worker         // transactions with layers still in the createdLayer queue, collect the transactions
2464*38e8c45fSAndroid Build Coastguard Worker         // before committing the created layers.
2465*38e8c45fSAndroid Build Coastguard Worker         // 3. Transactions can only be flushed after adding layers, since the layer can be a newly
2466*38e8c45fSAndroid Build Coastguard Worker         // created one
2467*38e8c45fSAndroid Build Coastguard Worker         mTransactionHandler.collectTransactions();
2468*38e8c45fSAndroid Build Coastguard Worker         {
2469*38e8c45fSAndroid Build Coastguard Worker             // TODO(b/238781169) lockless queue this and keep order.
2470*38e8c45fSAndroid Build Coastguard Worker             std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
2471*38e8c45fSAndroid Build Coastguard Worker             update.legacyLayers = std::move(mCreatedLayers);
2472*38e8c45fSAndroid Build Coastguard Worker             mCreatedLayers.clear();
2473*38e8c45fSAndroid Build Coastguard Worker             update.newLayers = std::move(mNewLayers);
2474*38e8c45fSAndroid Build Coastguard Worker             mNewLayers.clear();
2475*38e8c45fSAndroid Build Coastguard Worker             update.layerCreationArgs = std::move(mNewLayerArgs);
2476*38e8c45fSAndroid Build Coastguard Worker             mNewLayerArgs.clear();
2477*38e8c45fSAndroid Build Coastguard Worker             update.destroyedHandles = std::move(mDestroyedHandles);
2478*38e8c45fSAndroid Build Coastguard Worker             mDestroyedHandles.clear();
2479*38e8c45fSAndroid Build Coastguard Worker         }
2480*38e8c45fSAndroid Build Coastguard Worker 
2481*38e8c45fSAndroid Build Coastguard Worker         mLayerLifecycleManager.addLayers(std::move(update.newLayers));
2482*38e8c45fSAndroid Build Coastguard Worker         update.transactions = mTransactionHandler.flushTransactions();
2483*38e8c45fSAndroid Build Coastguard Worker         if (mTransactionTracing) {
2484*38e8c45fSAndroid Build Coastguard Worker             mTransactionTracing->addCommittedTransactions(ftl::to_underlying(vsyncId), frameTimeNs,
2485*38e8c45fSAndroid Build Coastguard Worker                                                           update, mFrontEndDisplayInfos,
2486*38e8c45fSAndroid Build Coastguard Worker                                                           mFrontEndDisplayInfosChanged);
2487*38e8c45fSAndroid Build Coastguard Worker         }
2488*38e8c45fSAndroid Build Coastguard Worker         mLayerLifecycleManager.applyTransactions(update.transactions);
2489*38e8c45fSAndroid Build Coastguard Worker         mLayerLifecycleManager.onHandlesDestroyed(update.destroyedHandles);
2490*38e8c45fSAndroid Build Coastguard Worker         for (auto& legacyLayer : update.legacyLayers) {
2491*38e8c45fSAndroid Build Coastguard Worker             mLegacyLayers[legacyLayer->sequence] = legacyLayer;
2492*38e8c45fSAndroid Build Coastguard Worker         }
2493*38e8c45fSAndroid Build Coastguard Worker         mLayerHierarchyBuilder.update(mLayerLifecycleManager);
2494*38e8c45fSAndroid Build Coastguard Worker     }
2495*38e8c45fSAndroid Build Coastguard Worker 
2496*38e8c45fSAndroid Build Coastguard Worker     // Keep a copy of the drawing state (that is going to be overwritten
2497*38e8c45fSAndroid Build Coastguard Worker     // by commitTransactionsLocked) outside of mStateLock so that the side
2498*38e8c45fSAndroid Build Coastguard Worker     // effects of the State assignment don't happen with mStateLock held,
2499*38e8c45fSAndroid Build Coastguard Worker     // which can cause deadlocks.
2500*38e8c45fSAndroid Build Coastguard Worker     State drawingState(mDrawingState);
2501*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
2502*38e8c45fSAndroid Build Coastguard Worker     bool mustComposite = false;
2503*38e8c45fSAndroid Build Coastguard Worker     mustComposite |= applyAndCommitDisplayTransactionStatesLocked(update.transactions);
2504*38e8c45fSAndroid Build Coastguard Worker 
2505*38e8c45fSAndroid Build Coastguard Worker     {
2506*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_NAME("LayerSnapshotBuilder:update");
2507*38e8c45fSAndroid Build Coastguard Worker         frontend::LayerSnapshotBuilder::Args
2508*38e8c45fSAndroid Build Coastguard Worker                 args{.root = mLayerHierarchyBuilder.getHierarchy(),
2509*38e8c45fSAndroid Build Coastguard Worker                      .layerLifecycleManager = mLayerLifecycleManager,
2510*38e8c45fSAndroid Build Coastguard Worker                      .includeMetadata = mCompositionEngine->getFeatureFlags().test(
2511*38e8c45fSAndroid Build Coastguard Worker                              compositionengine::Feature::kSnapshotLayerMetadata),
2512*38e8c45fSAndroid Build Coastguard Worker                      .displays = mFrontEndDisplayInfos,
2513*38e8c45fSAndroid Build Coastguard Worker                      .displayChanges = mFrontEndDisplayInfosChanged,
2514*38e8c45fSAndroid Build Coastguard Worker                      .globalShadowSettings = mDrawingState.globalShadowSettings,
2515*38e8c45fSAndroid Build Coastguard Worker                      .supportsBlur = mSupportsBlur,
2516*38e8c45fSAndroid Build Coastguard Worker                      .forceFullDamage = mForceFullDamage,
2517*38e8c45fSAndroid Build Coastguard Worker                      .supportedLayerGenericMetadata =
2518*38e8c45fSAndroid Build Coastguard Worker                              getHwComposer().getSupportedLayerGenericMetadata(),
2519*38e8c45fSAndroid Build Coastguard Worker                      .genericLayerMetadataKeyMap = getGenericLayerMetadataKeyMap(),
2520*38e8c45fSAndroid Build Coastguard Worker                      .skipRoundCornersWhenProtected =
2521*38e8c45fSAndroid Build Coastguard Worker                              !getRenderEngine().supportsProtectedContent()};
2522*38e8c45fSAndroid Build Coastguard Worker         mLayerSnapshotBuilder.update(args);
2523*38e8c45fSAndroid Build Coastguard Worker     }
2524*38e8c45fSAndroid Build Coastguard Worker 
2525*38e8c45fSAndroid Build Coastguard Worker     if (mLayerLifecycleManager.getGlobalChanges().any(Changes::Geometry | Changes::Input |
2526*38e8c45fSAndroid Build Coastguard Worker                                                       Changes::Hierarchy | Changes::Visibility)) {
2527*38e8c45fSAndroid Build Coastguard Worker         mUpdateInputInfo = true;
2528*38e8c45fSAndroid Build Coastguard Worker     }
2529*38e8c45fSAndroid Build Coastguard Worker     if (mLayerLifecycleManager.getGlobalChanges().any(Changes::VisibleRegion | Changes::Hierarchy |
2530*38e8c45fSAndroid Build Coastguard Worker                                                       Changes::Visibility | Changes::Geometry)) {
2531*38e8c45fSAndroid Build Coastguard Worker         mVisibleRegionsDirty = true;
2532*38e8c45fSAndroid Build Coastguard Worker     }
2533*38e8c45fSAndroid Build Coastguard Worker     if (mLayerLifecycleManager.getGlobalChanges().any(Changes::Hierarchy | Changes::FrameRate)) {
2534*38e8c45fSAndroid Build Coastguard Worker         // The frame rate of attached choreographers can only change as a result of a
2535*38e8c45fSAndroid Build Coastguard Worker         // FrameRate change (including when Hierarchy changes).
2536*38e8c45fSAndroid Build Coastguard Worker         mUpdateAttachedChoreographer = true;
2537*38e8c45fSAndroid Build Coastguard Worker     }
2538*38e8c45fSAndroid Build Coastguard Worker     outTransactionsAreEmpty = mLayerLifecycleManager.getGlobalChanges().get() == 0;
2539*38e8c45fSAndroid Build Coastguard Worker     if (FlagManager::getInstance().vrr_bugfix_24q4()) {
2540*38e8c45fSAndroid Build Coastguard Worker         mustComposite |= mLayerLifecycleManager.getGlobalChanges().any(
2541*38e8c45fSAndroid Build Coastguard Worker                 frontend::RequestedLayerState::kMustComposite);
2542*38e8c45fSAndroid Build Coastguard Worker     } else {
2543*38e8c45fSAndroid Build Coastguard Worker         mustComposite |= mLayerLifecycleManager.getGlobalChanges().get() != 0;
2544*38e8c45fSAndroid Build Coastguard Worker     }
2545*38e8c45fSAndroid Build Coastguard Worker 
2546*38e8c45fSAndroid Build Coastguard Worker     bool newDataLatched = false;
2547*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_NAME("DisplayCallbackAndStatsUpdates");
2548*38e8c45fSAndroid Build Coastguard Worker     mustComposite |= applyTransactionsLocked(update.transactions);
2549*38e8c45fSAndroid Build Coastguard Worker     traverseLegacyLayers([&](Layer* layer) { layer->commitTransaction(); });
2550*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t latchTime = systemTime();
2551*38e8c45fSAndroid Build Coastguard Worker     bool unused = false;
2552*38e8c45fSAndroid Build Coastguard Worker 
2553*38e8c45fSAndroid Build Coastguard Worker     for (auto& layer : mLayerLifecycleManager.getLayers()) {
2554*38e8c45fSAndroid Build Coastguard Worker         if (layer->changes.test(frontend::RequestedLayerState::Changes::Created) &&
2555*38e8c45fSAndroid Build Coastguard Worker             layer->bgColorLayer) {
2556*38e8c45fSAndroid Build Coastguard Worker             sp<Layer> bgColorLayer = getFactory().createEffectLayer(
2557*38e8c45fSAndroid Build Coastguard Worker                     LayerCreationArgs(this, nullptr, layer->name,
2558*38e8c45fSAndroid Build Coastguard Worker                                       ISurfaceComposerClient::eFXSurfaceEffect, LayerMetadata(),
2559*38e8c45fSAndroid Build Coastguard Worker                                       std::make_optional(layer->id), true));
2560*38e8c45fSAndroid Build Coastguard Worker             mLegacyLayers[bgColorLayer->sequence] = bgColorLayer;
2561*38e8c45fSAndroid Build Coastguard Worker         }
2562*38e8c45fSAndroid Build Coastguard Worker         const bool willReleaseBufferOnLatch = layer->willReleaseBufferOnLatch();
2563*38e8c45fSAndroid Build Coastguard Worker 
2564*38e8c45fSAndroid Build Coastguard Worker         auto it = mLegacyLayers.find(layer->id);
2565*38e8c45fSAndroid Build Coastguard Worker         if (it == mLegacyLayers.end() &&
2566*38e8c45fSAndroid Build Coastguard Worker             layer->changes.test(frontend::RequestedLayerState::Changes::Destroyed)) {
2567*38e8c45fSAndroid Build Coastguard Worker             // Layer handle was created and immediately destroyed. It was destroyed before it
2568*38e8c45fSAndroid Build Coastguard Worker             // was added to the map.
2569*38e8c45fSAndroid Build Coastguard Worker             continue;
2570*38e8c45fSAndroid Build Coastguard Worker         }
2571*38e8c45fSAndroid Build Coastguard Worker 
2572*38e8c45fSAndroid Build Coastguard Worker         LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
2573*38e8c45fSAndroid Build Coastguard Worker                                         "Couldnt find layer object for %s",
2574*38e8c45fSAndroid Build Coastguard Worker                                         layer->getDebugString().c_str());
2575*38e8c45fSAndroid Build Coastguard Worker         if (!layer->hasReadyFrame() && !willReleaseBufferOnLatch) {
2576*38e8c45fSAndroid Build Coastguard Worker             if (!it->second->hasBuffer()) {
2577*38e8c45fSAndroid Build Coastguard Worker                 // The last latch time is used to classify a missed frame as buffer stuffing
2578*38e8c45fSAndroid Build Coastguard Worker                 // instead of a missed frame. This is used to identify scenarios where we
2579*38e8c45fSAndroid Build Coastguard Worker                 // could not latch a buffer or apply a transaction due to backpressure.
2580*38e8c45fSAndroid Build Coastguard Worker                 // We only update the latch time for buffer less layers here, the latch time
2581*38e8c45fSAndroid Build Coastguard Worker                 // is updated for buffer layers when the buffer is latched.
2582*38e8c45fSAndroid Build Coastguard Worker                 it->second->updateLastLatchTime(latchTime);
2583*38e8c45fSAndroid Build Coastguard Worker             }
2584*38e8c45fSAndroid Build Coastguard Worker             continue;
2585*38e8c45fSAndroid Build Coastguard Worker         }
2586*38e8c45fSAndroid Build Coastguard Worker 
2587*38e8c45fSAndroid Build Coastguard Worker         const bool bgColorOnly =
2588*38e8c45fSAndroid Build Coastguard Worker                 !layer->externalTexture && (layer->bgColorLayerId != UNASSIGNED_LAYER_ID);
2589*38e8c45fSAndroid Build Coastguard Worker         if (willReleaseBufferOnLatch) {
2590*38e8c45fSAndroid Build Coastguard Worker             mLayersWithBuffersRemoved.emplace(it->second);
2591*38e8c45fSAndroid Build Coastguard Worker         }
2592*38e8c45fSAndroid Build Coastguard Worker         it->second->latchBufferImpl(unused, latchTime, bgColorOnly);
2593*38e8c45fSAndroid Build Coastguard Worker         newDataLatched = true;
2594*38e8c45fSAndroid Build Coastguard Worker 
2595*38e8c45fSAndroid Build Coastguard Worker         frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(it->second->sequence);
2596*38e8c45fSAndroid Build Coastguard Worker         gui::GameMode gameMode = (snapshot) ? snapshot->gameMode : gui::GameMode::Unsupported;
2597*38e8c45fSAndroid Build Coastguard Worker         mLayersWithQueuedFrames.emplace(it->second, gameMode);
2598*38e8c45fSAndroid Build Coastguard Worker     }
2599*38e8c45fSAndroid Build Coastguard Worker 
2600*38e8c45fSAndroid Build Coastguard Worker     updateLayerHistory(latchTime);
2601*38e8c45fSAndroid Build Coastguard Worker     mLayerSnapshotBuilder.forEachSnapshot([&](const frontend::LayerSnapshot& snapshot) {
2602*38e8c45fSAndroid Build Coastguard Worker         // update output's dirty region if a snapshot is visible and its
2603*38e8c45fSAndroid Build Coastguard Worker         // content is dirty or if a snapshot recently became invisible
2604*38e8c45fSAndroid Build Coastguard Worker         if ((snapshot.isVisible && snapshot.contentDirty) ||
2605*38e8c45fSAndroid Build Coastguard Worker             (!snapshot.isVisible && snapshot.changes.test(Changes::Visibility))) {
2606*38e8c45fSAndroid Build Coastguard Worker             Region visibleReg;
2607*38e8c45fSAndroid Build Coastguard Worker             visibleReg.set(snapshot.transformedBoundsWithoutTransparentRegion);
2608*38e8c45fSAndroid Build Coastguard Worker             invalidateLayerStack(snapshot.outputFilter, visibleReg);
2609*38e8c45fSAndroid Build Coastguard Worker         }
2610*38e8c45fSAndroid Build Coastguard Worker     });
2611*38e8c45fSAndroid Build Coastguard Worker 
2612*38e8c45fSAndroid Build Coastguard Worker     for (auto& destroyedLayer : mLayerLifecycleManager.getDestroyedLayers()) {
2613*38e8c45fSAndroid Build Coastguard Worker         mLegacyLayers.erase(destroyedLayer->id);
2614*38e8c45fSAndroid Build Coastguard Worker     }
2615*38e8c45fSAndroid Build Coastguard Worker 
2616*38e8c45fSAndroid Build Coastguard Worker     {
2617*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_NAME("LayerLifecycleManager:commitChanges");
2618*38e8c45fSAndroid Build Coastguard Worker         mLayerLifecycleManager.commitChanges();
2619*38e8c45fSAndroid Build Coastguard Worker     }
2620*38e8c45fSAndroid Build Coastguard Worker 
2621*38e8c45fSAndroid Build Coastguard Worker     // enter boot animation on first buffer latch
2622*38e8c45fSAndroid Build Coastguard Worker     if (CC_UNLIKELY(mBootStage == BootStage::BOOTLOADER && newDataLatched)) {
2623*38e8c45fSAndroid Build Coastguard Worker         ALOGI("Enter boot animation");
2624*38e8c45fSAndroid Build Coastguard Worker         mBootStage = BootStage::BOOTANIMATION;
2625*38e8c45fSAndroid Build Coastguard Worker     }
2626*38e8c45fSAndroid Build Coastguard Worker 
2627*38e8c45fSAndroid Build Coastguard Worker     mustComposite |= (getTransactionFlags() & ~eTransactionFlushNeeded) || newDataLatched;
2628*38e8c45fSAndroid Build Coastguard Worker     if (mustComposite) {
2629*38e8c45fSAndroid Build Coastguard Worker         commitTransactions();
2630*38e8c45fSAndroid Build Coastguard Worker     }
2631*38e8c45fSAndroid Build Coastguard Worker 
2632*38e8c45fSAndroid Build Coastguard Worker     return mustComposite;
2633*38e8c45fSAndroid Build Coastguard Worker }
2634*38e8c45fSAndroid Build Coastguard Worker 
commit(PhysicalDisplayId pacesetterId,const scheduler::FrameTargets & frameTargets)2635*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId,
2636*38e8c45fSAndroid Build Coastguard Worker                             const scheduler::FrameTargets& frameTargets) {
2637*38e8c45fSAndroid Build Coastguard Worker     const scheduler::FrameTarget& pacesetterFrameTarget = *frameTargets.get(pacesetterId)->get();
2638*38e8c45fSAndroid Build Coastguard Worker 
2639*38e8c45fSAndroid Build Coastguard Worker     const VsyncId vsyncId = pacesetterFrameTarget.vsyncId();
2640*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_NAME(ftl::Concat(__func__, ' ', ftl::to_underlying(vsyncId)).c_str());
2641*38e8c45fSAndroid Build Coastguard Worker 
2642*38e8c45fSAndroid Build Coastguard Worker     if (pacesetterFrameTarget.didMissFrame()) {
2643*38e8c45fSAndroid Build Coastguard Worker         mTimeStats->incrementMissedFrames();
2644*38e8c45fSAndroid Build Coastguard Worker     }
2645*38e8c45fSAndroid Build Coastguard Worker 
2646*38e8c45fSAndroid Build Coastguard Worker     // If a mode set is pending and the fence hasn't fired yet, wait for the next commit.
2647*38e8c45fSAndroid Build Coastguard Worker     if (std::any_of(frameTargets.begin(), frameTargets.end(),
2648*38e8c45fSAndroid Build Coastguard Worker                     [this](const auto& pair) FTL_FAKE_GUARD(kMainThreadContext) {
2649*38e8c45fSAndroid Build Coastguard Worker                         const auto [displayId, target] = pair;
2650*38e8c45fSAndroid Build Coastguard Worker                         return target->isFramePending() &&
2651*38e8c45fSAndroid Build Coastguard Worker                                 mDisplayModeController.isModeSetPending(displayId);
2652*38e8c45fSAndroid Build Coastguard Worker                     })) {
2653*38e8c45fSAndroid Build Coastguard Worker         mScheduler->scheduleFrame();
2654*38e8c45fSAndroid Build Coastguard Worker         return false;
2655*38e8c45fSAndroid Build Coastguard Worker     }
2656*38e8c45fSAndroid Build Coastguard Worker 
2657*38e8c45fSAndroid Build Coastguard Worker     {
2658*38e8c45fSAndroid Build Coastguard Worker         Mutex::Autolock lock(mStateLock);
2659*38e8c45fSAndroid Build Coastguard Worker 
2660*38e8c45fSAndroid Build Coastguard Worker         for (const auto [displayId, _] : frameTargets) {
2661*38e8c45fSAndroid Build Coastguard Worker             if (mDisplayModeController.isModeSetPending(displayId)) {
2662*38e8c45fSAndroid Build Coastguard Worker                 finalizeDisplayModeChange(displayId);
2663*38e8c45fSAndroid Build Coastguard Worker             }
2664*38e8c45fSAndroid Build Coastguard Worker         }
2665*38e8c45fSAndroid Build Coastguard Worker     }
2666*38e8c45fSAndroid Build Coastguard Worker 
2667*38e8c45fSAndroid Build Coastguard Worker     if (pacesetterFrameTarget.wouldBackpressureHwc()) {
2668*38e8c45fSAndroid Build Coastguard Worker         if (mBackpressureGpuComposition || pacesetterFrameTarget.didMissHwcFrame()) {
2669*38e8c45fSAndroid Build Coastguard Worker             if (FlagManager::getInstance().vrr_config()) {
2670*38e8c45fSAndroid Build Coastguard Worker                 mScheduler->getVsyncSchedule()->getTracker().onFrameMissed(
2671*38e8c45fSAndroid Build Coastguard Worker                         pacesetterFrameTarget.expectedPresentTime());
2672*38e8c45fSAndroid Build Coastguard Worker             }
2673*38e8c45fSAndroid Build Coastguard Worker             const Duration slack = FlagManager::getInstance().allow_n_vsyncs_in_targeter()
2674*38e8c45fSAndroid Build Coastguard Worker                     ? TimePoint::now() - pacesetterFrameTarget.frameBeginTime()
2675*38e8c45fSAndroid Build Coastguard Worker                     : Duration::fromNs(0);
2676*38e8c45fSAndroid Build Coastguard Worker             scheduleCommit(FrameHint::kNone, slack);
2677*38e8c45fSAndroid Build Coastguard Worker             return false;
2678*38e8c45fSAndroid Build Coastguard Worker         }
2679*38e8c45fSAndroid Build Coastguard Worker     }
2680*38e8c45fSAndroid Build Coastguard Worker 
2681*38e8c45fSAndroid Build Coastguard Worker     const Period vsyncPeriod = mScheduler->getVsyncSchedule()->period();
2682*38e8c45fSAndroid Build Coastguard Worker 
2683*38e8c45fSAndroid Build Coastguard Worker     // Save this once per commit + composite to ensure consistency
2684*38e8c45fSAndroid Build Coastguard Worker     // TODO (b/240619471): consider removing active display check once AOD is fixed
2685*38e8c45fSAndroid Build Coastguard Worker     const auto activeDisplay = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(mActiveDisplayId));
2686*38e8c45fSAndroid Build Coastguard Worker     mPowerHintSessionEnabled = mPowerAdvisor->usePowerHintSession() && activeDisplay &&
2687*38e8c45fSAndroid Build Coastguard Worker             activeDisplay->getPowerMode() == hal::PowerMode::ON;
2688*38e8c45fSAndroid Build Coastguard Worker     if (mPowerHintSessionEnabled) {
2689*38e8c45fSAndroid Build Coastguard Worker         mPowerAdvisor->setCommitStart(pacesetterFrameTarget.frameBeginTime());
2690*38e8c45fSAndroid Build Coastguard Worker         mPowerAdvisor->setExpectedPresentTime(pacesetterFrameTarget.expectedPresentTime());
2691*38e8c45fSAndroid Build Coastguard Worker 
2692*38e8c45fSAndroid Build Coastguard Worker         // Frame delay is how long we should have minus how long we actually have.
2693*38e8c45fSAndroid Build Coastguard Worker         const Duration idealSfWorkDuration =
2694*38e8c45fSAndroid Build Coastguard Worker                 mScheduler->vsyncModulator().getVsyncConfig().sfWorkDuration;
2695*38e8c45fSAndroid Build Coastguard Worker         const Duration frameDelay =
2696*38e8c45fSAndroid Build Coastguard Worker                 idealSfWorkDuration - pacesetterFrameTarget.expectedFrameDuration();
2697*38e8c45fSAndroid Build Coastguard Worker 
2698*38e8c45fSAndroid Build Coastguard Worker         mPowerAdvisor->setFrameDelay(frameDelay);
2699*38e8c45fSAndroid Build Coastguard Worker         mPowerAdvisor->setTotalFrameTargetWorkDuration(idealSfWorkDuration);
2700*38e8c45fSAndroid Build Coastguard Worker 
2701*38e8c45fSAndroid Build Coastguard Worker         const Period idealVsyncPeriod =
2702*38e8c45fSAndroid Build Coastguard Worker                 mDisplayModeController.getActiveMode(pacesetterId).fps.getPeriod();
2703*38e8c45fSAndroid Build Coastguard Worker         mPowerAdvisor->updateTargetWorkDuration(idealVsyncPeriod);
2704*38e8c45fSAndroid Build Coastguard Worker     }
2705*38e8c45fSAndroid Build Coastguard Worker 
2706*38e8c45fSAndroid Build Coastguard Worker     if (mRefreshRateOverlaySpinner || mHdrSdrRatioOverlay) {
2707*38e8c45fSAndroid Build Coastguard Worker         Mutex::Autolock lock(mStateLock);
2708*38e8c45fSAndroid Build Coastguard Worker         if (const auto display = getDefaultDisplayDeviceLocked()) {
2709*38e8c45fSAndroid Build Coastguard Worker             display->animateOverlay();
2710*38e8c45fSAndroid Build Coastguard Worker         }
2711*38e8c45fSAndroid Build Coastguard Worker     }
2712*38e8c45fSAndroid Build Coastguard Worker 
2713*38e8c45fSAndroid Build Coastguard Worker     // Composite if transactions were committed, or if requested by HWC.
2714*38e8c45fSAndroid Build Coastguard Worker     bool mustComposite = mMustComposite.exchange(false);
2715*38e8c45fSAndroid Build Coastguard Worker     {
2716*38e8c45fSAndroid Build Coastguard Worker         mFrameTimeline->setSfWakeUp(ftl::to_underlying(vsyncId),
2717*38e8c45fSAndroid Build Coastguard Worker                                     pacesetterFrameTarget.frameBeginTime().ns(),
2718*38e8c45fSAndroid Build Coastguard Worker                                     Fps::fromPeriodNsecs(vsyncPeriod.ns()),
2719*38e8c45fSAndroid Build Coastguard Worker                                     mScheduler->getPacesetterRefreshRate());
2720*38e8c45fSAndroid Build Coastguard Worker 
2721*38e8c45fSAndroid Build Coastguard Worker         const bool flushTransactions = clearTransactionFlags(eTransactionFlushNeeded);
2722*38e8c45fSAndroid Build Coastguard Worker         bool transactionsAreEmpty = false;
2723*38e8c45fSAndroid Build Coastguard Worker         mustComposite |= updateLayerSnapshots(vsyncId, pacesetterFrameTarget.frameBeginTime().ns(),
2724*38e8c45fSAndroid Build Coastguard Worker                                               flushTransactions, transactionsAreEmpty);
2725*38e8c45fSAndroid Build Coastguard Worker 
2726*38e8c45fSAndroid Build Coastguard Worker         // Tell VsyncTracker that we are going to present this frame before scheduling
2727*38e8c45fSAndroid Build Coastguard Worker         // setTransactionFlags which will schedule another SF frame. This was if the tracker
2728*38e8c45fSAndroid Build Coastguard Worker         // needs to adjust the vsync timeline, it will be done before the next frame.
2729*38e8c45fSAndroid Build Coastguard Worker         if (FlagManager::getInstance().vrr_config() && mustComposite) {
2730*38e8c45fSAndroid Build Coastguard Worker             mScheduler->getVsyncSchedule()->getTracker().onFrameBegin(
2731*38e8c45fSAndroid Build Coastguard Worker                 pacesetterFrameTarget.expectedPresentTime(),
2732*38e8c45fSAndroid Build Coastguard Worker                 pacesetterFrameTarget.lastSignaledFrameTime());
2733*38e8c45fSAndroid Build Coastguard Worker         }
2734*38e8c45fSAndroid Build Coastguard Worker         if (transactionFlushNeeded()) {
2735*38e8c45fSAndroid Build Coastguard Worker             setTransactionFlags(eTransactionFlushNeeded);
2736*38e8c45fSAndroid Build Coastguard Worker         }
2737*38e8c45fSAndroid Build Coastguard Worker 
2738*38e8c45fSAndroid Build Coastguard Worker         // This has to be called after latchBuffers because we want to include the layers that have
2739*38e8c45fSAndroid Build Coastguard Worker         // been latched in the commit callback
2740*38e8c45fSAndroid Build Coastguard Worker         if (transactionsAreEmpty) {
2741*38e8c45fSAndroid Build Coastguard Worker             // Invoke empty transaction callbacks early.
2742*38e8c45fSAndroid Build Coastguard Worker             mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
2743*38e8c45fSAndroid Build Coastguard Worker         } else {
2744*38e8c45fSAndroid Build Coastguard Worker             // Invoke OnCommit callbacks.
2745*38e8c45fSAndroid Build Coastguard Worker             mTransactionCallbackInvoker.sendCallbacks(true /* onCommitOnly */);
2746*38e8c45fSAndroid Build Coastguard Worker         }
2747*38e8c45fSAndroid Build Coastguard Worker     }
2748*38e8c45fSAndroid Build Coastguard Worker 
2749*38e8c45fSAndroid Build Coastguard Worker     // Layers need to get updated (in the previous line) before we can use them for
2750*38e8c45fSAndroid Build Coastguard Worker     // choosing the refresh rate.
2751*38e8c45fSAndroid Build Coastguard Worker     // Hold mStateLock as chooseRefreshRateForContent promotes wp<Layer> to sp<Layer>
2752*38e8c45fSAndroid Build Coastguard Worker     // and may eventually call to ~Layer() if it holds the last reference
2753*38e8c45fSAndroid Build Coastguard Worker     {
2754*38e8c45fSAndroid Build Coastguard Worker         bool updateAttachedChoreographer = mUpdateAttachedChoreographer;
2755*38e8c45fSAndroid Build Coastguard Worker         mUpdateAttachedChoreographer = false;
2756*38e8c45fSAndroid Build Coastguard Worker 
2757*38e8c45fSAndroid Build Coastguard Worker         Mutex::Autolock lock(mStateLock);
2758*38e8c45fSAndroid Build Coastguard Worker         mScheduler->chooseRefreshRateForContent(&mLayerHierarchyBuilder.getHierarchy(),
2759*38e8c45fSAndroid Build Coastguard Worker                                                 updateAttachedChoreographer);
2760*38e8c45fSAndroid Build Coastguard Worker 
2761*38e8c45fSAndroid Build Coastguard Worker         initiateDisplayModeChanges();
2762*38e8c45fSAndroid Build Coastguard Worker     }
2763*38e8c45fSAndroid Build Coastguard Worker 
2764*38e8c45fSAndroid Build Coastguard Worker     updateCursorAsync();
2765*38e8c45fSAndroid Build Coastguard Worker     if (!mustComposite) {
2766*38e8c45fSAndroid Build Coastguard Worker         updateInputFlinger(vsyncId, pacesetterFrameTarget.frameBeginTime());
2767*38e8c45fSAndroid Build Coastguard Worker     }
2768*38e8c45fSAndroid Build Coastguard Worker     doActiveLayersTracingIfNeeded(false, mVisibleRegionsDirty,
2769*38e8c45fSAndroid Build Coastguard Worker                                   pacesetterFrameTarget.frameBeginTime(), vsyncId);
2770*38e8c45fSAndroid Build Coastguard Worker 
2771*38e8c45fSAndroid Build Coastguard Worker     mLastCommittedVsyncId = vsyncId;
2772*38e8c45fSAndroid Build Coastguard Worker 
2773*38e8c45fSAndroid Build Coastguard Worker     persistDisplayBrightness(mustComposite);
2774*38e8c45fSAndroid Build Coastguard Worker 
2775*38e8c45fSAndroid Build Coastguard Worker     return mustComposite && CC_LIKELY(mBootStage != BootStage::BOOTLOADER);
2776*38e8c45fSAndroid Build Coastguard Worker }
2777*38e8c45fSAndroid Build Coastguard Worker 
composite(PhysicalDisplayId pacesetterId,const scheduler::FrameTargeters & frameTargeters)2778*38e8c45fSAndroid Build Coastguard Worker CompositeResultsPerDisplay SurfaceFlinger::composite(
2779*38e8c45fSAndroid Build Coastguard Worker         PhysicalDisplayId pacesetterId, const scheduler::FrameTargeters& frameTargeters) {
2780*38e8c45fSAndroid Build Coastguard Worker     const scheduler::FrameTarget& pacesetterTarget =
2781*38e8c45fSAndroid Build Coastguard Worker             frameTargeters.get(pacesetterId)->get()->target();
2782*38e8c45fSAndroid Build Coastguard Worker 
2783*38e8c45fSAndroid Build Coastguard Worker     const VsyncId vsyncId = pacesetterTarget.vsyncId();
2784*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_NAME(ftl::Concat(__func__, ' ', ftl::to_underlying(vsyncId)).c_str());
2785*38e8c45fSAndroid Build Coastguard Worker 
2786*38e8c45fSAndroid Build Coastguard Worker     compositionengine::CompositionRefreshArgs refreshArgs;
2787*38e8c45fSAndroid Build Coastguard Worker     refreshArgs.powerCallback = this;
2788*38e8c45fSAndroid Build Coastguard Worker     const auto& displays = FTL_FAKE_GUARD(mStateLock, mDisplays);
2789*38e8c45fSAndroid Build Coastguard Worker     refreshArgs.outputs.reserve(displays.size());
2790*38e8c45fSAndroid Build Coastguard Worker 
2791*38e8c45fSAndroid Build Coastguard Worker     // Add outputs for physical displays.
2792*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [id, targeter] : frameTargeters) {
2793*38e8c45fSAndroid Build Coastguard Worker         ftl::FakeGuard guard(mStateLock);
2794*38e8c45fSAndroid Build Coastguard Worker 
2795*38e8c45fSAndroid Build Coastguard Worker         if (const auto display = getCompositionDisplayLocked(id)) {
2796*38e8c45fSAndroid Build Coastguard Worker             refreshArgs.outputs.push_back(display);
2797*38e8c45fSAndroid Build Coastguard Worker         }
2798*38e8c45fSAndroid Build Coastguard Worker 
2799*38e8c45fSAndroid Build Coastguard Worker         refreshArgs.frameTargets.try_emplace(id, &targeter->target());
2800*38e8c45fSAndroid Build Coastguard Worker     }
2801*38e8c45fSAndroid Build Coastguard Worker 
2802*38e8c45fSAndroid Build Coastguard Worker     std::vector<DisplayId> displayIds;
2803*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [_, display] : displays) {
2804*38e8c45fSAndroid Build Coastguard Worker         displayIds.push_back(display->getId());
2805*38e8c45fSAndroid Build Coastguard Worker         display->tracePowerMode();
2806*38e8c45fSAndroid Build Coastguard Worker 
2807*38e8c45fSAndroid Build Coastguard Worker         // Add outputs for virtual displays.
2808*38e8c45fSAndroid Build Coastguard Worker         if (display->isVirtual()) {
2809*38e8c45fSAndroid Build Coastguard Worker             const Fps refreshRate = display->getAdjustedRefreshRate();
2810*38e8c45fSAndroid Build Coastguard Worker 
2811*38e8c45fSAndroid Build Coastguard Worker             if (!refreshRate.isValid() ||
2812*38e8c45fSAndroid Build Coastguard Worker                 mScheduler->isVsyncInPhase(pacesetterTarget.frameBeginTime(), refreshRate)) {
2813*38e8c45fSAndroid Build Coastguard Worker                 refreshArgs.outputs.push_back(display->getCompositionDisplay());
2814*38e8c45fSAndroid Build Coastguard Worker             }
2815*38e8c45fSAndroid Build Coastguard Worker         }
2816*38e8c45fSAndroid Build Coastguard Worker     }
2817*38e8c45fSAndroid Build Coastguard Worker     mPowerAdvisor->setDisplays(displayIds);
2818*38e8c45fSAndroid Build Coastguard Worker 
2819*38e8c45fSAndroid Build Coastguard Worker     const bool updateTaskMetadata = mCompositionEngine->getFeatureFlags().test(
2820*38e8c45fSAndroid Build Coastguard Worker             compositionengine::Feature::kSnapshotLayerMetadata);
2821*38e8c45fSAndroid Build Coastguard Worker 
2822*38e8c45fSAndroid Build Coastguard Worker     refreshArgs.bufferIdsToUncache = std::move(mBufferIdsToUncache);
2823*38e8c45fSAndroid Build Coastguard Worker     refreshArgs.outputColorSetting = mDisplayColorSetting;
2824*38e8c45fSAndroid Build Coastguard Worker     refreshArgs.forceOutputColorMode = mForceColorMode;
2825*38e8c45fSAndroid Build Coastguard Worker 
2826*38e8c45fSAndroid Build Coastguard Worker     refreshArgs.updatingOutputGeometryThisFrame = mVisibleRegionsDirty;
2827*38e8c45fSAndroid Build Coastguard Worker     refreshArgs.updatingGeometryThisFrame = mGeometryDirty.exchange(false) ||
2828*38e8c45fSAndroid Build Coastguard Worker             mVisibleRegionsDirty || mDrawingState.colorMatrixChanged;
2829*38e8c45fSAndroid Build Coastguard Worker     refreshArgs.internalDisplayRotationFlags = getActiveDisplayRotationFlags();
2830*38e8c45fSAndroid Build Coastguard Worker 
2831*38e8c45fSAndroid Build Coastguard Worker     if (CC_UNLIKELY(mDrawingState.colorMatrixChanged)) {
2832*38e8c45fSAndroid Build Coastguard Worker         refreshArgs.colorTransformMatrix = mDrawingState.colorMatrix;
2833*38e8c45fSAndroid Build Coastguard Worker         mDrawingState.colorMatrixChanged = false;
2834*38e8c45fSAndroid Build Coastguard Worker     }
2835*38e8c45fSAndroid Build Coastguard Worker 
2836*38e8c45fSAndroid Build Coastguard Worker     refreshArgs.devOptForceClientComposition = mDebugDisableHWC;
2837*38e8c45fSAndroid Build Coastguard Worker 
2838*38e8c45fSAndroid Build Coastguard Worker     if (mDebugFlashDelay != 0) {
2839*38e8c45fSAndroid Build Coastguard Worker         refreshArgs.devOptForceClientComposition = true;
2840*38e8c45fSAndroid Build Coastguard Worker         refreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::milliseconds(mDebugFlashDelay);
2841*38e8c45fSAndroid Build Coastguard Worker     }
2842*38e8c45fSAndroid Build Coastguard Worker 
2843*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/255601557) Update frameInterval per display
2844*38e8c45fSAndroid Build Coastguard Worker     refreshArgs.frameInterval =
2845*38e8c45fSAndroid Build Coastguard Worker             mScheduler->getNextFrameInterval(pacesetterId, pacesetterTarget.expectedPresentTime());
2846*38e8c45fSAndroid Build Coastguard Worker     const auto scheduledFrameResultOpt = mScheduler->getScheduledFrameResult();
2847*38e8c45fSAndroid Build Coastguard Worker     const auto scheduledFrameTimeOpt = scheduledFrameResultOpt
2848*38e8c45fSAndroid Build Coastguard Worker             ? std::optional{scheduledFrameResultOpt->callbackTime}
2849*38e8c45fSAndroid Build Coastguard Worker             : std::nullopt;
2850*38e8c45fSAndroid Build Coastguard Worker     refreshArgs.scheduledFrameTime = scheduledFrameTimeOpt;
2851*38e8c45fSAndroid Build Coastguard Worker     refreshArgs.hasTrustedPresentationListener = mNumTrustedPresentationListeners > 0;
2852*38e8c45fSAndroid Build Coastguard Worker     // Store the present time just before calling to the composition engine so we could notify
2853*38e8c45fSAndroid Build Coastguard Worker     // the scheduler.
2854*38e8c45fSAndroid Build Coastguard Worker     const auto presentTime = systemTime();
2855*38e8c45fSAndroid Build Coastguard Worker 
2856*38e8c45fSAndroid Build Coastguard Worker     constexpr bool kCursorOnly = false;
2857*38e8c45fSAndroid Build Coastguard Worker     const auto layers = moveSnapshotsToCompositionArgs(refreshArgs, kCursorOnly);
2858*38e8c45fSAndroid Build Coastguard Worker 
2859*38e8c45fSAndroid Build Coastguard Worker     if (!mVisibleRegionsDirty) {
2860*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [token, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
2861*38e8c45fSAndroid Build Coastguard Worker             auto compositionDisplay = display->getCompositionDisplay();
2862*38e8c45fSAndroid Build Coastguard Worker             if (!compositionDisplay->getState().isEnabled) continue;
2863*38e8c45fSAndroid Build Coastguard Worker             for (auto outputLayer : compositionDisplay->getOutputLayersOrderedByZ()) {
2864*38e8c45fSAndroid Build Coastguard Worker                 if (outputLayer->getLayerFE().getCompositionState() == nullptr) {
2865*38e8c45fSAndroid Build Coastguard Worker                     // This is unexpected but instead of crashing, capture traces to disk
2866*38e8c45fSAndroid Build Coastguard Worker                     // and recover gracefully by forcing CE to rebuild layer stack.
2867*38e8c45fSAndroid Build Coastguard Worker                     ALOGE("Output layer %s for display %s %" PRIu64 " has a null "
2868*38e8c45fSAndroid Build Coastguard Worker                           "snapshot. Forcing mVisibleRegionsDirty",
2869*38e8c45fSAndroid Build Coastguard Worker                           outputLayer->getLayerFE().getDebugName(),
2870*38e8c45fSAndroid Build Coastguard Worker                           compositionDisplay->getName().c_str(), compositionDisplay->getId().value);
2871*38e8c45fSAndroid Build Coastguard Worker 
2872*38e8c45fSAndroid Build Coastguard Worker                     TransactionTraceWriter::getInstance().invoke(__func__, /* overwrite= */ false);
2873*38e8c45fSAndroid Build Coastguard Worker                     mVisibleRegionsDirty = true;
2874*38e8c45fSAndroid Build Coastguard Worker                     refreshArgs.updatingOutputGeometryThisFrame = mVisibleRegionsDirty;
2875*38e8c45fSAndroid Build Coastguard Worker                     refreshArgs.updatingGeometryThisFrame = mVisibleRegionsDirty;
2876*38e8c45fSAndroid Build Coastguard Worker                 }
2877*38e8c45fSAndroid Build Coastguard Worker             }
2878*38e8c45fSAndroid Build Coastguard Worker         }
2879*38e8c45fSAndroid Build Coastguard Worker     }
2880*38e8c45fSAndroid Build Coastguard Worker 
2881*38e8c45fSAndroid Build Coastguard Worker     refreshArgs.refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
2882*38e8c45fSAndroid Build Coastguard Worker     for (auto& [layer, layerFE] : layers) {
2883*38e8c45fSAndroid Build Coastguard Worker         layer->onPreComposition(refreshArgs.refreshStartTime);
2884*38e8c45fSAndroid Build Coastguard Worker     }
2885*38e8c45fSAndroid Build Coastguard Worker 
2886*38e8c45fSAndroid Build Coastguard Worker     for (auto& [layer, layerFE] : layers) {
2887*38e8c45fSAndroid Build Coastguard Worker         attachReleaseFenceFutureToLayer(layer, layerFE,
2888*38e8c45fSAndroid Build Coastguard Worker                                         layerFE->mSnapshot->outputFilter.layerStack);
2889*38e8c45fSAndroid Build Coastguard Worker     }
2890*38e8c45fSAndroid Build Coastguard Worker 
2891*38e8c45fSAndroid Build Coastguard Worker     refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
2892*38e8c45fSAndroid Build Coastguard Worker     for (auto& [layer, _] : mLayersWithQueuedFrames) {
2893*38e8c45fSAndroid Build Coastguard Worker         if (const auto& layerFE =
2894*38e8c45fSAndroid Build Coastguard Worker                     layer->getCompositionEngineLayerFE({static_cast<uint32_t>(layer->sequence)})) {
2895*38e8c45fSAndroid Build Coastguard Worker             refreshArgs.layersWithQueuedFrames.push_back(layerFE);
2896*38e8c45fSAndroid Build Coastguard Worker             // Some layers are not displayed and do not yet have a future release fence
2897*38e8c45fSAndroid Build Coastguard Worker             if (layerFE->getReleaseFencePromiseStatus() ==
2898*38e8c45fSAndroid Build Coastguard Worker                         LayerFE::ReleaseFencePromiseStatus::UNINITIALIZED ||
2899*38e8c45fSAndroid Build Coastguard Worker                 layerFE->getReleaseFencePromiseStatus() ==
2900*38e8c45fSAndroid Build Coastguard Worker                         LayerFE::ReleaseFencePromiseStatus::FULFILLED) {
2901*38e8c45fSAndroid Build Coastguard Worker                 // layerStack is invalid because layer is not on a display
2902*38e8c45fSAndroid Build Coastguard Worker                 attachReleaseFenceFutureToLayer(layer.get(), layerFE.get(),
2903*38e8c45fSAndroid Build Coastguard Worker                                                 ui::INVALID_LAYER_STACK);
2904*38e8c45fSAndroid Build Coastguard Worker             }
2905*38e8c45fSAndroid Build Coastguard Worker         }
2906*38e8c45fSAndroid Build Coastguard Worker     }
2907*38e8c45fSAndroid Build Coastguard Worker 
2908*38e8c45fSAndroid Build Coastguard Worker     mCompositionEngine->present(refreshArgs);
2909*38e8c45fSAndroid Build Coastguard Worker     moveSnapshotsFromCompositionArgs(refreshArgs, layers);
2910*38e8c45fSAndroid Build Coastguard Worker 
2911*38e8c45fSAndroid Build Coastguard Worker     for (auto& [layer, layerFE] : layers) {
2912*38e8c45fSAndroid Build Coastguard Worker         CompositionResult compositionResult{layerFE->stealCompositionResult()};
2913*38e8c45fSAndroid Build Coastguard Worker         if (compositionResult.lastClientCompositionFence) {
2914*38e8c45fSAndroid Build Coastguard Worker             layer->setWasClientComposed(compositionResult.lastClientCompositionFence);
2915*38e8c45fSAndroid Build Coastguard Worker         }
2916*38e8c45fSAndroid Build Coastguard Worker         if (com_android_graphics_libgui_flags_apply_picture_profiles()) {
2917*38e8c45fSAndroid Build Coastguard Worker             mActivePictureUpdater.onLayerComposed(*layer, *layerFE, compositionResult);
2918*38e8c45fSAndroid Build Coastguard Worker         }
2919*38e8c45fSAndroid Build Coastguard Worker     }
2920*38e8c45fSAndroid Build Coastguard Worker 
2921*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_NAME("postComposition");
2922*38e8c45fSAndroid Build Coastguard Worker     mTimeStats->recordFrameDuration(pacesetterTarget.frameBeginTime().ns(), systemTime());
2923*38e8c45fSAndroid Build Coastguard Worker 
2924*38e8c45fSAndroid Build Coastguard Worker     // Send a power hint after presentation is finished.
2925*38e8c45fSAndroid Build Coastguard Worker     if (mPowerHintSessionEnabled) {
2926*38e8c45fSAndroid Build Coastguard Worker         // Now that the current frame has been presented above, PowerAdvisor needs the present time
2927*38e8c45fSAndroid Build Coastguard Worker         // of the previous frame (whose fence is signaled by now) to determine how long the HWC had
2928*38e8c45fSAndroid Build Coastguard Worker         // waited on that fence to retire before presenting.
2929*38e8c45fSAndroid Build Coastguard Worker         // TODO(b/355238809) `presentFenceForPreviousFrame` might not always be signaled (e.g. on
2930*38e8c45fSAndroid Build Coastguard Worker         // devices
2931*38e8c45fSAndroid Build Coastguard Worker         //  where HWC does not block on the previous present fence). Revise this assumtion.
2932*38e8c45fSAndroid Build Coastguard Worker         const auto& previousPresentFence = pacesetterTarget.presentFenceForPreviousFrame();
2933*38e8c45fSAndroid Build Coastguard Worker 
2934*38e8c45fSAndroid Build Coastguard Worker         mPowerAdvisor->setSfPresentTiming(TimePoint::fromNs(previousPresentFence->getSignalTime()),
2935*38e8c45fSAndroid Build Coastguard Worker                                           TimePoint::now());
2936*38e8c45fSAndroid Build Coastguard Worker         mPowerAdvisor->reportActualWorkDuration();
2937*38e8c45fSAndroid Build Coastguard Worker     }
2938*38e8c45fSAndroid Build Coastguard Worker 
2939*38e8c45fSAndroid Build Coastguard Worker     if (mScheduler->onCompositionPresented(presentTime)) {
2940*38e8c45fSAndroid Build Coastguard Worker         scheduleComposite(FrameHint::kNone);
2941*38e8c45fSAndroid Build Coastguard Worker     }
2942*38e8c45fSAndroid Build Coastguard Worker 
2943*38e8c45fSAndroid Build Coastguard Worker     mNotifyExpectedPresentMap[pacesetterId].hintStatus = NotifyExpectedPresentHintStatus::Start;
2944*38e8c45fSAndroid Build Coastguard Worker     onCompositionPresented(pacesetterId, frameTargeters, presentTime);
2945*38e8c45fSAndroid Build Coastguard Worker 
2946*38e8c45fSAndroid Build Coastguard Worker     const bool hadGpuComposited =
2947*38e8c45fSAndroid Build Coastguard Worker             multiDisplayUnion(mCompositionCoverage).test(CompositionCoverage::Gpu);
2948*38e8c45fSAndroid Build Coastguard Worker     mCompositionCoverage.clear();
2949*38e8c45fSAndroid Build Coastguard Worker 
2950*38e8c45fSAndroid Build Coastguard Worker     TimeStats::ClientCompositionRecord clientCompositionRecord;
2951*38e8c45fSAndroid Build Coastguard Worker 
2952*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [_, display] : displays) {
2953*38e8c45fSAndroid Build Coastguard Worker         const auto& state = display->getCompositionDisplay()->getState();
2954*38e8c45fSAndroid Build Coastguard Worker         CompositionCoverageFlags& flags =
2955*38e8c45fSAndroid Build Coastguard Worker                 mCompositionCoverage.try_emplace(display->getId()).first->second;
2956*38e8c45fSAndroid Build Coastguard Worker 
2957*38e8c45fSAndroid Build Coastguard Worker         if (state.usesDeviceComposition) {
2958*38e8c45fSAndroid Build Coastguard Worker             flags |= CompositionCoverage::Hwc;
2959*38e8c45fSAndroid Build Coastguard Worker         }
2960*38e8c45fSAndroid Build Coastguard Worker 
2961*38e8c45fSAndroid Build Coastguard Worker         if (state.reusedClientComposition) {
2962*38e8c45fSAndroid Build Coastguard Worker             flags |= CompositionCoverage::GpuReuse;
2963*38e8c45fSAndroid Build Coastguard Worker         } else if (state.usesClientComposition) {
2964*38e8c45fSAndroid Build Coastguard Worker             flags |= CompositionCoverage::Gpu;
2965*38e8c45fSAndroid Build Coastguard Worker         }
2966*38e8c45fSAndroid Build Coastguard Worker 
2967*38e8c45fSAndroid Build Coastguard Worker         clientCompositionRecord.predicted |=
2968*38e8c45fSAndroid Build Coastguard Worker                 (state.strategyPrediction != CompositionStrategyPredictionState::DISABLED);
2969*38e8c45fSAndroid Build Coastguard Worker         clientCompositionRecord.predictionSucceeded |=
2970*38e8c45fSAndroid Build Coastguard Worker                 (state.strategyPrediction == CompositionStrategyPredictionState::SUCCESS);
2971*38e8c45fSAndroid Build Coastguard Worker     }
2972*38e8c45fSAndroid Build Coastguard Worker 
2973*38e8c45fSAndroid Build Coastguard Worker     const auto coverage = multiDisplayUnion(mCompositionCoverage);
2974*38e8c45fSAndroid Build Coastguard Worker     const bool hasGpuComposited = coverage.test(CompositionCoverage::Gpu);
2975*38e8c45fSAndroid Build Coastguard Worker 
2976*38e8c45fSAndroid Build Coastguard Worker     clientCompositionRecord.hadClientComposition = hasGpuComposited;
2977*38e8c45fSAndroid Build Coastguard Worker     clientCompositionRecord.reused = coverage.test(CompositionCoverage::GpuReuse);
2978*38e8c45fSAndroid Build Coastguard Worker     clientCompositionRecord.changed = hadGpuComposited != hasGpuComposited;
2979*38e8c45fSAndroid Build Coastguard Worker 
2980*38e8c45fSAndroid Build Coastguard Worker     mTimeStats->pushCompositionStrategyState(clientCompositionRecord);
2981*38e8c45fSAndroid Build Coastguard Worker 
2982*38e8c45fSAndroid Build Coastguard Worker     using namespace ftl::flag_operators;
2983*38e8c45fSAndroid Build Coastguard Worker 
2984*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/160583065): Enable skip validation when SF caches all client composition layers.
2985*38e8c45fSAndroid Build Coastguard Worker     const bool hasGpuUseOrReuse =
2986*38e8c45fSAndroid Build Coastguard Worker             coverage.any(CompositionCoverage::Gpu | CompositionCoverage::GpuReuse);
2987*38e8c45fSAndroid Build Coastguard Worker     mScheduler->modulateVsync({}, &VsyncModulator::onDisplayRefresh, hasGpuUseOrReuse);
2988*38e8c45fSAndroid Build Coastguard Worker 
2989*38e8c45fSAndroid Build Coastguard Worker     mLayersWithQueuedFrames.clear();
2990*38e8c45fSAndroid Build Coastguard Worker     doActiveLayersTracingIfNeeded(true, mVisibleRegionsDirty, pacesetterTarget.frameBeginTime(),
2991*38e8c45fSAndroid Build Coastguard Worker                                   vsyncId);
2992*38e8c45fSAndroid Build Coastguard Worker 
2993*38e8c45fSAndroid Build Coastguard Worker     updateInputFlinger(vsyncId, pacesetterTarget.frameBeginTime());
2994*38e8c45fSAndroid Build Coastguard Worker 
2995*38e8c45fSAndroid Build Coastguard Worker     if (mVisibleRegionsDirty) mHdrLayerInfoChanged = true;
2996*38e8c45fSAndroid Build Coastguard Worker     mVisibleRegionsDirty = false;
2997*38e8c45fSAndroid Build Coastguard Worker 
2998*38e8c45fSAndroid Build Coastguard Worker     if (mCompositionEngine->needsAnotherUpdate()) {
2999*38e8c45fSAndroid Build Coastguard Worker         scheduleCommit(FrameHint::kNone);
3000*38e8c45fSAndroid Build Coastguard Worker     }
3001*38e8c45fSAndroid Build Coastguard Worker 
3002*38e8c45fSAndroid Build Coastguard Worker     if (mPowerHintSessionEnabled) {
3003*38e8c45fSAndroid Build Coastguard Worker         mPowerAdvisor->setCompositeEnd(TimePoint::now());
3004*38e8c45fSAndroid Build Coastguard Worker     }
3005*38e8c45fSAndroid Build Coastguard Worker 
3006*38e8c45fSAndroid Build Coastguard Worker     CompositeResultsPerDisplay resultsPerDisplay;
3007*38e8c45fSAndroid Build Coastguard Worker 
3008*38e8c45fSAndroid Build Coastguard Worker     // Filter out virtual displays.
3009*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [id, coverage] : mCompositionCoverage) {
3010*38e8c45fSAndroid Build Coastguard Worker         if (const auto idOpt = PhysicalDisplayId::tryCast(id)) {
3011*38e8c45fSAndroid Build Coastguard Worker             resultsPerDisplay.try_emplace(*idOpt, CompositeResult{coverage});
3012*38e8c45fSAndroid Build Coastguard Worker         }
3013*38e8c45fSAndroid Build Coastguard Worker     }
3014*38e8c45fSAndroid Build Coastguard Worker 
3015*38e8c45fSAndroid Build Coastguard Worker     return resultsPerDisplay;
3016*38e8c45fSAndroid Build Coastguard Worker }
3017*38e8c45fSAndroid Build Coastguard Worker 
isHdrLayer(const frontend::LayerSnapshot & snapshot) const3018*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::isHdrLayer(const frontend::LayerSnapshot& snapshot) const {
3019*38e8c45fSAndroid Build Coastguard Worker     // Even though the camera layer may be using an HDR transfer function or otherwise be "HDR"
3020*38e8c45fSAndroid Build Coastguard Worker     // the device may need to avoid boosting the brightness as a result of these layers to
3021*38e8c45fSAndroid Build Coastguard Worker     // reduce power consumption during camera recording
3022*38e8c45fSAndroid Build Coastguard Worker     if (mIgnoreHdrCameraLayers) {
3023*38e8c45fSAndroid Build Coastguard Worker         if (snapshot.externalTexture &&
3024*38e8c45fSAndroid Build Coastguard Worker             (snapshot.externalTexture->getUsage() & GRALLOC_USAGE_HW_CAMERA_WRITE) != 0) {
3025*38e8c45fSAndroid Build Coastguard Worker             return false;
3026*38e8c45fSAndroid Build Coastguard Worker         }
3027*38e8c45fSAndroid Build Coastguard Worker     }
3028*38e8c45fSAndroid Build Coastguard Worker     // RANGE_EXTENDED layer may identify themselves as being "HDR"
3029*38e8c45fSAndroid Build Coastguard Worker     // via a desired hdr/sdr ratio
3030*38e8c45fSAndroid Build Coastguard Worker     auto pixelFormat = snapshot.buffer
3031*38e8c45fSAndroid Build Coastguard Worker             ? std::make_optional(static_cast<ui::PixelFormat>(snapshot.buffer->getPixelFormat()))
3032*38e8c45fSAndroid Build Coastguard Worker             : std::nullopt;
3033*38e8c45fSAndroid Build Coastguard Worker 
3034*38e8c45fSAndroid Build Coastguard Worker     if (getHdrRenderType(snapshot.dataspace, pixelFormat, snapshot.desiredHdrSdrRatio) !=
3035*38e8c45fSAndroid Build Coastguard Worker         HdrRenderType::SDR) {
3036*38e8c45fSAndroid Build Coastguard Worker         return true;
3037*38e8c45fSAndroid Build Coastguard Worker     }
3038*38e8c45fSAndroid Build Coastguard Worker     // If the layer is not allowed to be dimmed, treat it as HDR. WindowManager may disable
3039*38e8c45fSAndroid Build Coastguard Worker     // dimming in order to keep animations invoking SDR screenshots of HDR layers seamless.
3040*38e8c45fSAndroid Build Coastguard Worker     // Treat such tagged layers as HDR so that DisplayManagerService does not try to change
3041*38e8c45fSAndroid Build Coastguard Worker     // the screen brightness
3042*38e8c45fSAndroid Build Coastguard Worker     if (!snapshot.dimmingEnabled) {
3043*38e8c45fSAndroid Build Coastguard Worker         return true;
3044*38e8c45fSAndroid Build Coastguard Worker     }
3045*38e8c45fSAndroid Build Coastguard Worker     return false;
3046*38e8c45fSAndroid Build Coastguard Worker }
3047*38e8c45fSAndroid Build Coastguard Worker 
getPhysicalDisplayOrientation(DisplayId displayId,bool isPrimary) const3048*38e8c45fSAndroid Build Coastguard Worker ui::Rotation SurfaceFlinger::getPhysicalDisplayOrientation(DisplayId displayId,
3049*38e8c45fSAndroid Build Coastguard Worker                                                            bool isPrimary) const {
3050*38e8c45fSAndroid Build Coastguard Worker     const auto id = PhysicalDisplayId::tryCast(displayId);
3051*38e8c45fSAndroid Build Coastguard Worker     if (!id) {
3052*38e8c45fSAndroid Build Coastguard Worker         return ui::ROTATION_0;
3053*38e8c45fSAndroid Build Coastguard Worker     }
3054*38e8c45fSAndroid Build Coastguard Worker     if (!mIgnoreHwcPhysicalDisplayOrientation &&
3055*38e8c45fSAndroid Build Coastguard Worker         getHwComposer().getComposer()->isSupported(
3056*38e8c45fSAndroid Build Coastguard Worker                 Hwc2::Composer::OptionalFeature::PhysicalDisplayOrientation)) {
3057*38e8c45fSAndroid Build Coastguard Worker         switch (getHwComposer().getPhysicalDisplayOrientation(*id)) {
3058*38e8c45fSAndroid Build Coastguard Worker             case Hwc2::AidlTransform::ROT_90:
3059*38e8c45fSAndroid Build Coastguard Worker                 return ui::ROTATION_90;
3060*38e8c45fSAndroid Build Coastguard Worker             case Hwc2::AidlTransform::ROT_180:
3061*38e8c45fSAndroid Build Coastguard Worker                 return ui::ROTATION_180;
3062*38e8c45fSAndroid Build Coastguard Worker             case Hwc2::AidlTransform::ROT_270:
3063*38e8c45fSAndroid Build Coastguard Worker                 return ui::ROTATION_270;
3064*38e8c45fSAndroid Build Coastguard Worker             default:
3065*38e8c45fSAndroid Build Coastguard Worker                 return ui::ROTATION_0;
3066*38e8c45fSAndroid Build Coastguard Worker         }
3067*38e8c45fSAndroid Build Coastguard Worker     }
3068*38e8c45fSAndroid Build Coastguard Worker 
3069*38e8c45fSAndroid Build Coastguard Worker     if (isPrimary) {
3070*38e8c45fSAndroid Build Coastguard Worker         using Values = SurfaceFlingerProperties::primary_display_orientation_values;
3071*38e8c45fSAndroid Build Coastguard Worker         switch (primary_display_orientation(Values::ORIENTATION_0)) {
3072*38e8c45fSAndroid Build Coastguard Worker             case Values::ORIENTATION_90:
3073*38e8c45fSAndroid Build Coastguard Worker                 return ui::ROTATION_90;
3074*38e8c45fSAndroid Build Coastguard Worker             case Values::ORIENTATION_180:
3075*38e8c45fSAndroid Build Coastguard Worker                 return ui::ROTATION_180;
3076*38e8c45fSAndroid Build Coastguard Worker             case Values::ORIENTATION_270:
3077*38e8c45fSAndroid Build Coastguard Worker                 return ui::ROTATION_270;
3078*38e8c45fSAndroid Build Coastguard Worker             default:
3079*38e8c45fSAndroid Build Coastguard Worker                 break;
3080*38e8c45fSAndroid Build Coastguard Worker         }
3081*38e8c45fSAndroid Build Coastguard Worker     }
3082*38e8c45fSAndroid Build Coastguard Worker     return ui::ROTATION_0;
3083*38e8c45fSAndroid Build Coastguard Worker }
3084*38e8c45fSAndroid Build Coastguard Worker 
onCompositionPresented(PhysicalDisplayId pacesetterId,const scheduler::FrameTargeters & frameTargeters,nsecs_t presentStartTime)3085*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId,
3086*38e8c45fSAndroid Build Coastguard Worker                                             const scheduler::FrameTargeters& frameTargeters,
3087*38e8c45fSAndroid Build Coastguard Worker                                             nsecs_t presentStartTime) {
3088*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
3089*38e8c45fSAndroid Build Coastguard Worker 
3090*38e8c45fSAndroid Build Coastguard Worker     ui::PhysicalDisplayMap<PhysicalDisplayId, std::shared_ptr<FenceTime>> presentFences;
3091*38e8c45fSAndroid Build Coastguard Worker     ui::PhysicalDisplayMap<PhysicalDisplayId, const sp<Fence>> gpuCompositionDoneFences;
3092*38e8c45fSAndroid Build Coastguard Worker 
3093*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [id, targeter] : frameTargeters) {
3094*38e8c45fSAndroid Build Coastguard Worker         auto presentFence = getHwComposer().getPresentFence(id);
3095*38e8c45fSAndroid Build Coastguard Worker 
3096*38e8c45fSAndroid Build Coastguard Worker         if (id == pacesetterId) {
3097*38e8c45fSAndroid Build Coastguard Worker             mTransactionCallbackInvoker.addPresentFence(presentFence);
3098*38e8c45fSAndroid Build Coastguard Worker         }
3099*38e8c45fSAndroid Build Coastguard Worker 
3100*38e8c45fSAndroid Build Coastguard Worker         if (auto fenceTime = targeter->setPresentFence(std::move(presentFence));
3101*38e8c45fSAndroid Build Coastguard Worker             fenceTime->isValid()) {
3102*38e8c45fSAndroid Build Coastguard Worker             presentFences.try_emplace(id, std::move(fenceTime));
3103*38e8c45fSAndroid Build Coastguard Worker         }
3104*38e8c45fSAndroid Build Coastguard Worker 
3105*38e8c45fSAndroid Build Coastguard Worker         ftl::FakeGuard guard(mStateLock);
3106*38e8c45fSAndroid Build Coastguard Worker         if (const auto display = getCompositionDisplayLocked(id);
3107*38e8c45fSAndroid Build Coastguard Worker             display && display->getState().usesClientComposition) {
3108*38e8c45fSAndroid Build Coastguard Worker             gpuCompositionDoneFences
3109*38e8c45fSAndroid Build Coastguard Worker                     .try_emplace(id, display->getRenderSurface()->getClientTargetAcquireFence());
3110*38e8c45fSAndroid Build Coastguard Worker         }
3111*38e8c45fSAndroid Build Coastguard Worker     }
3112*38e8c45fSAndroid Build Coastguard Worker 
3113*38e8c45fSAndroid Build Coastguard Worker     const auto pacesetterDisplay = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(pacesetterId));
3114*38e8c45fSAndroid Build Coastguard Worker 
3115*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<FenceTime> pacesetterPresentFenceTime =
3116*38e8c45fSAndroid Build Coastguard Worker             presentFences.get(pacesetterId)
3117*38e8c45fSAndroid Build Coastguard Worker                     .transform([](const FenceTimePtr& ptr) { return ptr; })
3118*38e8c45fSAndroid Build Coastguard Worker                     .value_or(FenceTime::NO_FENCE);
3119*38e8c45fSAndroid Build Coastguard Worker 
3120*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<FenceTime> pacesetterGpuCompositionDoneFenceTime =
3121*38e8c45fSAndroid Build Coastguard Worker             gpuCompositionDoneFences.get(pacesetterId)
3122*38e8c45fSAndroid Build Coastguard Worker                     .transform([](sp<Fence> fence) {
3123*38e8c45fSAndroid Build Coastguard Worker                         return std::make_shared<FenceTime>(std::move(fence));
3124*38e8c45fSAndroid Build Coastguard Worker                     })
3125*38e8c45fSAndroid Build Coastguard Worker                     .value_or(FenceTime::NO_FENCE);
3126*38e8c45fSAndroid Build Coastguard Worker 
3127*38e8c45fSAndroid Build Coastguard Worker     const TimePoint presentTime = TimePoint::now();
3128*38e8c45fSAndroid Build Coastguard Worker 
3129*38e8c45fSAndroid Build Coastguard Worker     // The Uids of layer owners that are in buffer stuffing mode, and their elevated
3130*38e8c45fSAndroid Build Coastguard Worker     // buffer counts. Messages to start recovery are sent exclusively to these Uids.
3131*38e8c45fSAndroid Build Coastguard Worker     BufferStuffingMap bufferStuffedUids;
3132*38e8c45fSAndroid Build Coastguard Worker 
3133*38e8c45fSAndroid Build Coastguard Worker     // Set presentation information before calling Layer::releasePendingBuffer, such that jank
3134*38e8c45fSAndroid Build Coastguard Worker     // information from previous' frame classification is already available when sending jank info
3135*38e8c45fSAndroid Build Coastguard Worker     // to clients, so they get jank classification as early as possible.
3136*38e8c45fSAndroid Build Coastguard Worker     mFrameTimeline->setSfPresent(presentTime.ns(), pacesetterPresentFenceTime,
3137*38e8c45fSAndroid Build Coastguard Worker                                  pacesetterGpuCompositionDoneFenceTime);
3138*38e8c45fSAndroid Build Coastguard Worker 
3139*38e8c45fSAndroid Build Coastguard Worker     // Find and register any layers that are in buffer stuffing mode
3140*38e8c45fSAndroid Build Coastguard Worker     const auto& presentFrames = mFrameTimeline->getPresentFrames();
3141*38e8c45fSAndroid Build Coastguard Worker 
3142*38e8c45fSAndroid Build Coastguard Worker     for (const auto& frame : presentFrames) {
3143*38e8c45fSAndroid Build Coastguard Worker         const auto& layer = mLayerLifecycleManager.getLayerFromId(frame->getLayerId());
3144*38e8c45fSAndroid Build Coastguard Worker         if (!layer) continue;
3145*38e8c45fSAndroid Build Coastguard Worker         uint32_t numberQueuedBuffers = layer->pendingBuffers ? layer->pendingBuffers->load() : 0;
3146*38e8c45fSAndroid Build Coastguard Worker         int32_t jankType = frame->getJankType().value_or(JankType::None);
3147*38e8c45fSAndroid Build Coastguard Worker         if (jankType & JankType::BufferStuffing &&
3148*38e8c45fSAndroid Build Coastguard Worker             layer->flags & layer_state_t::eRecoverableFromBufferStuffing) {
3149*38e8c45fSAndroid Build Coastguard Worker             auto [it, wasEmplaced] =
3150*38e8c45fSAndroid Build Coastguard Worker                     bufferStuffedUids.try_emplace(layer->ownerUid.val(), numberQueuedBuffers);
3151*38e8c45fSAndroid Build Coastguard Worker             // Update with maximum number of queued buffers, allows clients drawing
3152*38e8c45fSAndroid Build Coastguard Worker             // multiple windows to account for the most severely stuffed window
3153*38e8c45fSAndroid Build Coastguard Worker             if (!wasEmplaced && it->second < numberQueuedBuffers) {
3154*38e8c45fSAndroid Build Coastguard Worker                 it->second = numberQueuedBuffers;
3155*38e8c45fSAndroid Build Coastguard Worker             }
3156*38e8c45fSAndroid Build Coastguard Worker         }
3157*38e8c45fSAndroid Build Coastguard Worker     }
3158*38e8c45fSAndroid Build Coastguard Worker 
3159*38e8c45fSAndroid Build Coastguard Worker     if (!bufferStuffedUids.empty()) {
3160*38e8c45fSAndroid Build Coastguard Worker         mScheduler->addBufferStuffedUids(std::move(bufferStuffedUids));
3161*38e8c45fSAndroid Build Coastguard Worker     }
3162*38e8c45fSAndroid Build Coastguard Worker 
3163*38e8c45fSAndroid Build Coastguard Worker     // We use the CompositionEngine::getLastFrameRefreshTimestamp() which might
3164*38e8c45fSAndroid Build Coastguard Worker     // be sampled a little later than when we started doing work for this frame,
3165*38e8c45fSAndroid Build Coastguard Worker     // but that should be okay since CompositorTiming has snapping logic.
3166*38e8c45fSAndroid Build Coastguard Worker     const TimePoint compositeTime =
3167*38e8c45fSAndroid Build Coastguard Worker             TimePoint::fromNs(mCompositionEngine->getLastFrameRefreshTimestamp());
3168*38e8c45fSAndroid Build Coastguard Worker     const Duration presentLatency = mHasReliablePresentFences
3169*38e8c45fSAndroid Build Coastguard Worker             ? mPresentLatencyTracker.trackPendingFrame(compositeTime, pacesetterPresentFenceTime)
3170*38e8c45fSAndroid Build Coastguard Worker             : Duration::zero();
3171*38e8c45fSAndroid Build Coastguard Worker 
3172*38e8c45fSAndroid Build Coastguard Worker     const auto schedule = mScheduler->getVsyncSchedule();
3173*38e8c45fSAndroid Build Coastguard Worker     const TimePoint vsyncDeadline = schedule->vsyncDeadlineAfter(presentTime);
3174*38e8c45fSAndroid Build Coastguard Worker     const Fps renderRate = pacesetterDisplay->refreshRateSelector().getActiveMode().fps;
3175*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t vsyncPhase =
3176*38e8c45fSAndroid Build Coastguard Worker             mScheduler->getVsyncConfiguration().getCurrentConfigs().late.sfOffset;
3177*38e8c45fSAndroid Build Coastguard Worker 
3178*38e8c45fSAndroid Build Coastguard Worker     const CompositorTiming compositorTiming(vsyncDeadline.ns(), renderRate.getPeriodNsecs(),
3179*38e8c45fSAndroid Build Coastguard Worker                                             vsyncPhase, presentLatency.ns());
3180*38e8c45fSAndroid Build Coastguard Worker 
3181*38e8c45fSAndroid Build Coastguard Worker     ui::DisplayMap<ui::LayerStack, const DisplayDevice*> layerStackToDisplay;
3182*38e8c45fSAndroid Build Coastguard Worker     {
3183*38e8c45fSAndroid Build Coastguard Worker         if (!mLayersWithBuffersRemoved.empty() || mNumTrustedPresentationListeners > 0) {
3184*38e8c45fSAndroid Build Coastguard Worker             Mutex::Autolock lock(mStateLock);
3185*38e8c45fSAndroid Build Coastguard Worker             for (const auto& [token, display] : mDisplays) {
3186*38e8c45fSAndroid Build Coastguard Worker                 layerStackToDisplay.emplace_or_replace(display->getLayerStack(), display.get());
3187*38e8c45fSAndroid Build Coastguard Worker             }
3188*38e8c45fSAndroid Build Coastguard Worker         }
3189*38e8c45fSAndroid Build Coastguard Worker     }
3190*38e8c45fSAndroid Build Coastguard Worker 
3191*38e8c45fSAndroid Build Coastguard Worker     for (auto layer : mLayersWithBuffersRemoved) {
3192*38e8c45fSAndroid Build Coastguard Worker         std::vector<ui::LayerStack> previouslyPresentedLayerStacks =
3193*38e8c45fSAndroid Build Coastguard Worker                 std::move(layer->mPreviouslyPresentedLayerStacks);
3194*38e8c45fSAndroid Build Coastguard Worker         layer->mPreviouslyPresentedLayerStacks.clear();
3195*38e8c45fSAndroid Build Coastguard Worker         for (auto layerStack : previouslyPresentedLayerStacks) {
3196*38e8c45fSAndroid Build Coastguard Worker             auto optDisplay = layerStackToDisplay.get(layerStack);
3197*38e8c45fSAndroid Build Coastguard Worker             if (optDisplay && !optDisplay->get()->isVirtual()) {
3198*38e8c45fSAndroid Build Coastguard Worker                 auto fence = getHwComposer().getPresentFence(optDisplay->get()->getPhysicalId());
3199*38e8c45fSAndroid Build Coastguard Worker                 layer->prepareReleaseCallbacks(ftl::yield<FenceResult>(fence),
3200*38e8c45fSAndroid Build Coastguard Worker                                                ui::INVALID_LAYER_STACK);
3201*38e8c45fSAndroid Build Coastguard Worker             }
3202*38e8c45fSAndroid Build Coastguard Worker         }
3203*38e8c45fSAndroid Build Coastguard Worker         layer->releasePendingBuffer(presentTime.ns());
3204*38e8c45fSAndroid Build Coastguard Worker     }
3205*38e8c45fSAndroid Build Coastguard Worker     mLayersWithBuffersRemoved.clear();
3206*38e8c45fSAndroid Build Coastguard Worker 
3207*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [layer, gameMode] : mLayersWithQueuedFrames) {
3208*38e8c45fSAndroid Build Coastguard Worker         layer->onCompositionPresented(pacesetterDisplay.get(),
3209*38e8c45fSAndroid Build Coastguard Worker                                       pacesetterGpuCompositionDoneFenceTime,
3210*38e8c45fSAndroid Build Coastguard Worker                                       pacesetterPresentFenceTime, compositorTiming, gameMode);
3211*38e8c45fSAndroid Build Coastguard Worker         layer->releasePendingBuffer(presentTime.ns());
3212*38e8c45fSAndroid Build Coastguard Worker     }
3213*38e8c45fSAndroid Build Coastguard Worker 
3214*38e8c45fSAndroid Build Coastguard Worker     for (const auto& layerEvent : mLayerEvents) {
3215*38e8c45fSAndroid Build Coastguard Worker         auto result =
3216*38e8c45fSAndroid Build Coastguard Worker                 stats::stats_write(stats::SURFACE_CONTROL_EVENT,
3217*38e8c45fSAndroid Build Coastguard Worker                                    static_cast<int32_t>(layerEvent.uid),
3218*38e8c45fSAndroid Build Coastguard Worker                                    static_cast<int64_t>(layerEvent.timeSinceLastEvent.count()),
3219*38e8c45fSAndroid Build Coastguard Worker                                    static_cast<int32_t>(layerEvent.dataspace));
3220*38e8c45fSAndroid Build Coastguard Worker         if (result < 0) {
3221*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Failed to report layer event with error: %d", result);
3222*38e8c45fSAndroid Build Coastguard Worker         }
3223*38e8c45fSAndroid Build Coastguard Worker     }
3224*38e8c45fSAndroid Build Coastguard Worker     mLayerEvents.clear();
3225*38e8c45fSAndroid Build Coastguard Worker 
3226*38e8c45fSAndroid Build Coastguard Worker     std::vector<std::pair<std::shared_ptr<compositionengine::Display>, sp<HdrLayerInfoReporter>>>
3227*38e8c45fSAndroid Build Coastguard Worker             hdrInfoListeners;
3228*38e8c45fSAndroid Build Coastguard Worker     bool haveNewHdrInfoListeners = false;
3229*38e8c45fSAndroid Build Coastguard Worker     sp<gui::IActivePictureListener> activePictureListener;
3230*38e8c45fSAndroid Build Coastguard Worker     bool haveNewActivePictureListener = false;
3231*38e8c45fSAndroid Build Coastguard Worker     {
3232*38e8c45fSAndroid Build Coastguard Worker         Mutex::Autolock lock(mStateLock);
3233*38e8c45fSAndroid Build Coastguard Worker         if (mFpsReporter) {
3234*38e8c45fSAndroid Build Coastguard Worker             mFpsReporter->dispatchLayerFps(mLayerHierarchyBuilder.getHierarchy());
3235*38e8c45fSAndroid Build Coastguard Worker         }
3236*38e8c45fSAndroid Build Coastguard Worker 
3237*38e8c45fSAndroid Build Coastguard Worker         if (mTunnelModeEnabledReporter) {
3238*38e8c45fSAndroid Build Coastguard Worker             mTunnelModeEnabledReporter->updateTunnelModeStatus();
3239*38e8c45fSAndroid Build Coastguard Worker         }
3240*38e8c45fSAndroid Build Coastguard Worker 
3241*38e8c45fSAndroid Build Coastguard Worker         hdrInfoListeners.reserve(mHdrLayerInfoListeners.size());
3242*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [displayId, reporter] : mHdrLayerInfoListeners) {
3243*38e8c45fSAndroid Build Coastguard Worker             if (reporter && reporter->hasListeners()) {
3244*38e8c45fSAndroid Build Coastguard Worker                 if (const auto display = getDisplayDeviceLocked(displayId)) {
3245*38e8c45fSAndroid Build Coastguard Worker                     hdrInfoListeners.emplace_back(display->getCompositionDisplay(), reporter);
3246*38e8c45fSAndroid Build Coastguard Worker                 }
3247*38e8c45fSAndroid Build Coastguard Worker             }
3248*38e8c45fSAndroid Build Coastguard Worker         }
3249*38e8c45fSAndroid Build Coastguard Worker         haveNewHdrInfoListeners = mAddingHDRLayerInfoListener; // grab this with state lock
3250*38e8c45fSAndroid Build Coastguard Worker         mAddingHDRLayerInfoListener = false;
3251*38e8c45fSAndroid Build Coastguard Worker 
3252*38e8c45fSAndroid Build Coastguard Worker         activePictureListener = mActivePictureListener;
3253*38e8c45fSAndroid Build Coastguard Worker         haveNewActivePictureListener = mHaveNewActivePictureListener;
3254*38e8c45fSAndroid Build Coastguard Worker         mHaveNewActivePictureListener = false;
3255*38e8c45fSAndroid Build Coastguard Worker     }
3256*38e8c45fSAndroid Build Coastguard Worker 
3257*38e8c45fSAndroid Build Coastguard Worker     if (haveNewHdrInfoListeners || mHdrLayerInfoChanged) {
3258*38e8c45fSAndroid Build Coastguard Worker         for (auto& [compositionDisplay, listener] : hdrInfoListeners) {
3259*38e8c45fSAndroid Build Coastguard Worker             HdrLayerInfoReporter::HdrLayerInfo info;
3260*38e8c45fSAndroid Build Coastguard Worker             int32_t maxArea = 0;
3261*38e8c45fSAndroid Build Coastguard Worker 
3262*38e8c45fSAndroid Build Coastguard Worker             auto updateInfoFn =
3263*38e8c45fSAndroid Build Coastguard Worker                     [&](const std::shared_ptr<compositionengine::Display>& compositionDisplay,
3264*38e8c45fSAndroid Build Coastguard Worker                         const frontend::LayerSnapshot& snapshot, const sp<LayerFE>& layerFe) {
3265*38e8c45fSAndroid Build Coastguard Worker                         if (snapshot.isVisible &&
3266*38e8c45fSAndroid Build Coastguard Worker                             compositionDisplay->includesLayer(snapshot.outputFilter)) {
3267*38e8c45fSAndroid Build Coastguard Worker                             if (isHdrLayer(snapshot)) {
3268*38e8c45fSAndroid Build Coastguard Worker                                 const auto* outputLayer =
3269*38e8c45fSAndroid Build Coastguard Worker                                         compositionDisplay->getOutputLayerForLayer(layerFe);
3270*38e8c45fSAndroid Build Coastguard Worker                                 if (outputLayer) {
3271*38e8c45fSAndroid Build Coastguard Worker                                     const float desiredHdrSdrRatio =
3272*38e8c45fSAndroid Build Coastguard Worker                                             snapshot.desiredHdrSdrRatio < 1.f
3273*38e8c45fSAndroid Build Coastguard Worker                                             ? std::numeric_limits<float>::infinity()
3274*38e8c45fSAndroid Build Coastguard Worker                                             : snapshot.desiredHdrSdrRatio;
3275*38e8c45fSAndroid Build Coastguard Worker 
3276*38e8c45fSAndroid Build Coastguard Worker                                     float desiredRatio = desiredHdrSdrRatio;
3277*38e8c45fSAndroid Build Coastguard Worker                                     if (FlagManager::getInstance().begone_bright_hlg() &&
3278*38e8c45fSAndroid Build Coastguard Worker                                         desiredHdrSdrRatio ==
3279*38e8c45fSAndroid Build Coastguard Worker                                                 std::numeric_limits<float>::infinity()) {
3280*38e8c45fSAndroid Build Coastguard Worker                                         desiredRatio = getIdealizedMaxHeadroom(snapshot.dataspace);
3281*38e8c45fSAndroid Build Coastguard Worker                                     }
3282*38e8c45fSAndroid Build Coastguard Worker 
3283*38e8c45fSAndroid Build Coastguard Worker                                     info.mergeDesiredRatio(desiredRatio);
3284*38e8c45fSAndroid Build Coastguard Worker                                     info.numberOfHdrLayers++;
3285*38e8c45fSAndroid Build Coastguard Worker                                     const auto displayFrame = outputLayer->getState().displayFrame;
3286*38e8c45fSAndroid Build Coastguard Worker                                     const int32_t area =
3287*38e8c45fSAndroid Build Coastguard Worker                                             displayFrame.width() * displayFrame.height();
3288*38e8c45fSAndroid Build Coastguard Worker                                     if (area > maxArea) {
3289*38e8c45fSAndroid Build Coastguard Worker                                         maxArea = area;
3290*38e8c45fSAndroid Build Coastguard Worker                                         info.maxW = displayFrame.width();
3291*38e8c45fSAndroid Build Coastguard Worker                                         info.maxH = displayFrame.height();
3292*38e8c45fSAndroid Build Coastguard Worker                                     }
3293*38e8c45fSAndroid Build Coastguard Worker                                 }
3294*38e8c45fSAndroid Build Coastguard Worker                             }
3295*38e8c45fSAndroid Build Coastguard Worker                         }
3296*38e8c45fSAndroid Build Coastguard Worker                     };
3297*38e8c45fSAndroid Build Coastguard Worker 
3298*38e8c45fSAndroid Build Coastguard Worker             mLayerSnapshotBuilder.forEachVisibleSnapshot(
3299*38e8c45fSAndroid Build Coastguard Worker                     [&, compositionDisplay = compositionDisplay](
3300*38e8c45fSAndroid Build Coastguard Worker                             std::unique_ptr<frontend::LayerSnapshot>& snapshot)
3301*38e8c45fSAndroid Build Coastguard Worker                             FTL_FAKE_GUARD(kMainThreadContext) {
3302*38e8c45fSAndroid Build Coastguard Worker                                 auto it = mLegacyLayers.find(snapshot->sequence);
3303*38e8c45fSAndroid Build Coastguard Worker                                 LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
3304*38e8c45fSAndroid Build Coastguard Worker                                                                 "Couldnt find layer object for %s",
3305*38e8c45fSAndroid Build Coastguard Worker                                                                 snapshot->getDebugString().c_str());
3306*38e8c45fSAndroid Build Coastguard Worker                                 auto& legacyLayer = it->second;
3307*38e8c45fSAndroid Build Coastguard Worker                                 sp<LayerFE> layerFe =
3308*38e8c45fSAndroid Build Coastguard Worker                                         legacyLayer->getCompositionEngineLayerFE(snapshot->path);
3309*38e8c45fSAndroid Build Coastguard Worker 
3310*38e8c45fSAndroid Build Coastguard Worker                                 updateInfoFn(compositionDisplay, *snapshot, layerFe);
3311*38e8c45fSAndroid Build Coastguard Worker                             });
3312*38e8c45fSAndroid Build Coastguard Worker             listener->dispatchHdrLayerInfo(info);
3313*38e8c45fSAndroid Build Coastguard Worker         }
3314*38e8c45fSAndroid Build Coastguard Worker     }
3315*38e8c45fSAndroid Build Coastguard Worker     mHdrLayerInfoChanged = false;
3316*38e8c45fSAndroid Build Coastguard Worker 
3317*38e8c45fSAndroid Build Coastguard Worker     if (com_android_graphics_libgui_flags_apply_picture_profiles()) {
3318*38e8c45fSAndroid Build Coastguard Worker         // Track, update and notify changes to active pictures - layers that are undergoing picture
3319*38e8c45fSAndroid Build Coastguard Worker         // processing
3320*38e8c45fSAndroid Build Coastguard Worker         if (mActivePictureUpdater.updateAndHasChanged() || haveNewActivePictureListener) {
3321*38e8c45fSAndroid Build Coastguard Worker             if (activePictureListener) {
3322*38e8c45fSAndroid Build Coastguard Worker                 activePictureListener->onActivePicturesChanged(
3323*38e8c45fSAndroid Build Coastguard Worker                         mActivePictureUpdater.getActivePictures());
3324*38e8c45fSAndroid Build Coastguard Worker             }
3325*38e8c45fSAndroid Build Coastguard Worker         }
3326*38e8c45fSAndroid Build Coastguard Worker     }
3327*38e8c45fSAndroid Build Coastguard Worker 
3328*38e8c45fSAndroid Build Coastguard Worker     mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
3329*38e8c45fSAndroid Build Coastguard Worker     mTransactionCallbackInvoker.clearCompletedTransactions();
3330*38e8c45fSAndroid Build Coastguard Worker 
3331*38e8c45fSAndroid Build Coastguard Worker     mTimeStats->incrementTotalFrames();
3332*38e8c45fSAndroid Build Coastguard Worker     mTimeStats->setPresentFenceGlobal(pacesetterPresentFenceTime);
3333*38e8c45fSAndroid Build Coastguard Worker 
3334*38e8c45fSAndroid Build Coastguard Worker     for (auto&& [id, presentFence] : presentFences) {
3335*38e8c45fSAndroid Build Coastguard Worker         ftl::FakeGuard guard(mStateLock);
3336*38e8c45fSAndroid Build Coastguard Worker         const bool isInternalDisplay =
3337*38e8c45fSAndroid Build Coastguard Worker                 mPhysicalDisplays.get(id).transform(&PhysicalDisplay::isInternal).value_or(false);
3338*38e8c45fSAndroid Build Coastguard Worker 
3339*38e8c45fSAndroid Build Coastguard Worker         if (isInternalDisplay) {
3340*38e8c45fSAndroid Build Coastguard Worker             mScheduler->addPresentFence(id, std::move(presentFence));
3341*38e8c45fSAndroid Build Coastguard Worker         }
3342*38e8c45fSAndroid Build Coastguard Worker     }
3343*38e8c45fSAndroid Build Coastguard Worker 
3344*38e8c45fSAndroid Build Coastguard Worker     const bool hasPacesetterDisplay =
3345*38e8c45fSAndroid Build Coastguard Worker             pacesetterDisplay && getHwComposer().isConnected(pacesetterId);
3346*38e8c45fSAndroid Build Coastguard Worker 
3347*38e8c45fSAndroid Build Coastguard Worker     if (!hasSyncFramework) {
3348*38e8c45fSAndroid Build Coastguard Worker         if (hasPacesetterDisplay && pacesetterDisplay->isPoweredOn()) {
3349*38e8c45fSAndroid Build Coastguard Worker             mScheduler->enableHardwareVsync(pacesetterId);
3350*38e8c45fSAndroid Build Coastguard Worker         }
3351*38e8c45fSAndroid Build Coastguard Worker     }
3352*38e8c45fSAndroid Build Coastguard Worker 
3353*38e8c45fSAndroid Build Coastguard Worker     if (hasPacesetterDisplay && !pacesetterDisplay->isPoweredOn()) {
3354*38e8c45fSAndroid Build Coastguard Worker         getRenderEngine().cleanupPostRender();
3355*38e8c45fSAndroid Build Coastguard Worker         return;
3356*38e8c45fSAndroid Build Coastguard Worker     }
3357*38e8c45fSAndroid Build Coastguard Worker 
3358*38e8c45fSAndroid Build Coastguard Worker     // Cleanup any outstanding resources due to rendering a prior frame.
3359*38e8c45fSAndroid Build Coastguard Worker     getRenderEngine().cleanupPostRender();
3360*38e8c45fSAndroid Build Coastguard Worker 
3361*38e8c45fSAndroid Build Coastguard Worker     if (mNumTrustedPresentationListeners > 0) {
3362*38e8c45fSAndroid Build Coastguard Worker         // We avoid any reverse traversal upwards so this shouldn't be too expensive
3363*38e8c45fSAndroid Build Coastguard Worker         traverseLegacyLayers([&](Layer* layer) FTL_FAKE_GUARD(kMainThreadContext) {
3364*38e8c45fSAndroid Build Coastguard Worker             if (!layer->hasTrustedPresentationListener()) {
3365*38e8c45fSAndroid Build Coastguard Worker                 return;
3366*38e8c45fSAndroid Build Coastguard Worker             }
3367*38e8c45fSAndroid Build Coastguard Worker             const frontend::LayerSnapshot* snapshot =
3368*38e8c45fSAndroid Build Coastguard Worker                     mLayerSnapshotBuilder.getSnapshot(layer->sequence);
3369*38e8c45fSAndroid Build Coastguard Worker             std::optional<const DisplayDevice*> displayOpt = std::nullopt;
3370*38e8c45fSAndroid Build Coastguard Worker             if (snapshot) {
3371*38e8c45fSAndroid Build Coastguard Worker                 displayOpt = layerStackToDisplay.get(snapshot->outputFilter.layerStack);
3372*38e8c45fSAndroid Build Coastguard Worker             }
3373*38e8c45fSAndroid Build Coastguard Worker             const DisplayDevice* display = displayOpt.value_or(nullptr);
3374*38e8c45fSAndroid Build Coastguard Worker             layer->updateTrustedPresentationState(display, snapshot,
3375*38e8c45fSAndroid Build Coastguard Worker                                                   nanoseconds_to_milliseconds(presentStartTime),
3376*38e8c45fSAndroid Build Coastguard Worker                                                   false);
3377*38e8c45fSAndroid Build Coastguard Worker         });
3378*38e8c45fSAndroid Build Coastguard Worker     }
3379*38e8c45fSAndroid Build Coastguard Worker 
3380*38e8c45fSAndroid Build Coastguard Worker     // Even though SFTRACE_INT64 already checks if tracing is enabled, it doesn't prevent the
3381*38e8c45fSAndroid Build Coastguard Worker     // side-effect of getTotalSize(), so we check that again here
3382*38e8c45fSAndroid Build Coastguard Worker     if (SFTRACE_ENABLED()) {
3383*38e8c45fSAndroid Build Coastguard Worker         // getTotalSize returns the total number of buffers that were allocated by SurfaceFlinger
3384*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_INT64("Total Buffer Size", GraphicBufferAllocator::get().getTotalSize());
3385*38e8c45fSAndroid Build Coastguard Worker     }
3386*38e8c45fSAndroid Build Coastguard Worker }
3387*38e8c45fSAndroid Build Coastguard Worker 
commitTransactions()3388*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::commitTransactions() {
3389*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
3390*38e8c45fSAndroid Build Coastguard Worker     mDebugInTransaction = systemTime();
3391*38e8c45fSAndroid Build Coastguard Worker 
3392*38e8c45fSAndroid Build Coastguard Worker     // Here we're guaranteed that some transaction flags are set
3393*38e8c45fSAndroid Build Coastguard Worker     // so we can call commitTransactionsLocked unconditionally.
3394*38e8c45fSAndroid Build Coastguard Worker     // We clear the flags with mStateLock held to guarantee that
3395*38e8c45fSAndroid Build Coastguard Worker     // mCurrentState won't change until the transaction is committed.
3396*38e8c45fSAndroid Build Coastguard Worker     mScheduler->modulateVsync({}, &VsyncModulator::onTransactionCommit);
3397*38e8c45fSAndroid Build Coastguard Worker     commitTransactionsLocked(clearTransactionFlags(eTransactionMask));
3398*38e8c45fSAndroid Build Coastguard Worker     mDebugInTransaction = 0;
3399*38e8c45fSAndroid Build Coastguard Worker }
3400*38e8c45fSAndroid Build Coastguard Worker 
loadDisplayModes(PhysicalDisplayId displayId) const3401*38e8c45fSAndroid Build Coastguard Worker std::pair<DisplayModes, DisplayModePtr> SurfaceFlinger::loadDisplayModes(
3402*38e8c45fSAndroid Build Coastguard Worker         PhysicalDisplayId displayId) const {
3403*38e8c45fSAndroid Build Coastguard Worker     std::vector<HWComposer::HWCDisplayMode> hwcModes;
3404*38e8c45fSAndroid Build Coastguard Worker     std::optional<hal::HWConfigId> activeModeHwcIdOpt;
3405*38e8c45fSAndroid Build Coastguard Worker 
3406*38e8c45fSAndroid Build Coastguard Worker     const bool isExternalDisplay = FlagManager::getInstance().connected_display() &&
3407*38e8c45fSAndroid Build Coastguard Worker             getHwComposer().getDisplayConnectionType(displayId) ==
3408*38e8c45fSAndroid Build Coastguard Worker                     ui::DisplayConnectionType::External;
3409*38e8c45fSAndroid Build Coastguard Worker 
3410*38e8c45fSAndroid Build Coastguard Worker     int attempt = 0;
3411*38e8c45fSAndroid Build Coastguard Worker     constexpr int kMaxAttempts = 3;
3412*38e8c45fSAndroid Build Coastguard Worker     do {
3413*38e8c45fSAndroid Build Coastguard Worker         hwcModes = getHwComposer().getModes(displayId,
3414*38e8c45fSAndroid Build Coastguard Worker                                             scheduler::RefreshRateSelector::kMinSupportedFrameRate
3415*38e8c45fSAndroid Build Coastguard Worker                                                     .getPeriodNsecs());
3416*38e8c45fSAndroid Build Coastguard Worker         const auto activeModeHwcIdExp = getHwComposer().getActiveMode(displayId);
3417*38e8c45fSAndroid Build Coastguard Worker         activeModeHwcIdOpt = activeModeHwcIdExp.value_opt();
3418*38e8c45fSAndroid Build Coastguard Worker 
3419*38e8c45fSAndroid Build Coastguard Worker         if (isExternalDisplay &&
3420*38e8c45fSAndroid Build Coastguard Worker             activeModeHwcIdExp.has_error([](status_t error) { return error == NO_INIT; })) {
3421*38e8c45fSAndroid Build Coastguard Worker             constexpr nsecs_t k59HzVsyncPeriod = 16949153;
3422*38e8c45fSAndroid Build Coastguard Worker             constexpr nsecs_t k60HzVsyncPeriod = 16666667;
3423*38e8c45fSAndroid Build Coastguard Worker 
3424*38e8c45fSAndroid Build Coastguard Worker             // DM sets the initial mode for an external display to 1080p@60, but
3425*38e8c45fSAndroid Build Coastguard Worker             // this comes after SF creates its own state (including the
3426*38e8c45fSAndroid Build Coastguard Worker             // DisplayDevice). For now, pick the same mode in order to avoid
3427*38e8c45fSAndroid Build Coastguard Worker             // inconsistent state and unnecessary mode switching.
3428*38e8c45fSAndroid Build Coastguard Worker             // TODO (b/318534874): Let DM decide the initial mode.
3429*38e8c45fSAndroid Build Coastguard Worker             //
3430*38e8c45fSAndroid Build Coastguard Worker             // Try to find 1920x1080 @ 60 Hz
3431*38e8c45fSAndroid Build Coastguard Worker             if (const auto iter = std::find_if(hwcModes.begin(), hwcModes.end(),
3432*38e8c45fSAndroid Build Coastguard Worker                                                [](const auto& mode) {
3433*38e8c45fSAndroid Build Coastguard Worker                                                    return mode.width == 1920 &&
3434*38e8c45fSAndroid Build Coastguard Worker                                                            mode.height == 1080 &&
3435*38e8c45fSAndroid Build Coastguard Worker                                                            mode.vsyncPeriod == k60HzVsyncPeriod;
3436*38e8c45fSAndroid Build Coastguard Worker                                                });
3437*38e8c45fSAndroid Build Coastguard Worker                 iter != hwcModes.end()) {
3438*38e8c45fSAndroid Build Coastguard Worker                 activeModeHwcIdOpt = iter->hwcId;
3439*38e8c45fSAndroid Build Coastguard Worker                 break;
3440*38e8c45fSAndroid Build Coastguard Worker             }
3441*38e8c45fSAndroid Build Coastguard Worker 
3442*38e8c45fSAndroid Build Coastguard Worker             // Try to find 1920x1080 @ 59-60 Hz
3443*38e8c45fSAndroid Build Coastguard Worker             if (const auto iter = std::find_if(hwcModes.begin(), hwcModes.end(),
3444*38e8c45fSAndroid Build Coastguard Worker                                                [](const auto& mode) {
3445*38e8c45fSAndroid Build Coastguard Worker                                                    return mode.width == 1920 &&
3446*38e8c45fSAndroid Build Coastguard Worker                                                            mode.height == 1080 &&
3447*38e8c45fSAndroid Build Coastguard Worker                                                            mode.vsyncPeriod >= k60HzVsyncPeriod &&
3448*38e8c45fSAndroid Build Coastguard Worker                                                            mode.vsyncPeriod <= k59HzVsyncPeriod;
3449*38e8c45fSAndroid Build Coastguard Worker                                                });
3450*38e8c45fSAndroid Build Coastguard Worker                 iter != hwcModes.end()) {
3451*38e8c45fSAndroid Build Coastguard Worker                 activeModeHwcIdOpt = iter->hwcId;
3452*38e8c45fSAndroid Build Coastguard Worker                 break;
3453*38e8c45fSAndroid Build Coastguard Worker             }
3454*38e8c45fSAndroid Build Coastguard Worker 
3455*38e8c45fSAndroid Build Coastguard Worker             // The display does not support 1080p@60, and this is the last attempt to pick a display
3456*38e8c45fSAndroid Build Coastguard Worker             // mode. Prefer 60 Hz if available, with the closest resolution to 1080p.
3457*38e8c45fSAndroid Build Coastguard Worker             if (attempt + 1 == kMaxAttempts) {
3458*38e8c45fSAndroid Build Coastguard Worker                 std::vector<HWComposer::HWCDisplayMode> hwcModeOpts;
3459*38e8c45fSAndroid Build Coastguard Worker 
3460*38e8c45fSAndroid Build Coastguard Worker                 for (const auto& mode : hwcModes) {
3461*38e8c45fSAndroid Build Coastguard Worker                     if (mode.width <= 1920 && mode.height <= 1080 &&
3462*38e8c45fSAndroid Build Coastguard Worker                         mode.vsyncPeriod >= k60HzVsyncPeriod &&
3463*38e8c45fSAndroid Build Coastguard Worker                         mode.vsyncPeriod <= k59HzVsyncPeriod) {
3464*38e8c45fSAndroid Build Coastguard Worker                         hwcModeOpts.push_back(mode);
3465*38e8c45fSAndroid Build Coastguard Worker                     }
3466*38e8c45fSAndroid Build Coastguard Worker                 }
3467*38e8c45fSAndroid Build Coastguard Worker 
3468*38e8c45fSAndroid Build Coastguard Worker                 if (const auto iter = std::max_element(hwcModeOpts.begin(), hwcModeOpts.end(),
3469*38e8c45fSAndroid Build Coastguard Worker                                                        [](const auto& a, const auto& b) {
3470*38e8c45fSAndroid Build Coastguard Worker                                                            const auto aSize = a.width * a.height;
3471*38e8c45fSAndroid Build Coastguard Worker                                                            const auto bSize = b.width * b.height;
3472*38e8c45fSAndroid Build Coastguard Worker                                                            if (aSize < bSize)
3473*38e8c45fSAndroid Build Coastguard Worker                                                                return true;
3474*38e8c45fSAndroid Build Coastguard Worker                                                            else if (aSize == bSize)
3475*38e8c45fSAndroid Build Coastguard Worker                                                                return a.vsyncPeriod > b.vsyncPeriod;
3476*38e8c45fSAndroid Build Coastguard Worker                                                            else
3477*38e8c45fSAndroid Build Coastguard Worker                                                                return false;
3478*38e8c45fSAndroid Build Coastguard Worker                                                        });
3479*38e8c45fSAndroid Build Coastguard Worker                     iter != hwcModeOpts.end()) {
3480*38e8c45fSAndroid Build Coastguard Worker                     activeModeHwcIdOpt = iter->hwcId;
3481*38e8c45fSAndroid Build Coastguard Worker                     break;
3482*38e8c45fSAndroid Build Coastguard Worker                 }
3483*38e8c45fSAndroid Build Coastguard Worker 
3484*38e8c45fSAndroid Build Coastguard Worker                 // hwcModeOpts was empty, use hwcModes[0] as the last resort
3485*38e8c45fSAndroid Build Coastguard Worker                 activeModeHwcIdOpt = hwcModes[0].hwcId;
3486*38e8c45fSAndroid Build Coastguard Worker             }
3487*38e8c45fSAndroid Build Coastguard Worker         }
3488*38e8c45fSAndroid Build Coastguard Worker 
3489*38e8c45fSAndroid Build Coastguard Worker         const auto isActiveMode = [activeModeHwcIdOpt](const HWComposer::HWCDisplayMode& mode) {
3490*38e8c45fSAndroid Build Coastguard Worker             return mode.hwcId == activeModeHwcIdOpt;
3491*38e8c45fSAndroid Build Coastguard Worker         };
3492*38e8c45fSAndroid Build Coastguard Worker 
3493*38e8c45fSAndroid Build Coastguard Worker         if (std::any_of(hwcModes.begin(), hwcModes.end(), isActiveMode)) {
3494*38e8c45fSAndroid Build Coastguard Worker             break;
3495*38e8c45fSAndroid Build Coastguard Worker         }
3496*38e8c45fSAndroid Build Coastguard Worker     } while (++attempt < kMaxAttempts);
3497*38e8c45fSAndroid Build Coastguard Worker 
3498*38e8c45fSAndroid Build Coastguard Worker     if (attempt == kMaxAttempts) {
3499*38e8c45fSAndroid Build Coastguard Worker         const std::string activeMode =
3500*38e8c45fSAndroid Build Coastguard Worker                 activeModeHwcIdOpt ? std::to_string(*activeModeHwcIdOpt) : "unknown"s;
3501*38e8c45fSAndroid Build Coastguard Worker         ALOGE("HWC failed to report an active mode that is supported: activeModeHwcId=%s, "
3502*38e8c45fSAndroid Build Coastguard Worker               "hwcModes={%s}",
3503*38e8c45fSAndroid Build Coastguard Worker               activeMode.c_str(), base::Join(hwcModes, ", ").c_str());
3504*38e8c45fSAndroid Build Coastguard Worker         return {};
3505*38e8c45fSAndroid Build Coastguard Worker     }
3506*38e8c45fSAndroid Build Coastguard Worker 
3507*38e8c45fSAndroid Build Coastguard Worker     const DisplayModes oldModes = mPhysicalDisplays.get(displayId)
3508*38e8c45fSAndroid Build Coastguard Worker                                           .transform([](const PhysicalDisplay& display) {
3509*38e8c45fSAndroid Build Coastguard Worker                                               return display.snapshot().displayModes();
3510*38e8c45fSAndroid Build Coastguard Worker                                           })
3511*38e8c45fSAndroid Build Coastguard Worker                                           .value_or(DisplayModes{});
3512*38e8c45fSAndroid Build Coastguard Worker 
3513*38e8c45fSAndroid Build Coastguard Worker     DisplayModeId nextModeId = std::accumulate(oldModes.begin(), oldModes.end(), DisplayModeId(-1),
3514*38e8c45fSAndroid Build Coastguard Worker                                                [](DisplayModeId max, const auto& pair) {
3515*38e8c45fSAndroid Build Coastguard Worker                                                    return std::max(max, pair.first);
3516*38e8c45fSAndroid Build Coastguard Worker                                                });
3517*38e8c45fSAndroid Build Coastguard Worker     ++nextModeId;
3518*38e8c45fSAndroid Build Coastguard Worker 
3519*38e8c45fSAndroid Build Coastguard Worker     DisplayModes newModes;
3520*38e8c45fSAndroid Build Coastguard Worker     for (const auto& hwcMode : hwcModes) {
3521*38e8c45fSAndroid Build Coastguard Worker         const auto id = nextModeId++;
3522*38e8c45fSAndroid Build Coastguard Worker         OutputType hdrOutputType = FlagManager::getInstance().connected_display_hdr()
3523*38e8c45fSAndroid Build Coastguard Worker                 ? hwcMode.hdrOutputType
3524*38e8c45fSAndroid Build Coastguard Worker                 : OutputType::INVALID;
3525*38e8c45fSAndroid Build Coastguard Worker         newModes.try_emplace(id,
3526*38e8c45fSAndroid Build Coastguard Worker                              DisplayMode::Builder(hwcMode.hwcId)
3527*38e8c45fSAndroid Build Coastguard Worker                                      .setId(id)
3528*38e8c45fSAndroid Build Coastguard Worker                                      .setPhysicalDisplayId(displayId)
3529*38e8c45fSAndroid Build Coastguard Worker                                      .setResolution({hwcMode.width, hwcMode.height})
3530*38e8c45fSAndroid Build Coastguard Worker                                      .setVsyncPeriod(hwcMode.vsyncPeriod)
3531*38e8c45fSAndroid Build Coastguard Worker                                      .setVrrConfig(hwcMode.vrrConfig)
3532*38e8c45fSAndroid Build Coastguard Worker                                      .setDpiX(hwcMode.dpiX)
3533*38e8c45fSAndroid Build Coastguard Worker                                      .setDpiY(hwcMode.dpiY)
3534*38e8c45fSAndroid Build Coastguard Worker                                      .setGroup(hwcMode.configGroup)
3535*38e8c45fSAndroid Build Coastguard Worker                                      .setHdrOutputType(hdrOutputType)
3536*38e8c45fSAndroid Build Coastguard Worker                                      .build());
3537*38e8c45fSAndroid Build Coastguard Worker     }
3538*38e8c45fSAndroid Build Coastguard Worker 
3539*38e8c45fSAndroid Build Coastguard Worker     const bool sameModes =
3540*38e8c45fSAndroid Build Coastguard Worker             std::equal(newModes.begin(), newModes.end(), oldModes.begin(), oldModes.end(),
3541*38e8c45fSAndroid Build Coastguard Worker                        [](const auto& lhs, const auto& rhs) {
3542*38e8c45fSAndroid Build Coastguard Worker                            return equalsExceptDisplayModeId(*lhs.second, *rhs.second);
3543*38e8c45fSAndroid Build Coastguard Worker                        });
3544*38e8c45fSAndroid Build Coastguard Worker 
3545*38e8c45fSAndroid Build Coastguard Worker     // Keep IDs if modes have not changed.
3546*38e8c45fSAndroid Build Coastguard Worker     const auto& modes = sameModes ? oldModes : newModes;
3547*38e8c45fSAndroid Build Coastguard Worker     const DisplayModePtr activeMode =
3548*38e8c45fSAndroid Build Coastguard Worker             std::find_if(modes.begin(), modes.end(), [activeModeHwcIdOpt](const auto& pair) {
3549*38e8c45fSAndroid Build Coastguard Worker                 return pair.second->getHwcId() == activeModeHwcIdOpt;
3550*38e8c45fSAndroid Build Coastguard Worker             })->second;
3551*38e8c45fSAndroid Build Coastguard Worker 
3552*38e8c45fSAndroid Build Coastguard Worker     if (isExternalDisplay) {
3553*38e8c45fSAndroid Build Coastguard Worker         ALOGI("External display %s initial mode: {%s}", to_string(displayId).c_str(),
3554*38e8c45fSAndroid Build Coastguard Worker               to_string(*activeMode).c_str());
3555*38e8c45fSAndroid Build Coastguard Worker     }
3556*38e8c45fSAndroid Build Coastguard Worker     return {modes, activeMode};
3557*38e8c45fSAndroid Build Coastguard Worker }
3558*38e8c45fSAndroid Build Coastguard Worker 
configureLocked()3559*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::configureLocked() {
3560*38e8c45fSAndroid Build Coastguard Worker     std::vector<HotplugEvent> events;
3561*38e8c45fSAndroid Build Coastguard Worker     {
3562*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mHotplugMutex);
3563*38e8c45fSAndroid Build Coastguard Worker         events = std::move(mPendingHotplugEvents);
3564*38e8c45fSAndroid Build Coastguard Worker     }
3565*38e8c45fSAndroid Build Coastguard Worker 
3566*38e8c45fSAndroid Build Coastguard Worker     for (const auto [hwcDisplayId, connection] : events) {
3567*38e8c45fSAndroid Build Coastguard Worker         if (auto info = getHwComposer().onHotplug(hwcDisplayId, connection)) {
3568*38e8c45fSAndroid Build Coastguard Worker             const auto displayId = info->id;
3569*38e8c45fSAndroid Build Coastguard Worker             const ftl::Concat displayString("display ", displayId.value, "(HAL ID ", hwcDisplayId,
3570*38e8c45fSAndroid Build Coastguard Worker                                             ')');
3571*38e8c45fSAndroid Build Coastguard Worker 
3572*38e8c45fSAndroid Build Coastguard Worker             if (connection == hal::Connection::CONNECTED) {
3573*38e8c45fSAndroid Build Coastguard Worker                 const auto activeModeIdOpt =
3574*38e8c45fSAndroid Build Coastguard Worker                         processHotplugConnect(displayId, hwcDisplayId, std::move(*info),
3575*38e8c45fSAndroid Build Coastguard Worker                                               displayString.c_str());
3576*38e8c45fSAndroid Build Coastguard Worker                 if (!activeModeIdOpt) {
3577*38e8c45fSAndroid Build Coastguard Worker                     mScheduler->dispatchHotplugError(
3578*38e8c45fSAndroid Build Coastguard Worker                             static_cast<int32_t>(DisplayHotplugEvent::ERROR_UNKNOWN));
3579*38e8c45fSAndroid Build Coastguard Worker                     getHwComposer().disconnectDisplay(displayId);
3580*38e8c45fSAndroid Build Coastguard Worker                     continue;
3581*38e8c45fSAndroid Build Coastguard Worker                 }
3582*38e8c45fSAndroid Build Coastguard Worker 
3583*38e8c45fSAndroid Build Coastguard Worker                 const auto [kernelIdleTimerController, idleTimerTimeoutMs] =
3584*38e8c45fSAndroid Build Coastguard Worker                         getKernelIdleTimerProperties(displayId);
3585*38e8c45fSAndroid Build Coastguard Worker 
3586*38e8c45fSAndroid Build Coastguard Worker                 using Config = scheduler::RefreshRateSelector::Config;
3587*38e8c45fSAndroid Build Coastguard Worker                 const Config config =
3588*38e8c45fSAndroid Build Coastguard Worker                         {.enableFrameRateOverride = sysprop::enable_frame_rate_override(true)
3589*38e8c45fSAndroid Build Coastguard Worker                                  ? Config::FrameRateOverride::Enabled
3590*38e8c45fSAndroid Build Coastguard Worker                                  : Config::FrameRateOverride::Disabled,
3591*38e8c45fSAndroid Build Coastguard Worker                          .frameRateMultipleThreshold =
3592*38e8c45fSAndroid Build Coastguard Worker                                  base::GetIntProperty("debug.sf.frame_rate_multiple_threshold"s, 0),
3593*38e8c45fSAndroid Build Coastguard Worker                          .legacyIdleTimerTimeout = idleTimerTimeoutMs,
3594*38e8c45fSAndroid Build Coastguard Worker                          .kernelIdleTimerController = kernelIdleTimerController};
3595*38e8c45fSAndroid Build Coastguard Worker 
3596*38e8c45fSAndroid Build Coastguard Worker                 const auto snapshotOpt =
3597*38e8c45fSAndroid Build Coastguard Worker                         mPhysicalDisplays.get(displayId).transform(&PhysicalDisplay::snapshotRef);
3598*38e8c45fSAndroid Build Coastguard Worker                 LOG_ALWAYS_FATAL_IF(!snapshotOpt);
3599*38e8c45fSAndroid Build Coastguard Worker 
3600*38e8c45fSAndroid Build Coastguard Worker                 mDisplayModeController.registerDisplay(*snapshotOpt, *activeModeIdOpt, config);
3601*38e8c45fSAndroid Build Coastguard Worker             } else {
3602*38e8c45fSAndroid Build Coastguard Worker                 // Unregister before destroying the DisplaySnapshot below.
3603*38e8c45fSAndroid Build Coastguard Worker                 mDisplayModeController.unregisterDisplay(displayId);
3604*38e8c45fSAndroid Build Coastguard Worker 
3605*38e8c45fSAndroid Build Coastguard Worker                 processHotplugDisconnect(displayId, displayString.c_str());
3606*38e8c45fSAndroid Build Coastguard Worker             }
3607*38e8c45fSAndroid Build Coastguard Worker         }
3608*38e8c45fSAndroid Build Coastguard Worker     }
3609*38e8c45fSAndroid Build Coastguard Worker 
3610*38e8c45fSAndroid Build Coastguard Worker     return !events.empty();
3611*38e8c45fSAndroid Build Coastguard Worker }
3612*38e8c45fSAndroid Build Coastguard Worker 
processHotplugConnect(PhysicalDisplayId displayId,hal::HWDisplayId hwcDisplayId,DisplayIdentificationInfo && info,const char * displayString)3613*38e8c45fSAndroid Build Coastguard Worker std::optional<DisplayModeId> SurfaceFlinger::processHotplugConnect(PhysicalDisplayId displayId,
3614*38e8c45fSAndroid Build Coastguard Worker                                                                    hal::HWDisplayId hwcDisplayId,
3615*38e8c45fSAndroid Build Coastguard Worker                                                                    DisplayIdentificationInfo&& info,
3616*38e8c45fSAndroid Build Coastguard Worker                                                                    const char* displayString) {
3617*38e8c45fSAndroid Build Coastguard Worker     auto [displayModes, activeMode] = loadDisplayModes(displayId);
3618*38e8c45fSAndroid Build Coastguard Worker     if (!activeMode) {
3619*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Failed to hotplug %s", displayString);
3620*38e8c45fSAndroid Build Coastguard Worker         return std::nullopt;
3621*38e8c45fSAndroid Build Coastguard Worker     }
3622*38e8c45fSAndroid Build Coastguard Worker 
3623*38e8c45fSAndroid Build Coastguard Worker     const DisplayModeId activeModeId = activeMode->getId();
3624*38e8c45fSAndroid Build Coastguard Worker     ui::ColorModes colorModes = getHwComposer().getColorModes(displayId);
3625*38e8c45fSAndroid Build Coastguard Worker 
3626*38e8c45fSAndroid Build Coastguard Worker     if (const auto displayOpt = mPhysicalDisplays.get(displayId)) {
3627*38e8c45fSAndroid Build Coastguard Worker         const auto& display = displayOpt->get();
3628*38e8c45fSAndroid Build Coastguard Worker         const auto& snapshot = display.snapshot();
3629*38e8c45fSAndroid Build Coastguard Worker 
3630*38e8c45fSAndroid Build Coastguard Worker         std::optional<DeviceProductInfo> deviceProductInfo;
3631*38e8c45fSAndroid Build Coastguard Worker         if (getHwComposer().updatesDeviceProductInfoOnHotplugReconnect()) {
3632*38e8c45fSAndroid Build Coastguard Worker             deviceProductInfo = std::move(info.deviceProductInfo);
3633*38e8c45fSAndroid Build Coastguard Worker         } else {
3634*38e8c45fSAndroid Build Coastguard Worker             deviceProductInfo = snapshot.deviceProductInfo();
3635*38e8c45fSAndroid Build Coastguard Worker         }
3636*38e8c45fSAndroid Build Coastguard Worker 
3637*38e8c45fSAndroid Build Coastguard Worker         const auto it =
3638*38e8c45fSAndroid Build Coastguard Worker                 mPhysicalDisplays.try_replace(displayId, display.token(), displayId,
3639*38e8c45fSAndroid Build Coastguard Worker                                               snapshot.connectionType(), std::move(displayModes),
3640*38e8c45fSAndroid Build Coastguard Worker                                               std::move(colorModes), std::move(deviceProductInfo));
3641*38e8c45fSAndroid Build Coastguard Worker 
3642*38e8c45fSAndroid Build Coastguard Worker         auto& state = mCurrentState.displays.editValueFor(it->second.token());
3643*38e8c45fSAndroid Build Coastguard Worker         state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId.
3644*38e8c45fSAndroid Build Coastguard Worker         state.physical->activeMode = std::move(activeMode);
3645*38e8c45fSAndroid Build Coastguard Worker         ALOGI("Reconnecting %s", displayString);
3646*38e8c45fSAndroid Build Coastguard Worker         return activeModeId;
3647*38e8c45fSAndroid Build Coastguard Worker     }
3648*38e8c45fSAndroid Build Coastguard Worker 
3649*38e8c45fSAndroid Build Coastguard Worker     const sp<IBinder> token = sp<BBinder>::make();
3650*38e8c45fSAndroid Build Coastguard Worker     const ui::DisplayConnectionType connectionType =
3651*38e8c45fSAndroid Build Coastguard Worker             getHwComposer().getDisplayConnectionType(displayId);
3652*38e8c45fSAndroid Build Coastguard Worker 
3653*38e8c45fSAndroid Build Coastguard Worker     mPhysicalDisplays.try_emplace(displayId, token, displayId, connectionType,
3654*38e8c45fSAndroid Build Coastguard Worker                                   std::move(displayModes), std::move(colorModes),
3655*38e8c45fSAndroid Build Coastguard Worker                                   std::move(info.deviceProductInfo));
3656*38e8c45fSAndroid Build Coastguard Worker 
3657*38e8c45fSAndroid Build Coastguard Worker     DisplayDeviceState state;
3658*38e8c45fSAndroid Build Coastguard Worker     state.physical = {.id = displayId,
3659*38e8c45fSAndroid Build Coastguard Worker                       .hwcDisplayId = hwcDisplayId,
3660*38e8c45fSAndroid Build Coastguard Worker                       .activeMode = std::move(activeMode)};
3661*38e8c45fSAndroid Build Coastguard Worker     if (mIsHdcpViaNegVsync) {
3662*38e8c45fSAndroid Build Coastguard Worker         state.isSecure = connectionType == ui::DisplayConnectionType::Internal;
3663*38e8c45fSAndroid Build Coastguard Worker     } else {
3664*38e8c45fSAndroid Build Coastguard Worker         // TODO(b/349703362): Remove this when HDCP aidl API becomes ready
3665*38e8c45fSAndroid Build Coastguard Worker         state.isSecure = true; // All physical displays are currently considered secure.
3666*38e8c45fSAndroid Build Coastguard Worker     }
3667*38e8c45fSAndroid Build Coastguard Worker     state.isProtected = true;
3668*38e8c45fSAndroid Build Coastguard Worker     state.displayName = std::move(info.name);
3669*38e8c45fSAndroid Build Coastguard Worker     state.maxLayerPictureProfiles = getHwComposer().getMaxLayerPictureProfiles(displayId);
3670*38e8c45fSAndroid Build Coastguard Worker     state.hasPictureProcessing =
3671*38e8c45fSAndroid Build Coastguard Worker             getHwComposer().hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING);
3672*38e8c45fSAndroid Build Coastguard Worker     mCurrentState.displays.add(token, state);
3673*38e8c45fSAndroid Build Coastguard Worker     ALOGI("Connecting %s", displayString);
3674*38e8c45fSAndroid Build Coastguard Worker     return activeModeId;
3675*38e8c45fSAndroid Build Coastguard Worker }
3676*38e8c45fSAndroid Build Coastguard Worker 
processHotplugDisconnect(PhysicalDisplayId displayId,const char * displayString)3677*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::processHotplugDisconnect(PhysicalDisplayId displayId,
3678*38e8c45fSAndroid Build Coastguard Worker                                               const char* displayString) {
3679*38e8c45fSAndroid Build Coastguard Worker     ALOGI("Disconnecting %s", displayString);
3680*38e8c45fSAndroid Build Coastguard Worker 
3681*38e8c45fSAndroid Build Coastguard Worker     const auto displayOpt = mPhysicalDisplays.get(displayId);
3682*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!displayOpt);
3683*38e8c45fSAndroid Build Coastguard Worker     const auto& display = displayOpt->get();
3684*38e8c45fSAndroid Build Coastguard Worker 
3685*38e8c45fSAndroid Build Coastguard Worker     if (const ssize_t index = mCurrentState.displays.indexOfKey(display.token()); index >= 0) {
3686*38e8c45fSAndroid Build Coastguard Worker         mCurrentState.displays.removeItemsAt(index);
3687*38e8c45fSAndroid Build Coastguard Worker     }
3688*38e8c45fSAndroid Build Coastguard Worker 
3689*38e8c45fSAndroid Build Coastguard Worker     mPhysicalDisplays.erase(displayId);
3690*38e8c45fSAndroid Build Coastguard Worker }
3691*38e8c45fSAndroid Build Coastguard Worker 
setupNewDisplayDeviceInternal(const wp<IBinder> & displayToken,std::shared_ptr<compositionengine::Display> compositionDisplay,const DisplayDeviceState & state,const sp<compositionengine::DisplaySurface> & displaySurface,const sp<IGraphicBufferProducer> & producer)3692*38e8c45fSAndroid Build Coastguard Worker sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
3693*38e8c45fSAndroid Build Coastguard Worker         const wp<IBinder>& displayToken,
3694*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<compositionengine::Display> compositionDisplay,
3695*38e8c45fSAndroid Build Coastguard Worker         const DisplayDeviceState& state,
3696*38e8c45fSAndroid Build Coastguard Worker         const sp<compositionengine::DisplaySurface>& displaySurface,
3697*38e8c45fSAndroid Build Coastguard Worker         const sp<IGraphicBufferProducer>& producer) {
3698*38e8c45fSAndroid Build Coastguard Worker     DisplayDeviceCreationArgs creationArgs(sp<SurfaceFlinger>::fromExisting(this), getHwComposer(),
3699*38e8c45fSAndroid Build Coastguard Worker                                            displayToken, compositionDisplay);
3700*38e8c45fSAndroid Build Coastguard Worker     creationArgs.sequenceId = state.sequenceId;
3701*38e8c45fSAndroid Build Coastguard Worker     creationArgs.isSecure = state.isSecure;
3702*38e8c45fSAndroid Build Coastguard Worker     creationArgs.isProtected = state.isProtected;
3703*38e8c45fSAndroid Build Coastguard Worker     creationArgs.displaySurface = displaySurface;
3704*38e8c45fSAndroid Build Coastguard Worker     creationArgs.hasWideColorGamut = false;
3705*38e8c45fSAndroid Build Coastguard Worker     creationArgs.supportedPerFrameMetadata = 0;
3706*38e8c45fSAndroid Build Coastguard Worker 
3707*38e8c45fSAndroid Build Coastguard Worker     if (const auto physicalIdOpt = PhysicalDisplayId::tryCast(compositionDisplay->getId())) {
3708*38e8c45fSAndroid Build Coastguard Worker         const auto physicalId = *physicalIdOpt;
3709*38e8c45fSAndroid Build Coastguard Worker 
3710*38e8c45fSAndroid Build Coastguard Worker         creationArgs.isPrimary = physicalId == getPrimaryDisplayIdLocked();
3711*38e8c45fSAndroid Build Coastguard Worker         creationArgs.refreshRateSelector =
3712*38e8c45fSAndroid Build Coastguard Worker                 FTL_FAKE_GUARD(kMainThreadContext,
3713*38e8c45fSAndroid Build Coastguard Worker                                mDisplayModeController.selectorPtrFor(physicalId));
3714*38e8c45fSAndroid Build Coastguard Worker 
3715*38e8c45fSAndroid Build Coastguard Worker         mPhysicalDisplays.get(physicalId)
3716*38e8c45fSAndroid Build Coastguard Worker                 .transform(&PhysicalDisplay::snapshotRef)
3717*38e8c45fSAndroid Build Coastguard Worker                 .transform(ftl::unit_fn([&](const display::DisplaySnapshot& snapshot) {
3718*38e8c45fSAndroid Build Coastguard Worker                     for (const auto mode : snapshot.colorModes()) {
3719*38e8c45fSAndroid Build Coastguard Worker                         creationArgs.hasWideColorGamut |= ui::isWideColorMode(mode);
3720*38e8c45fSAndroid Build Coastguard Worker                         creationArgs.hwcColorModes
3721*38e8c45fSAndroid Build Coastguard Worker                                 .emplace(mode, getHwComposer().getRenderIntents(physicalId, mode));
3722*38e8c45fSAndroid Build Coastguard Worker                     }
3723*38e8c45fSAndroid Build Coastguard Worker                 }));
3724*38e8c45fSAndroid Build Coastguard Worker     }
3725*38e8c45fSAndroid Build Coastguard Worker 
3726*38e8c45fSAndroid Build Coastguard Worker     if (const auto id = HalDisplayId::tryCast(compositionDisplay->getId())) {
3727*38e8c45fSAndroid Build Coastguard Worker         getHwComposer().getHdrCapabilities(*id, &creationArgs.hdrCapabilities);
3728*38e8c45fSAndroid Build Coastguard Worker         creationArgs.supportedPerFrameMetadata = getHwComposer().getSupportedPerFrameMetadata(*id);
3729*38e8c45fSAndroid Build Coastguard Worker     }
3730*38e8c45fSAndroid Build Coastguard Worker 
3731*38e8c45fSAndroid Build Coastguard Worker     auto nativeWindowSurface = getFactory().createNativeWindowSurface(producer);
3732*38e8c45fSAndroid Build Coastguard Worker     auto nativeWindow = nativeWindowSurface->getNativeWindow();
3733*38e8c45fSAndroid Build Coastguard Worker     creationArgs.nativeWindow = nativeWindow;
3734*38e8c45fSAndroid Build Coastguard Worker 
3735*38e8c45fSAndroid Build Coastguard Worker     // Make sure that composition can never be stalled by a virtual display
3736*38e8c45fSAndroid Build Coastguard Worker     // consumer that isn't processing buffers fast enough. We have to do this
3737*38e8c45fSAndroid Build Coastguard Worker     // here, in case the display is composed entirely by HWC.
3738*38e8c45fSAndroid Build Coastguard Worker     if (state.isVirtual()) {
3739*38e8c45fSAndroid Build Coastguard Worker         nativeWindow->setSwapInterval(nativeWindow.get(), 0);
3740*38e8c45fSAndroid Build Coastguard Worker     }
3741*38e8c45fSAndroid Build Coastguard Worker 
3742*38e8c45fSAndroid Build Coastguard Worker     creationArgs.physicalOrientation =
3743*38e8c45fSAndroid Build Coastguard Worker             getPhysicalDisplayOrientation(compositionDisplay->getId(), creationArgs.isPrimary);
3744*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Display Orientation: %s", toCString(creationArgs.physicalOrientation));
3745*38e8c45fSAndroid Build Coastguard Worker 
3746*38e8c45fSAndroid Build Coastguard Worker     creationArgs.initialPowerMode = state.isVirtual() ? hal::PowerMode::ON : hal::PowerMode::OFF;
3747*38e8c45fSAndroid Build Coastguard Worker 
3748*38e8c45fSAndroid Build Coastguard Worker     creationArgs.requestedRefreshRate = state.requestedRefreshRate;
3749*38e8c45fSAndroid Build Coastguard Worker 
3750*38e8c45fSAndroid Build Coastguard Worker     sp<DisplayDevice> display = getFactory().createDisplayDevice(creationArgs);
3751*38e8c45fSAndroid Build Coastguard Worker 
3752*38e8c45fSAndroid Build Coastguard Worker     nativeWindowSurface->preallocateBuffers();
3753*38e8c45fSAndroid Build Coastguard Worker 
3754*38e8c45fSAndroid Build Coastguard Worker     ui::ColorMode defaultColorMode = ui::ColorMode::NATIVE;
3755*38e8c45fSAndroid Build Coastguard Worker     Dataspace defaultDataSpace = Dataspace::UNKNOWN;
3756*38e8c45fSAndroid Build Coastguard Worker     if (display->hasWideColorGamut()) {
3757*38e8c45fSAndroid Build Coastguard Worker         defaultColorMode = ui::ColorMode::SRGB;
3758*38e8c45fSAndroid Build Coastguard Worker         defaultDataSpace = Dataspace::V0_SRGB;
3759*38e8c45fSAndroid Build Coastguard Worker     }
3760*38e8c45fSAndroid Build Coastguard Worker     display->getCompositionDisplay()->setColorProfile(
3761*38e8c45fSAndroid Build Coastguard Worker             compositionengine::Output::ColorProfile{defaultColorMode, defaultDataSpace,
3762*38e8c45fSAndroid Build Coastguard Worker                                                     RenderIntent::COLORIMETRIC});
3763*38e8c45fSAndroid Build Coastguard Worker 
3764*38e8c45fSAndroid Build Coastguard Worker     if (const auto& physical = state.physical) {
3765*38e8c45fSAndroid Build Coastguard Worker         const auto& mode = *physical->activeMode;
3766*38e8c45fSAndroid Build Coastguard Worker         mDisplayModeController.setActiveMode(physical->id, mode.getId(), mode.getVsyncRate(),
3767*38e8c45fSAndroid Build Coastguard Worker                                              mode.getPeakFps());
3768*38e8c45fSAndroid Build Coastguard Worker     }
3769*38e8c45fSAndroid Build Coastguard Worker 
3770*38e8c45fSAndroid Build Coastguard Worker     display->setLayerFilter(makeLayerFilterForDisplay(display->getId(), state.layerStack));
3771*38e8c45fSAndroid Build Coastguard Worker     display->setProjection(state.orientation, state.layerStackSpaceRect,
3772*38e8c45fSAndroid Build Coastguard Worker                            state.orientedDisplaySpaceRect);
3773*38e8c45fSAndroid Build Coastguard Worker     display->setDisplayName(state.displayName);
3774*38e8c45fSAndroid Build Coastguard Worker     display->setFlags(state.flags);
3775*38e8c45fSAndroid Build Coastguard Worker 
3776*38e8c45fSAndroid Build Coastguard Worker     return display;
3777*38e8c45fSAndroid Build Coastguard Worker }
3778*38e8c45fSAndroid Build Coastguard Worker 
incRefreshableDisplays()3779*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::incRefreshableDisplays() {
3780*38e8c45fSAndroid Build Coastguard Worker     if (FlagManager::getInstance().no_vsyncs_on_screen_off()) {
3781*38e8c45fSAndroid Build Coastguard Worker         mRefreshableDisplays++;
3782*38e8c45fSAndroid Build Coastguard Worker         if (mRefreshableDisplays == 1) {
3783*38e8c45fSAndroid Build Coastguard Worker             ftl::FakeGuard guard(kMainThreadContext);
3784*38e8c45fSAndroid Build Coastguard Worker             mScheduler->omitVsyncDispatching(false);
3785*38e8c45fSAndroid Build Coastguard Worker         }
3786*38e8c45fSAndroid Build Coastguard Worker     }
3787*38e8c45fSAndroid Build Coastguard Worker }
3788*38e8c45fSAndroid Build Coastguard Worker 
decRefreshableDisplays()3789*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::decRefreshableDisplays() {
3790*38e8c45fSAndroid Build Coastguard Worker     if (FlagManager::getInstance().no_vsyncs_on_screen_off()) {
3791*38e8c45fSAndroid Build Coastguard Worker         mRefreshableDisplays--;
3792*38e8c45fSAndroid Build Coastguard Worker         if (mRefreshableDisplays == 0) {
3793*38e8c45fSAndroid Build Coastguard Worker             ftl::FakeGuard guard(kMainThreadContext);
3794*38e8c45fSAndroid Build Coastguard Worker             mScheduler->omitVsyncDispatching(true);
3795*38e8c45fSAndroid Build Coastguard Worker         }
3796*38e8c45fSAndroid Build Coastguard Worker     }
3797*38e8c45fSAndroid Build Coastguard Worker }
3798*38e8c45fSAndroid Build Coastguard Worker 
processDisplayAdded(const wp<IBinder> & displayToken,const DisplayDeviceState & state)3799*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
3800*38e8c45fSAndroid Build Coastguard Worker                                          const DisplayDeviceState& state) {
3801*38e8c45fSAndroid Build Coastguard Worker     ui::Size resolution(0, 0);
3802*38e8c45fSAndroid Build Coastguard Worker     ui::PixelFormat pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_UNKNOWN);
3803*38e8c45fSAndroid Build Coastguard Worker     if (state.physical) {
3804*38e8c45fSAndroid Build Coastguard Worker         resolution = state.physical->activeMode->getResolution();
3805*38e8c45fSAndroid Build Coastguard Worker         pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888);
3806*38e8c45fSAndroid Build Coastguard Worker     } else if (state.surface != nullptr) {
3807*38e8c45fSAndroid Build Coastguard Worker         int status = state.surface->query(NATIVE_WINDOW_WIDTH, &resolution.width);
3808*38e8c45fSAndroid Build Coastguard Worker         ALOGE_IF(status != NO_ERROR, "Unable to query width (%d)", status);
3809*38e8c45fSAndroid Build Coastguard Worker         status = state.surface->query(NATIVE_WINDOW_HEIGHT, &resolution.height);
3810*38e8c45fSAndroid Build Coastguard Worker         ALOGE_IF(status != NO_ERROR, "Unable to query height (%d)", status);
3811*38e8c45fSAndroid Build Coastguard Worker         int format;
3812*38e8c45fSAndroid Build Coastguard Worker         status = state.surface->query(NATIVE_WINDOW_FORMAT, &format);
3813*38e8c45fSAndroid Build Coastguard Worker         ALOGE_IF(status != NO_ERROR, "Unable to query format (%d)", status);
3814*38e8c45fSAndroid Build Coastguard Worker         pixelFormat = static_cast<ui::PixelFormat>(format);
3815*38e8c45fSAndroid Build Coastguard Worker     } else {
3816*38e8c45fSAndroid Build Coastguard Worker         // Virtual displays without a surface are dormant:
3817*38e8c45fSAndroid Build Coastguard Worker         // they have external state (layer stack, projection,
3818*38e8c45fSAndroid Build Coastguard Worker         // etc.) but no internal state (i.e. a DisplayDevice).
3819*38e8c45fSAndroid Build Coastguard Worker         return;
3820*38e8c45fSAndroid Build Coastguard Worker     }
3821*38e8c45fSAndroid Build Coastguard Worker 
3822*38e8c45fSAndroid Build Coastguard Worker     compositionengine::DisplayCreationArgsBuilder builder;
3823*38e8c45fSAndroid Build Coastguard Worker     if (const auto& physical = state.physical) {
3824*38e8c45fSAndroid Build Coastguard Worker         builder.setId(physical->id);
3825*38e8c45fSAndroid Build Coastguard Worker     } else {
3826*38e8c45fSAndroid Build Coastguard Worker         builder.setId(acquireVirtualDisplay(resolution, pixelFormat, state.uniqueId));
3827*38e8c45fSAndroid Build Coastguard Worker     }
3828*38e8c45fSAndroid Build Coastguard Worker 
3829*38e8c45fSAndroid Build Coastguard Worker     builder.setPixels(resolution);
3830*38e8c45fSAndroid Build Coastguard Worker     builder.setIsSecure(state.isSecure);
3831*38e8c45fSAndroid Build Coastguard Worker     builder.setIsProtected(state.isProtected);
3832*38e8c45fSAndroid Build Coastguard Worker     builder.setHasPictureProcessing(state.hasPictureProcessing);
3833*38e8c45fSAndroid Build Coastguard Worker     builder.setMaxLayerPictureProfiles(state.maxLayerPictureProfiles);
3834*38e8c45fSAndroid Build Coastguard Worker     builder.setPowerAdvisor(mPowerAdvisor.get());
3835*38e8c45fSAndroid Build Coastguard Worker     builder.setName(state.displayName);
3836*38e8c45fSAndroid Build Coastguard Worker     auto compositionDisplay = getCompositionEngine().createDisplay(builder.build());
3837*38e8c45fSAndroid Build Coastguard Worker     compositionDisplay->setLayerCachingEnabled(mLayerCachingEnabled);
3838*38e8c45fSAndroid Build Coastguard Worker 
3839*38e8c45fSAndroid Build Coastguard Worker     sp<compositionengine::DisplaySurface> displaySurface;
3840*38e8c45fSAndroid Build Coastguard Worker     sp<IGraphicBufferProducer> producer;
3841*38e8c45fSAndroid Build Coastguard Worker     sp<IGraphicBufferProducer> bqProducer;
3842*38e8c45fSAndroid Build Coastguard Worker     sp<IGraphicBufferConsumer> bqConsumer;
3843*38e8c45fSAndroid Build Coastguard Worker     getFactory().createBufferQueue(&bqProducer, &bqConsumer, /*consumerIsSurfaceFlinger =*/false);
3844*38e8c45fSAndroid Build Coastguard Worker 
3845*38e8c45fSAndroid Build Coastguard Worker     if (state.isVirtual()) {
3846*38e8c45fSAndroid Build Coastguard Worker         const auto displayId = VirtualDisplayId::tryCast(compositionDisplay->getId());
3847*38e8c45fSAndroid Build Coastguard Worker         LOG_FATAL_IF(!displayId);
3848*38e8c45fSAndroid Build Coastguard Worker         auto surface = sp<VirtualDisplaySurface>::make(getHwComposer(), *displayId, state.surface,
3849*38e8c45fSAndroid Build Coastguard Worker                                                        bqProducer, bqConsumer, state.displayName);
3850*38e8c45fSAndroid Build Coastguard Worker         displaySurface = surface;
3851*38e8c45fSAndroid Build Coastguard Worker         producer = std::move(surface);
3852*38e8c45fSAndroid Build Coastguard Worker     } else {
3853*38e8c45fSAndroid Build Coastguard Worker         ALOGE_IF(state.surface != nullptr,
3854*38e8c45fSAndroid Build Coastguard Worker                  "adding a supported display, but rendering "
3855*38e8c45fSAndroid Build Coastguard Worker                  "surface is provided (%p), ignoring it",
3856*38e8c45fSAndroid Build Coastguard Worker                  state.surface.get());
3857*38e8c45fSAndroid Build Coastguard Worker         const auto displayId = PhysicalDisplayId::tryCast(compositionDisplay->getId());
3858*38e8c45fSAndroid Build Coastguard Worker         LOG_FATAL_IF(!displayId);
3859*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
3860*38e8c45fSAndroid Build Coastguard Worker         const auto frameBufferSurface =
3861*38e8c45fSAndroid Build Coastguard Worker                 sp<FramebufferSurface>::make(getHwComposer(), *displayId, bqProducer, bqConsumer,
3862*38e8c45fSAndroid Build Coastguard Worker                                              state.physical->activeMode->getResolution(),
3863*38e8c45fSAndroid Build Coastguard Worker                                              ui::Size(maxGraphicsWidth, maxGraphicsHeight));
3864*38e8c45fSAndroid Build Coastguard Worker         displaySurface = frameBufferSurface;
3865*38e8c45fSAndroid Build Coastguard Worker         producer = frameBufferSurface->getSurface()->getIGraphicBufferProducer();
3866*38e8c45fSAndroid Build Coastguard Worker #else
3867*38e8c45fSAndroid Build Coastguard Worker         displaySurface =
3868*38e8c45fSAndroid Build Coastguard Worker                 sp<FramebufferSurface>::make(getHwComposer(), *displayId, bqConsumer,
3869*38e8c45fSAndroid Build Coastguard Worker                                              state.physical->activeMode->getResolution(),
3870*38e8c45fSAndroid Build Coastguard Worker                                              ui::Size(maxGraphicsWidth, maxGraphicsHeight));
3871*38e8c45fSAndroid Build Coastguard Worker         producer = bqProducer;
3872*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
3873*38e8c45fSAndroid Build Coastguard Worker     }
3874*38e8c45fSAndroid Build Coastguard Worker 
3875*38e8c45fSAndroid Build Coastguard Worker     LOG_FATAL_IF(!displaySurface);
3876*38e8c45fSAndroid Build Coastguard Worker     auto display = setupNewDisplayDeviceInternal(displayToken, std::move(compositionDisplay), state,
3877*38e8c45fSAndroid Build Coastguard Worker                                                  displaySurface, producer);
3878*38e8c45fSAndroid Build Coastguard Worker 
3879*38e8c45fSAndroid Build Coastguard Worker     if (mScheduler && !display->isVirtual()) {
3880*38e8c45fSAndroid Build Coastguard Worker         // TODO(b/241285876): Annotate `processDisplayAdded` instead.
3881*38e8c45fSAndroid Build Coastguard Worker         ftl::FakeGuard guard(kMainThreadContext);
3882*38e8c45fSAndroid Build Coastguard Worker 
3883*38e8c45fSAndroid Build Coastguard Worker         // For hotplug reconnect, renew the registration since display modes have been reloaded.
3884*38e8c45fSAndroid Build Coastguard Worker         mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector(),
3885*38e8c45fSAndroid Build Coastguard Worker                                     mActiveDisplayId);
3886*38e8c45fSAndroid Build Coastguard Worker     }
3887*38e8c45fSAndroid Build Coastguard Worker 
3888*38e8c45fSAndroid Build Coastguard Worker     if (display->isVirtual()) {
3889*38e8c45fSAndroid Build Coastguard Worker         display->adjustRefreshRate(mScheduler->getPacesetterRefreshRate());
3890*38e8c45fSAndroid Build Coastguard Worker     }
3891*38e8c45fSAndroid Build Coastguard Worker 
3892*38e8c45fSAndroid Build Coastguard Worker     if (display->isRefreshable()) {
3893*38e8c45fSAndroid Build Coastguard Worker         incRefreshableDisplays();
3894*38e8c45fSAndroid Build Coastguard Worker     }
3895*38e8c45fSAndroid Build Coastguard Worker 
3896*38e8c45fSAndroid Build Coastguard Worker     mDisplays.try_emplace(displayToken, std::move(display));
3897*38e8c45fSAndroid Build Coastguard Worker 
3898*38e8c45fSAndroid Build Coastguard Worker     // For an external display, loadDisplayModes already attempted to select the same mode
3899*38e8c45fSAndroid Build Coastguard Worker     // as DM, but SF still needs to be updated to match.
3900*38e8c45fSAndroid Build Coastguard Worker     // TODO (b/318534874): Let DM decide the initial mode.
3901*38e8c45fSAndroid Build Coastguard Worker     if (const auto& physical = state.physical;
3902*38e8c45fSAndroid Build Coastguard Worker         mScheduler && physical && FlagManager::getInstance().connected_display()) {
3903*38e8c45fSAndroid Build Coastguard Worker         const bool isInternalDisplay = mPhysicalDisplays.get(physical->id)
3904*38e8c45fSAndroid Build Coastguard Worker                                                .transform(&PhysicalDisplay::isInternal)
3905*38e8c45fSAndroid Build Coastguard Worker                                                .value_or(false);
3906*38e8c45fSAndroid Build Coastguard Worker 
3907*38e8c45fSAndroid Build Coastguard Worker         if (!isInternalDisplay) {
3908*38e8c45fSAndroid Build Coastguard Worker             auto activeModePtr = physical->activeMode;
3909*38e8c45fSAndroid Build Coastguard Worker             const auto fps = activeModePtr->getPeakFps();
3910*38e8c45fSAndroid Build Coastguard Worker 
3911*38e8c45fSAndroid Build Coastguard Worker             setDesiredMode(
3912*38e8c45fSAndroid Build Coastguard Worker                     {.mode = scheduler::FrameRateMode{fps,
3913*38e8c45fSAndroid Build Coastguard Worker                                                       ftl::as_non_null(std::move(activeModePtr))},
3914*38e8c45fSAndroid Build Coastguard Worker                      .emitEvent = false,
3915*38e8c45fSAndroid Build Coastguard Worker                      .force = true});
3916*38e8c45fSAndroid Build Coastguard Worker         }
3917*38e8c45fSAndroid Build Coastguard Worker     }
3918*38e8c45fSAndroid Build Coastguard Worker }
3919*38e8c45fSAndroid Build Coastguard Worker 
processDisplayRemoved(const wp<IBinder> & displayToken)3920*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
3921*38e8c45fSAndroid Build Coastguard Worker     auto display = getDisplayDeviceLocked(displayToken);
3922*38e8c45fSAndroid Build Coastguard Worker     if (display) {
3923*38e8c45fSAndroid Build Coastguard Worker         display->disconnect();
3924*38e8c45fSAndroid Build Coastguard Worker 
3925*38e8c45fSAndroid Build Coastguard Worker         if (display->isVirtual()) {
3926*38e8c45fSAndroid Build Coastguard Worker             releaseVirtualDisplay(display->getVirtualId());
3927*38e8c45fSAndroid Build Coastguard Worker         } else {
3928*38e8c45fSAndroid Build Coastguard Worker             mScheduler->unregisterDisplay(display->getPhysicalId(), mActiveDisplayId);
3929*38e8c45fSAndroid Build Coastguard Worker         }
3930*38e8c45fSAndroid Build Coastguard Worker 
3931*38e8c45fSAndroid Build Coastguard Worker         if (display->isRefreshable()) {
3932*38e8c45fSAndroid Build Coastguard Worker             decRefreshableDisplays();
3933*38e8c45fSAndroid Build Coastguard Worker         }
3934*38e8c45fSAndroid Build Coastguard Worker     }
3935*38e8c45fSAndroid Build Coastguard Worker 
3936*38e8c45fSAndroid Build Coastguard Worker     mDisplays.erase(displayToken);
3937*38e8c45fSAndroid Build Coastguard Worker 
3938*38e8c45fSAndroid Build Coastguard Worker     if (display && display->isVirtual()) {
3939*38e8c45fSAndroid Build Coastguard Worker         static_cast<void>(mScheduler->schedule([display = std::move(display)] {
3940*38e8c45fSAndroid Build Coastguard Worker             // Destroy the display without holding the mStateLock.
3941*38e8c45fSAndroid Build Coastguard Worker             // This is a temporary solution until we can manage transaction queues without
3942*38e8c45fSAndroid Build Coastguard Worker             // holding the mStateLock.
3943*38e8c45fSAndroid Build Coastguard Worker             // With blast, the IGBP that is passed to the VirtualDisplaySurface is owned by the
3944*38e8c45fSAndroid Build Coastguard Worker             // client. When the IGBP is disconnected, its buffer cache in SF will be cleared
3945*38e8c45fSAndroid Build Coastguard Worker             // via SurfaceComposerClient::doUncacheBufferTransaction. This call from the client
3946*38e8c45fSAndroid Build Coastguard Worker             // ends up running on the main thread causing a deadlock since setTransactionstate
3947*38e8c45fSAndroid Build Coastguard Worker             // will try to acquire the mStateLock. Instead we extend the lifetime of
3948*38e8c45fSAndroid Build Coastguard Worker             // DisplayDevice and destroy it in the main thread without holding the mStateLock.
3949*38e8c45fSAndroid Build Coastguard Worker             // The display will be disconnected and removed from the mDisplays list so it will
3950*38e8c45fSAndroid Build Coastguard Worker             // not be accessible.
3951*38e8c45fSAndroid Build Coastguard Worker         }));
3952*38e8c45fSAndroid Build Coastguard Worker     }
3953*38e8c45fSAndroid Build Coastguard Worker }
3954*38e8c45fSAndroid Build Coastguard Worker 
processDisplayChanged(const wp<IBinder> & displayToken,const DisplayDeviceState & currentState,const DisplayDeviceState & drawingState)3955*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken,
3956*38e8c45fSAndroid Build Coastguard Worker                                            const DisplayDeviceState& currentState,
3957*38e8c45fSAndroid Build Coastguard Worker                                            const DisplayDeviceState& drawingState) {
3958*38e8c45fSAndroid Build Coastguard Worker     const sp<IBinder> currentBinder = IInterface::asBinder(currentState.surface);
3959*38e8c45fSAndroid Build Coastguard Worker     const sp<IBinder> drawingBinder = IInterface::asBinder(drawingState.surface);
3960*38e8c45fSAndroid Build Coastguard Worker 
3961*38e8c45fSAndroid Build Coastguard Worker     // Recreate the DisplayDevice if the surface or sequence ID changed.
3962*38e8c45fSAndroid Build Coastguard Worker     if (currentBinder != drawingBinder || currentState.sequenceId != drawingState.sequenceId) {
3963*38e8c45fSAndroid Build Coastguard Worker         if (const auto display = getDisplayDeviceLocked(displayToken)) {
3964*38e8c45fSAndroid Build Coastguard Worker             display->disconnect();
3965*38e8c45fSAndroid Build Coastguard Worker             if (display->isVirtual()) {
3966*38e8c45fSAndroid Build Coastguard Worker                 releaseVirtualDisplay(display->getVirtualId());
3967*38e8c45fSAndroid Build Coastguard Worker             }
3968*38e8c45fSAndroid Build Coastguard Worker 
3969*38e8c45fSAndroid Build Coastguard Worker             if (display->isRefreshable()) {
3970*38e8c45fSAndroid Build Coastguard Worker                 decRefreshableDisplays();
3971*38e8c45fSAndroid Build Coastguard Worker             }
3972*38e8c45fSAndroid Build Coastguard Worker         }
3973*38e8c45fSAndroid Build Coastguard Worker 
3974*38e8c45fSAndroid Build Coastguard Worker         mDisplays.erase(displayToken);
3975*38e8c45fSAndroid Build Coastguard Worker 
3976*38e8c45fSAndroid Build Coastguard Worker         if (const auto& physical = currentState.physical) {
3977*38e8c45fSAndroid Build Coastguard Worker             getHwComposer().allocatePhysicalDisplay(physical->hwcDisplayId, physical->id,
3978*38e8c45fSAndroid Build Coastguard Worker                                                     /*physicalSize=*/std::nullopt);
3979*38e8c45fSAndroid Build Coastguard Worker         }
3980*38e8c45fSAndroid Build Coastguard Worker 
3981*38e8c45fSAndroid Build Coastguard Worker         processDisplayAdded(displayToken, currentState);
3982*38e8c45fSAndroid Build Coastguard Worker 
3983*38e8c45fSAndroid Build Coastguard Worker         if (currentState.physical) {
3984*38e8c45fSAndroid Build Coastguard Worker             const auto display = getDisplayDeviceLocked(displayToken);
3985*38e8c45fSAndroid Build Coastguard Worker             if (!mSkipPowerOnForQuiescent) {
3986*38e8c45fSAndroid Build Coastguard Worker                 setPowerModeInternal(display, hal::PowerMode::ON);
3987*38e8c45fSAndroid Build Coastguard Worker             }
3988*38e8c45fSAndroid Build Coastguard Worker 
3989*38e8c45fSAndroid Build Coastguard Worker             if (display->getPhysicalId() == mActiveDisplayId) {
3990*38e8c45fSAndroid Build Coastguard Worker                 onActiveDisplayChangedLocked(nullptr, *display);
3991*38e8c45fSAndroid Build Coastguard Worker             }
3992*38e8c45fSAndroid Build Coastguard Worker         }
3993*38e8c45fSAndroid Build Coastguard Worker         return;
3994*38e8c45fSAndroid Build Coastguard Worker     }
3995*38e8c45fSAndroid Build Coastguard Worker 
3996*38e8c45fSAndroid Build Coastguard Worker     if (const auto display = getDisplayDeviceLocked(displayToken)) {
3997*38e8c45fSAndroid Build Coastguard Worker         if (currentState.layerStack != drawingState.layerStack) {
3998*38e8c45fSAndroid Build Coastguard Worker             display->setLayerFilter(
3999*38e8c45fSAndroid Build Coastguard Worker                     makeLayerFilterForDisplay(display->getId(), currentState.layerStack));
4000*38e8c45fSAndroid Build Coastguard Worker         }
4001*38e8c45fSAndroid Build Coastguard Worker         if (currentState.flags != drawingState.flags) {
4002*38e8c45fSAndroid Build Coastguard Worker             display->setFlags(currentState.flags);
4003*38e8c45fSAndroid Build Coastguard Worker         }
4004*38e8c45fSAndroid Build Coastguard Worker         if ((currentState.orientation != drawingState.orientation) ||
4005*38e8c45fSAndroid Build Coastguard Worker             (currentState.layerStackSpaceRect != drawingState.layerStackSpaceRect) ||
4006*38e8c45fSAndroid Build Coastguard Worker             (currentState.orientedDisplaySpaceRect != drawingState.orientedDisplaySpaceRect)) {
4007*38e8c45fSAndroid Build Coastguard Worker             display->setProjection(currentState.orientation, currentState.layerStackSpaceRect,
4008*38e8c45fSAndroid Build Coastguard Worker                                    currentState.orientedDisplaySpaceRect);
4009*38e8c45fSAndroid Build Coastguard Worker             if (display->getId() == mActiveDisplayId) {
4010*38e8c45fSAndroid Build Coastguard Worker                 mActiveDisplayTransformHint = display->getTransformHint();
4011*38e8c45fSAndroid Build Coastguard Worker                 sActiveDisplayRotationFlags =
4012*38e8c45fSAndroid Build Coastguard Worker                         ui::Transform::toRotationFlags(display->getOrientation());
4013*38e8c45fSAndroid Build Coastguard Worker             }
4014*38e8c45fSAndroid Build Coastguard Worker         }
4015*38e8c45fSAndroid Build Coastguard Worker         if (currentState.width != drawingState.width ||
4016*38e8c45fSAndroid Build Coastguard Worker             currentState.height != drawingState.height) {
4017*38e8c45fSAndroid Build Coastguard Worker             display->setDisplaySize(currentState.width, currentState.height);
4018*38e8c45fSAndroid Build Coastguard Worker 
4019*38e8c45fSAndroid Build Coastguard Worker             if (display->getId() == mActiveDisplayId) {
4020*38e8c45fSAndroid Build Coastguard Worker                 onActiveDisplaySizeChanged(*display);
4021*38e8c45fSAndroid Build Coastguard Worker             }
4022*38e8c45fSAndroid Build Coastguard Worker         }
4023*38e8c45fSAndroid Build Coastguard Worker     }
4024*38e8c45fSAndroid Build Coastguard Worker }
4025*38e8c45fSAndroid Build Coastguard Worker 
processDisplayChangesLocked()4026*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::processDisplayChangesLocked() {
4027*38e8c45fSAndroid Build Coastguard Worker     // here we take advantage of Vector's copy-on-write semantics to
4028*38e8c45fSAndroid Build Coastguard Worker     // improve performance by skipping the transaction entirely when
4029*38e8c45fSAndroid Build Coastguard Worker     // know that the lists are identical
4030*38e8c45fSAndroid Build Coastguard Worker     const KeyedVector<wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
4031*38e8c45fSAndroid Build Coastguard Worker     const KeyedVector<wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
4032*38e8c45fSAndroid Build Coastguard Worker     if (!curr.isIdenticalTo(draw)) {
4033*38e8c45fSAndroid Build Coastguard Worker         mVisibleRegionsDirty = true;
4034*38e8c45fSAndroid Build Coastguard Worker         mUpdateInputInfo = true;
4035*38e8c45fSAndroid Build Coastguard Worker 
4036*38e8c45fSAndroid Build Coastguard Worker         // Apply the current color matrix to any added or changed display.
4037*38e8c45fSAndroid Build Coastguard Worker         mCurrentState.colorMatrixChanged = true;
4038*38e8c45fSAndroid Build Coastguard Worker 
4039*38e8c45fSAndroid Build Coastguard Worker         // find the displays that were removed
4040*38e8c45fSAndroid Build Coastguard Worker         // (ie: in drawing state but not in current state)
4041*38e8c45fSAndroid Build Coastguard Worker         // also handle displays that changed
4042*38e8c45fSAndroid Build Coastguard Worker         // (ie: displays that are in both lists)
4043*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < draw.size(); i++) {
4044*38e8c45fSAndroid Build Coastguard Worker             const wp<IBinder>& displayToken = draw.keyAt(i);
4045*38e8c45fSAndroid Build Coastguard Worker             const ssize_t j = curr.indexOfKey(displayToken);
4046*38e8c45fSAndroid Build Coastguard Worker             if (j < 0) {
4047*38e8c45fSAndroid Build Coastguard Worker                 // in drawing state but not in current state
4048*38e8c45fSAndroid Build Coastguard Worker                 processDisplayRemoved(displayToken);
4049*38e8c45fSAndroid Build Coastguard Worker             } else {
4050*38e8c45fSAndroid Build Coastguard Worker                 // this display is in both lists. see if something changed.
4051*38e8c45fSAndroid Build Coastguard Worker                 const DisplayDeviceState& currentState = curr[j];
4052*38e8c45fSAndroid Build Coastguard Worker                 const DisplayDeviceState& drawingState = draw[i];
4053*38e8c45fSAndroid Build Coastguard Worker                 processDisplayChanged(displayToken, currentState, drawingState);
4054*38e8c45fSAndroid Build Coastguard Worker             }
4055*38e8c45fSAndroid Build Coastguard Worker         }
4056*38e8c45fSAndroid Build Coastguard Worker 
4057*38e8c45fSAndroid Build Coastguard Worker         // find displays that were added
4058*38e8c45fSAndroid Build Coastguard Worker         // (ie: in current state but not in drawing state)
4059*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < curr.size(); i++) {
4060*38e8c45fSAndroid Build Coastguard Worker             const wp<IBinder>& displayToken = curr.keyAt(i);
4061*38e8c45fSAndroid Build Coastguard Worker             if (draw.indexOfKey(displayToken) < 0) {
4062*38e8c45fSAndroid Build Coastguard Worker                 processDisplayAdded(displayToken, curr[i]);
4063*38e8c45fSAndroid Build Coastguard Worker             }
4064*38e8c45fSAndroid Build Coastguard Worker         }
4065*38e8c45fSAndroid Build Coastguard Worker     }
4066*38e8c45fSAndroid Build Coastguard Worker 
4067*38e8c45fSAndroid Build Coastguard Worker     mDrawingState.displays = mCurrentState.displays;
4068*38e8c45fSAndroid Build Coastguard Worker }
4069*38e8c45fSAndroid Build Coastguard Worker 
commitTransactionsLocked(uint32_t transactionFlags)4070*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) {
4071*38e8c45fSAndroid Build Coastguard Worker     // Commit display transactions.
4072*38e8c45fSAndroid Build Coastguard Worker     const bool displayTransactionNeeded = transactionFlags & eDisplayTransactionNeeded;
4073*38e8c45fSAndroid Build Coastguard Worker     mFrontEndDisplayInfosChanged = displayTransactionNeeded;
4074*38e8c45fSAndroid Build Coastguard Worker 
4075*38e8c45fSAndroid Build Coastguard Worker     if (mSomeChildrenChanged) {
4076*38e8c45fSAndroid Build Coastguard Worker         mVisibleRegionsDirty = true;
4077*38e8c45fSAndroid Build Coastguard Worker         mSomeChildrenChanged = false;
4078*38e8c45fSAndroid Build Coastguard Worker         mUpdateInputInfo = true;
4079*38e8c45fSAndroid Build Coastguard Worker     }
4080*38e8c45fSAndroid Build Coastguard Worker 
4081*38e8c45fSAndroid Build Coastguard Worker     if (mLayersAdded) {
4082*38e8c45fSAndroid Build Coastguard Worker         mLayersAdded = false;
4083*38e8c45fSAndroid Build Coastguard Worker         // Layers have been added.
4084*38e8c45fSAndroid Build Coastguard Worker         mVisibleRegionsDirty = true;
4085*38e8c45fSAndroid Build Coastguard Worker         mUpdateInputInfo = true;
4086*38e8c45fSAndroid Build Coastguard Worker     }
4087*38e8c45fSAndroid Build Coastguard Worker 
4088*38e8c45fSAndroid Build Coastguard Worker     // some layers might have been removed, so
4089*38e8c45fSAndroid Build Coastguard Worker     // we need to update the regions they're exposing.
4090*38e8c45fSAndroid Build Coastguard Worker     if (mLayersRemoved) {
4091*38e8c45fSAndroid Build Coastguard Worker         mLayersRemoved = false;
4092*38e8c45fSAndroid Build Coastguard Worker         mVisibleRegionsDirty = true;
4093*38e8c45fSAndroid Build Coastguard Worker         mUpdateInputInfo = true;
4094*38e8c45fSAndroid Build Coastguard Worker     }
4095*38e8c45fSAndroid Build Coastguard Worker 
4096*38e8c45fSAndroid Build Coastguard Worker     if (transactionFlags & eInputInfoUpdateNeeded) {
4097*38e8c45fSAndroid Build Coastguard Worker         mUpdateInputInfo = true;
4098*38e8c45fSAndroid Build Coastguard Worker     }
4099*38e8c45fSAndroid Build Coastguard Worker 
4100*38e8c45fSAndroid Build Coastguard Worker     doCommitTransactions();
4101*38e8c45fSAndroid Build Coastguard Worker }
4102*38e8c45fSAndroid Build Coastguard Worker 
updateInputFlinger(VsyncId vsyncId,TimePoint frameTime)4103*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId, TimePoint frameTime) {
4104*38e8c45fSAndroid Build Coastguard Worker     if (!mInputFlinger || (!mUpdateInputInfo && mInputWindowCommands.empty())) {
4105*38e8c45fSAndroid Build Coastguard Worker         return;
4106*38e8c45fSAndroid Build Coastguard Worker     }
4107*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
4108*38e8c45fSAndroid Build Coastguard Worker 
4109*38e8c45fSAndroid Build Coastguard Worker     std::vector<WindowInfo> windowInfos;
4110*38e8c45fSAndroid Build Coastguard Worker     std::vector<DisplayInfo> displayInfos;
4111*38e8c45fSAndroid Build Coastguard Worker     bool updateWindowInfo = false;
4112*38e8c45fSAndroid Build Coastguard Worker     if (mUpdateInputInfo) {
4113*38e8c45fSAndroid Build Coastguard Worker         mUpdateInputInfo = false;
4114*38e8c45fSAndroid Build Coastguard Worker         updateWindowInfo = true;
4115*38e8c45fSAndroid Build Coastguard Worker         buildWindowInfos(windowInfos, displayInfos);
4116*38e8c45fSAndroid Build Coastguard Worker     }
4117*38e8c45fSAndroid Build Coastguard Worker 
4118*38e8c45fSAndroid Build Coastguard Worker     std::unordered_set<int32_t> visibleWindowIds;
4119*38e8c45fSAndroid Build Coastguard Worker     for (WindowInfo& windowInfo : windowInfos) {
4120*38e8c45fSAndroid Build Coastguard Worker         if (!windowInfo.inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
4121*38e8c45fSAndroid Build Coastguard Worker             visibleWindowIds.insert(windowInfo.id);
4122*38e8c45fSAndroid Build Coastguard Worker         }
4123*38e8c45fSAndroid Build Coastguard Worker     }
4124*38e8c45fSAndroid Build Coastguard Worker     bool visibleWindowsChanged = false;
4125*38e8c45fSAndroid Build Coastguard Worker     if (visibleWindowIds != mVisibleWindowIds) {
4126*38e8c45fSAndroid Build Coastguard Worker         visibleWindowsChanged = true;
4127*38e8c45fSAndroid Build Coastguard Worker         mVisibleWindowIds = std::move(visibleWindowIds);
4128*38e8c45fSAndroid Build Coastguard Worker     }
4129*38e8c45fSAndroid Build Coastguard Worker 
4130*38e8c45fSAndroid Build Coastguard Worker     BackgroundExecutor::getInstance().sendCallbacks({[updateWindowInfo,
4131*38e8c45fSAndroid Build Coastguard Worker                                                       windowInfos = std::move(windowInfos),
4132*38e8c45fSAndroid Build Coastguard Worker                                                       displayInfos = std::move(displayInfos),
4133*38e8c45fSAndroid Build Coastguard Worker                                                       inputWindowCommands =
4134*38e8c45fSAndroid Build Coastguard Worker                                                               std::move(mInputWindowCommands),
4135*38e8c45fSAndroid Build Coastguard Worker                                                       inputFlinger = mInputFlinger, this,
4136*38e8c45fSAndroid Build Coastguard Worker                                                       visibleWindowsChanged, vsyncId,
4137*38e8c45fSAndroid Build Coastguard Worker                                                       frameTime]() mutable {
4138*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_NAME("BackgroundExecutor::updateInputFlinger");
4139*38e8c45fSAndroid Build Coastguard Worker         if (updateWindowInfo) {
4140*38e8c45fSAndroid Build Coastguard Worker             mWindowInfosListenerInvoker
4141*38e8c45fSAndroid Build Coastguard Worker                     ->windowInfosChanged(gui::WindowInfosUpdate{std::move(windowInfos),
4142*38e8c45fSAndroid Build Coastguard Worker                                                                 std::move(displayInfos),
4143*38e8c45fSAndroid Build Coastguard Worker                                                                 ftl::to_underlying(vsyncId),
4144*38e8c45fSAndroid Build Coastguard Worker                                                                 frameTime.ns()},
4145*38e8c45fSAndroid Build Coastguard Worker                                          std::move(
4146*38e8c45fSAndroid Build Coastguard Worker                                                  inputWindowCommands.windowInfosReportedListeners),
4147*38e8c45fSAndroid Build Coastguard Worker                                          /* forceImmediateCall= */ visibleWindowsChanged ||
4148*38e8c45fSAndroid Build Coastguard Worker                                                  !inputWindowCommands.focusRequests.empty());
4149*38e8c45fSAndroid Build Coastguard Worker         } else {
4150*38e8c45fSAndroid Build Coastguard Worker             // If there are listeners but no changes to input windows, call the listeners
4151*38e8c45fSAndroid Build Coastguard Worker             // immediately.
4152*38e8c45fSAndroid Build Coastguard Worker             for (const auto& listener : inputWindowCommands.windowInfosReportedListeners) {
4153*38e8c45fSAndroid Build Coastguard Worker                 if (IInterface::asBinder(listener)->isBinderAlive()) {
4154*38e8c45fSAndroid Build Coastguard Worker                     listener->onWindowInfosReported();
4155*38e8c45fSAndroid Build Coastguard Worker                 }
4156*38e8c45fSAndroid Build Coastguard Worker             }
4157*38e8c45fSAndroid Build Coastguard Worker         }
4158*38e8c45fSAndroid Build Coastguard Worker         for (const auto& focusRequest : inputWindowCommands.focusRequests) {
4159*38e8c45fSAndroid Build Coastguard Worker             inputFlinger->setFocusedWindow(focusRequest);
4160*38e8c45fSAndroid Build Coastguard Worker         }
4161*38e8c45fSAndroid Build Coastguard Worker     }});
4162*38e8c45fSAndroid Build Coastguard Worker 
4163*38e8c45fSAndroid Build Coastguard Worker     mInputWindowCommands.clear();
4164*38e8c45fSAndroid Build Coastguard Worker }
4165*38e8c45fSAndroid Build Coastguard Worker 
persistDisplayBrightness(bool needsComposite)4166*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::persistDisplayBrightness(bool needsComposite) {
4167*38e8c45fSAndroid Build Coastguard Worker     const bool supportsDisplayBrightnessCommand = getHwComposer().getComposer()->isSupported(
4168*38e8c45fSAndroid Build Coastguard Worker             Hwc2::Composer::OptionalFeature::DisplayBrightnessCommand);
4169*38e8c45fSAndroid Build Coastguard Worker     if (!supportsDisplayBrightnessCommand) {
4170*38e8c45fSAndroid Build Coastguard Worker         return;
4171*38e8c45fSAndroid Build Coastguard Worker     }
4172*38e8c45fSAndroid Build Coastguard Worker 
4173*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
4174*38e8c45fSAndroid Build Coastguard Worker         if (const auto brightness = display->getStagedBrightness(); brightness) {
4175*38e8c45fSAndroid Build Coastguard Worker             if (!needsComposite) {
4176*38e8c45fSAndroid Build Coastguard Worker                 const status_t error =
4177*38e8c45fSAndroid Build Coastguard Worker                         getHwComposer()
4178*38e8c45fSAndroid Build Coastguard Worker                                 .setDisplayBrightness(display->getPhysicalId(), *brightness,
4179*38e8c45fSAndroid Build Coastguard Worker                                                       display->getCompositionDisplay()
4180*38e8c45fSAndroid Build Coastguard Worker                                                               ->getState()
4181*38e8c45fSAndroid Build Coastguard Worker                                                               .displayBrightnessNits,
4182*38e8c45fSAndroid Build Coastguard Worker                                                       Hwc2::Composer::DisplayBrightnessOptions{
4183*38e8c45fSAndroid Build Coastguard Worker                                                               .applyImmediately = true})
4184*38e8c45fSAndroid Build Coastguard Worker                                 .get();
4185*38e8c45fSAndroid Build Coastguard Worker 
4186*38e8c45fSAndroid Build Coastguard Worker                 ALOGE_IF(error != NO_ERROR,
4187*38e8c45fSAndroid Build Coastguard Worker                          "Error setting display brightness for display %s: %d (%s)",
4188*38e8c45fSAndroid Build Coastguard Worker                          to_string(display->getId()).c_str(), error, strerror(error));
4189*38e8c45fSAndroid Build Coastguard Worker             }
4190*38e8c45fSAndroid Build Coastguard Worker             display->persistBrightness(needsComposite);
4191*38e8c45fSAndroid Build Coastguard Worker         }
4192*38e8c45fSAndroid Build Coastguard Worker     }
4193*38e8c45fSAndroid Build Coastguard Worker }
4194*38e8c45fSAndroid Build Coastguard Worker 
buildWindowInfos(std::vector<WindowInfo> & outWindowInfos,std::vector<DisplayInfo> & outDisplayInfos)4195*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::buildWindowInfos(std::vector<WindowInfo>& outWindowInfos,
4196*38e8c45fSAndroid Build Coastguard Worker                                       std::vector<DisplayInfo>& outDisplayInfos) {
4197*38e8c45fSAndroid Build Coastguard Worker     static size_t sNumWindowInfos = 0;
4198*38e8c45fSAndroid Build Coastguard Worker     outWindowInfos.reserve(sNumWindowInfos);
4199*38e8c45fSAndroid Build Coastguard Worker     sNumWindowInfos = 0;
4200*38e8c45fSAndroid Build Coastguard Worker 
4201*38e8c45fSAndroid Build Coastguard Worker     mLayerSnapshotBuilder.forEachInputSnapshot(
4202*38e8c45fSAndroid Build Coastguard Worker             [&outWindowInfos](const frontend::LayerSnapshot& snapshot) {
4203*38e8c45fSAndroid Build Coastguard Worker                 outWindowInfos.push_back(snapshot.inputInfo);
4204*38e8c45fSAndroid Build Coastguard Worker             });
4205*38e8c45fSAndroid Build Coastguard Worker 
4206*38e8c45fSAndroid Build Coastguard Worker     sNumWindowInfos = outWindowInfos.size();
4207*38e8c45fSAndroid Build Coastguard Worker 
4208*38e8c45fSAndroid Build Coastguard Worker     outDisplayInfos.reserve(mFrontEndDisplayInfos.size());
4209*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [_, info] : mFrontEndDisplayInfos) {
4210*38e8c45fSAndroid Build Coastguard Worker         outDisplayInfos.push_back(info.info);
4211*38e8c45fSAndroid Build Coastguard Worker     }
4212*38e8c45fSAndroid Build Coastguard Worker }
4213*38e8c45fSAndroid Build Coastguard Worker 
updateCursorAsync()4214*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::updateCursorAsync() {
4215*38e8c45fSAndroid Build Coastguard Worker     compositionengine::CompositionRefreshArgs refreshArgs;
4216*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
4217*38e8c45fSAndroid Build Coastguard Worker         if (HalDisplayId::tryCast(display->getId())) {
4218*38e8c45fSAndroid Build Coastguard Worker             refreshArgs.outputs.push_back(display->getCompositionDisplay());
4219*38e8c45fSAndroid Build Coastguard Worker         }
4220*38e8c45fSAndroid Build Coastguard Worker     }
4221*38e8c45fSAndroid Build Coastguard Worker 
4222*38e8c45fSAndroid Build Coastguard Worker     constexpr bool kCursorOnly = true;
4223*38e8c45fSAndroid Build Coastguard Worker     const auto layers = moveSnapshotsToCompositionArgs(refreshArgs, kCursorOnly);
4224*38e8c45fSAndroid Build Coastguard Worker     mCompositionEngine->updateCursorAsync(refreshArgs);
4225*38e8c45fSAndroid Build Coastguard Worker     moveSnapshotsFromCompositionArgs(refreshArgs, layers);
4226*38e8c45fSAndroid Build Coastguard Worker }
4227*38e8c45fSAndroid Build Coastguard Worker 
requestHardwareVsync(PhysicalDisplayId displayId,bool enable)4228*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::requestHardwareVsync(PhysicalDisplayId displayId, bool enable) {
4229*38e8c45fSAndroid Build Coastguard Worker     getHwComposer().setVsyncEnabled(displayId, enable ? hal::Vsync::ENABLE : hal::Vsync::DISABLE);
4230*38e8c45fSAndroid Build Coastguard Worker }
4231*38e8c45fSAndroid Build Coastguard Worker 
requestDisplayModes(std::vector<display::DisplayModeRequest> modeRequests)4232*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest> modeRequests) {
4233*38e8c45fSAndroid Build Coastguard Worker     if (mBootStage != BootStage::FINISHED) {
4234*38e8c45fSAndroid Build Coastguard Worker         ALOGV("Currently in the boot stage, skipping display mode changes");
4235*38e8c45fSAndroid Build Coastguard Worker         return;
4236*38e8c45fSAndroid Build Coastguard Worker     }
4237*38e8c45fSAndroid Build Coastguard Worker 
4238*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
4239*38e8c45fSAndroid Build Coastguard Worker 
4240*38e8c45fSAndroid Build Coastguard Worker     // If this is called from the main thread mStateLock must be locked before
4241*38e8c45fSAndroid Build Coastguard Worker     // Currently the only way to call this function from the main thread is from
4242*38e8c45fSAndroid Build Coastguard Worker     // Scheduler::chooseRefreshRateForContent
4243*38e8c45fSAndroid Build Coastguard Worker 
4244*38e8c45fSAndroid Build Coastguard Worker     ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId);
4245*38e8c45fSAndroid Build Coastguard Worker 
4246*38e8c45fSAndroid Build Coastguard Worker     for (auto& request : modeRequests) {
4247*38e8c45fSAndroid Build Coastguard Worker         const auto& modePtr = request.mode.modePtr;
4248*38e8c45fSAndroid Build Coastguard Worker 
4249*38e8c45fSAndroid Build Coastguard Worker         const auto displayId = modePtr->getPhysicalDisplayId();
4250*38e8c45fSAndroid Build Coastguard Worker         const auto display = getDisplayDeviceLocked(displayId);
4251*38e8c45fSAndroid Build Coastguard Worker 
4252*38e8c45fSAndroid Build Coastguard Worker         if (!display) continue;
4253*38e8c45fSAndroid Build Coastguard Worker 
4254*38e8c45fSAndroid Build Coastguard Worker         if (display->refreshRateSelector().isModeAllowed(request.mode)) {
4255*38e8c45fSAndroid Build Coastguard Worker             setDesiredMode(std::move(request));
4256*38e8c45fSAndroid Build Coastguard Worker         } else {
4257*38e8c45fSAndroid Build Coastguard Worker             ALOGV("%s: Mode %d is disallowed for display %s", __func__,
4258*38e8c45fSAndroid Build Coastguard Worker                   ftl::to_underlying(modePtr->getId()), to_string(displayId).c_str());
4259*38e8c45fSAndroid Build Coastguard Worker         }
4260*38e8c45fSAndroid Build Coastguard Worker     }
4261*38e8c45fSAndroid Build Coastguard Worker }
4262*38e8c45fSAndroid Build Coastguard Worker 
notifyCpuLoadUp()4263*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::notifyCpuLoadUp() {
4264*38e8c45fSAndroid Build Coastguard Worker     mPowerAdvisor->notifyCpuLoadUp();
4265*38e8c45fSAndroid Build Coastguard Worker }
4266*38e8c45fSAndroid Build Coastguard Worker 
onChoreographerAttached()4267*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onChoreographerAttached() {
4268*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
4269*38e8c45fSAndroid Build Coastguard Worker     mUpdateAttachedChoreographer = true;
4270*38e8c45fSAndroid Build Coastguard Worker     scheduleCommit(FrameHint::kNone);
4271*38e8c45fSAndroid Build Coastguard Worker }
4272*38e8c45fSAndroid Build Coastguard Worker 
onExpectedPresentTimePosted(TimePoint expectedPresentTime,ftl::NonNull<DisplayModePtr> modePtr,Fps renderRate)4273*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onExpectedPresentTimePosted(TimePoint expectedPresentTime,
4274*38e8c45fSAndroid Build Coastguard Worker                                                  ftl::NonNull<DisplayModePtr> modePtr,
4275*38e8c45fSAndroid Build Coastguard Worker                                                  Fps renderRate) {
4276*38e8c45fSAndroid Build Coastguard Worker     const auto vsyncPeriod = modePtr->getVsyncRate().getPeriod();
4277*38e8c45fSAndroid Build Coastguard Worker     const auto timeoutOpt = [&]() -> std::optional<Period> {
4278*38e8c45fSAndroid Build Coastguard Worker         const auto vrrConfig = modePtr->getVrrConfig();
4279*38e8c45fSAndroid Build Coastguard Worker         if (!vrrConfig) return std::nullopt;
4280*38e8c45fSAndroid Build Coastguard Worker 
4281*38e8c45fSAndroid Build Coastguard Worker         const auto notifyExpectedPresentConfig =
4282*38e8c45fSAndroid Build Coastguard Worker                 modePtr->getVrrConfig()->notifyExpectedPresentConfig;
4283*38e8c45fSAndroid Build Coastguard Worker         if (!notifyExpectedPresentConfig) return std::nullopt;
4284*38e8c45fSAndroid Build Coastguard Worker         return Period::fromNs(notifyExpectedPresentConfig->timeoutNs);
4285*38e8c45fSAndroid Build Coastguard Worker     }();
4286*38e8c45fSAndroid Build Coastguard Worker 
4287*38e8c45fSAndroid Build Coastguard Worker     notifyExpectedPresentIfRequired(modePtr->getPhysicalDisplayId(), vsyncPeriod,
4288*38e8c45fSAndroid Build Coastguard Worker                                     expectedPresentTime, renderRate, timeoutOpt);
4289*38e8c45fSAndroid Build Coastguard Worker }
4290*38e8c45fSAndroid Build Coastguard Worker 
notifyExpectedPresentIfRequired(PhysicalDisplayId displayId,Period vsyncPeriod,TimePoint expectedPresentTime,Fps frameInterval,std::optional<Period> timeoutOpt)4291*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::notifyExpectedPresentIfRequired(PhysicalDisplayId displayId,
4292*38e8c45fSAndroid Build Coastguard Worker                                                      Period vsyncPeriod,
4293*38e8c45fSAndroid Build Coastguard Worker                                                      TimePoint expectedPresentTime,
4294*38e8c45fSAndroid Build Coastguard Worker                                                      Fps frameInterval,
4295*38e8c45fSAndroid Build Coastguard Worker                                                      std::optional<Period> timeoutOpt) {
4296*38e8c45fSAndroid Build Coastguard Worker     auto& data = mNotifyExpectedPresentMap[displayId];
4297*38e8c45fSAndroid Build Coastguard Worker     const auto lastExpectedPresentTimestamp = data.lastExpectedPresentTimestamp;
4298*38e8c45fSAndroid Build Coastguard Worker     const auto lastFrameInterval = data.lastFrameInterval;
4299*38e8c45fSAndroid Build Coastguard Worker     data.lastFrameInterval = frameInterval;
4300*38e8c45fSAndroid Build Coastguard Worker     data.lastExpectedPresentTimestamp = expectedPresentTime;
4301*38e8c45fSAndroid Build Coastguard Worker     const auto threshold = Duration::fromNs(vsyncPeriod.ns() / 2);
4302*38e8c45fSAndroid Build Coastguard Worker 
4303*38e8c45fSAndroid Build Coastguard Worker     const constexpr nsecs_t kOneSecondNs =
4304*38e8c45fSAndroid Build Coastguard Worker             std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
4305*38e8c45fSAndroid Build Coastguard Worker     const auto timeout =
4306*38e8c45fSAndroid Build Coastguard Worker             Period::fromNs(timeoutOpt && timeoutOpt->ns() > 0 ? timeoutOpt->ns() : kOneSecondNs);
4307*38e8c45fSAndroid Build Coastguard Worker     const bool frameIntervalIsOnCadence =
4308*38e8c45fSAndroid Build Coastguard Worker             isFrameIntervalOnCadence(expectedPresentTime, lastExpectedPresentTimestamp,
4309*38e8c45fSAndroid Build Coastguard Worker                                      lastFrameInterval, timeout, threshold);
4310*38e8c45fSAndroid Build Coastguard Worker 
4311*38e8c45fSAndroid Build Coastguard Worker     const bool expectedPresentWithinTimeout =
4312*38e8c45fSAndroid Build Coastguard Worker             isExpectedPresentWithinTimeout(expectedPresentTime, lastExpectedPresentTimestamp,
4313*38e8c45fSAndroid Build Coastguard Worker                                            timeoutOpt, threshold);
4314*38e8c45fSAndroid Build Coastguard Worker     if (expectedPresentWithinTimeout && frameIntervalIsOnCadence) {
4315*38e8c45fSAndroid Build Coastguard Worker         return;
4316*38e8c45fSAndroid Build Coastguard Worker     }
4317*38e8c45fSAndroid Build Coastguard Worker 
4318*38e8c45fSAndroid Build Coastguard Worker     auto hintStatus = data.hintStatus.load();
4319*38e8c45fSAndroid Build Coastguard Worker     if (!expectedPresentWithinTimeout) {
4320*38e8c45fSAndroid Build Coastguard Worker         if ((hintStatus != NotifyExpectedPresentHintStatus::Sent &&
4321*38e8c45fSAndroid Build Coastguard Worker              hintStatus != NotifyExpectedPresentHintStatus::ScheduleOnTx) ||
4322*38e8c45fSAndroid Build Coastguard Worker             (timeoutOpt && timeoutOpt->ns() == 0)) {
4323*38e8c45fSAndroid Build Coastguard Worker             // Send the hint immediately if timeout, as the hint gets
4324*38e8c45fSAndroid Build Coastguard Worker             // delayed otherwise, as the frame is scheduled close
4325*38e8c45fSAndroid Build Coastguard Worker             // to the actual present.
4326*38e8c45fSAndroid Build Coastguard Worker             if (data.hintStatus
4327*38e8c45fSAndroid Build Coastguard Worker                         .compare_exchange_strong(hintStatus,
4328*38e8c45fSAndroid Build Coastguard Worker                                                  NotifyExpectedPresentHintStatus::ScheduleOnTx)) {
4329*38e8c45fSAndroid Build Coastguard Worker                 scheduleNotifyExpectedPresentHint(displayId);
4330*38e8c45fSAndroid Build Coastguard Worker                 return;
4331*38e8c45fSAndroid Build Coastguard Worker             }
4332*38e8c45fSAndroid Build Coastguard Worker         }
4333*38e8c45fSAndroid Build Coastguard Worker     }
4334*38e8c45fSAndroid Build Coastguard Worker 
4335*38e8c45fSAndroid Build Coastguard Worker     if (hintStatus == NotifyExpectedPresentHintStatus::Sent &&
4336*38e8c45fSAndroid Build Coastguard Worker         data.hintStatus.compare_exchange_strong(hintStatus,
4337*38e8c45fSAndroid Build Coastguard Worker                                                 NotifyExpectedPresentHintStatus::ScheduleOnTx)) {
4338*38e8c45fSAndroid Build Coastguard Worker         return;
4339*38e8c45fSAndroid Build Coastguard Worker     }
4340*38e8c45fSAndroid Build Coastguard Worker     if (hintStatus != NotifyExpectedPresentHintStatus::Start) {
4341*38e8c45fSAndroid Build Coastguard Worker         return;
4342*38e8c45fSAndroid Build Coastguard Worker     }
4343*38e8c45fSAndroid Build Coastguard Worker     data.hintStatus.store(NotifyExpectedPresentHintStatus::ScheduleOnPresent);
4344*38e8c45fSAndroid Build Coastguard Worker     mScheduler->scheduleFrame();
4345*38e8c45fSAndroid Build Coastguard Worker }
4346*38e8c45fSAndroid Build Coastguard Worker 
scheduleNotifyExpectedPresentHint(PhysicalDisplayId displayId,VsyncId vsyncId)4347*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::scheduleNotifyExpectedPresentHint(PhysicalDisplayId displayId,
4348*38e8c45fSAndroid Build Coastguard Worker                                                        VsyncId vsyncId) {
4349*38e8c45fSAndroid Build Coastguard Worker     auto itr = mNotifyExpectedPresentMap.find(displayId);
4350*38e8c45fSAndroid Build Coastguard Worker     if (itr == mNotifyExpectedPresentMap.end()) {
4351*38e8c45fSAndroid Build Coastguard Worker         return;
4352*38e8c45fSAndroid Build Coastguard Worker     }
4353*38e8c45fSAndroid Build Coastguard Worker 
4354*38e8c45fSAndroid Build Coastguard Worker     const char* const whence = __func__;
4355*38e8c45fSAndroid Build Coastguard Worker     const auto sendHint = [=, this]() {
4356*38e8c45fSAndroid Build Coastguard Worker         auto& data = mNotifyExpectedPresentMap.at(displayId);
4357*38e8c45fSAndroid Build Coastguard Worker         TimePoint expectedPresentTime = data.lastExpectedPresentTimestamp;
4358*38e8c45fSAndroid Build Coastguard Worker         if (ftl::to_underlying(vsyncId) != FrameTimelineInfo::INVALID_VSYNC_ID) {
4359*38e8c45fSAndroid Build Coastguard Worker             const auto predictionOpt = mFrameTimeline->getTokenManager()->getPredictionsForToken(
4360*38e8c45fSAndroid Build Coastguard Worker                     ftl::to_underlying(vsyncId));
4361*38e8c45fSAndroid Build Coastguard Worker             const auto expectedPresentTimeOnPredictor = TimePoint::fromNs(
4362*38e8c45fSAndroid Build Coastguard Worker                     predictionOpt ? predictionOpt->presentTime : expectedPresentTime.ns());
4363*38e8c45fSAndroid Build Coastguard Worker             const auto scheduledFrameResultOpt = mScheduler->getScheduledFrameResult();
4364*38e8c45fSAndroid Build Coastguard Worker             const auto expectedPresentTimeOnScheduler = scheduledFrameResultOpt.has_value()
4365*38e8c45fSAndroid Build Coastguard Worker                     ? scheduledFrameResultOpt->vsyncTime
4366*38e8c45fSAndroid Build Coastguard Worker                     : TimePoint::fromNs(0);
4367*38e8c45fSAndroid Build Coastguard Worker             expectedPresentTime =
4368*38e8c45fSAndroid Build Coastguard Worker                     std::max(expectedPresentTimeOnPredictor, expectedPresentTimeOnScheduler);
4369*38e8c45fSAndroid Build Coastguard Worker         }
4370*38e8c45fSAndroid Build Coastguard Worker 
4371*38e8c45fSAndroid Build Coastguard Worker         if (expectedPresentTime < TimePoint::now()) {
4372*38e8c45fSAndroid Build Coastguard Worker             expectedPresentTime =
4373*38e8c45fSAndroid Build Coastguard Worker                     mScheduler->getVsyncSchedule()->vsyncDeadlineAfter(TimePoint::now());
4374*38e8c45fSAndroid Build Coastguard Worker             if (mScheduler->vsyncModulator().getVsyncConfig().sfWorkDuration >
4375*38e8c45fSAndroid Build Coastguard Worker                 mScheduler->getVsyncSchedule(displayId)->period()) {
4376*38e8c45fSAndroid Build Coastguard Worker                 expectedPresentTime += mScheduler->getVsyncSchedule(displayId)->period();
4377*38e8c45fSAndroid Build Coastguard Worker             }
4378*38e8c45fSAndroid Build Coastguard Worker         }
4379*38e8c45fSAndroid Build Coastguard Worker         const auto status = getHwComposer().notifyExpectedPresent(displayId, expectedPresentTime,
4380*38e8c45fSAndroid Build Coastguard Worker                                                                   data.lastFrameInterval);
4381*38e8c45fSAndroid Build Coastguard Worker         if (status != NO_ERROR) {
4382*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s failed to notifyExpectedPresentHint for display %" PRId64, whence,
4383*38e8c45fSAndroid Build Coastguard Worker                   displayId.value);
4384*38e8c45fSAndroid Build Coastguard Worker         }
4385*38e8c45fSAndroid Build Coastguard Worker     };
4386*38e8c45fSAndroid Build Coastguard Worker 
4387*38e8c45fSAndroid Build Coastguard Worker     if (itr->second.hintStatus == NotifyExpectedPresentHintStatus::ScheduleOnTx) {
4388*38e8c45fSAndroid Build Coastguard Worker         return static_cast<void>(mScheduler->schedule([=,
4389*38e8c45fSAndroid Build Coastguard Worker                                                        this]() FTL_FAKE_GUARD(kMainThreadContext) {
4390*38e8c45fSAndroid Build Coastguard Worker             auto& data = mNotifyExpectedPresentMap.at(displayId);
4391*38e8c45fSAndroid Build Coastguard Worker             auto scheduleHintOnTx = NotifyExpectedPresentHintStatus::ScheduleOnTx;
4392*38e8c45fSAndroid Build Coastguard Worker             if (data.hintStatus.compare_exchange_strong(scheduleHintOnTx,
4393*38e8c45fSAndroid Build Coastguard Worker                                                         NotifyExpectedPresentHintStatus::Sent)) {
4394*38e8c45fSAndroid Build Coastguard Worker                 sendHint();
4395*38e8c45fSAndroid Build Coastguard Worker                 constexpr bool kAllowToEnable = true;
4396*38e8c45fSAndroid Build Coastguard Worker                 mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable);
4397*38e8c45fSAndroid Build Coastguard Worker             }
4398*38e8c45fSAndroid Build Coastguard Worker         }));
4399*38e8c45fSAndroid Build Coastguard Worker     }
4400*38e8c45fSAndroid Build Coastguard Worker     auto scheduleHintOnPresent = NotifyExpectedPresentHintStatus::ScheduleOnPresent;
4401*38e8c45fSAndroid Build Coastguard Worker     if (itr->second.hintStatus.compare_exchange_strong(scheduleHintOnPresent,
4402*38e8c45fSAndroid Build Coastguard Worker                                                        NotifyExpectedPresentHintStatus::Sent)) {
4403*38e8c45fSAndroid Build Coastguard Worker         sendHint();
4404*38e8c45fSAndroid Build Coastguard Worker     }
4405*38e8c45fSAndroid Build Coastguard Worker }
4406*38e8c45fSAndroid Build Coastguard Worker 
sendNotifyExpectedPresentHint(PhysicalDisplayId displayId)4407*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::sendNotifyExpectedPresentHint(PhysicalDisplayId displayId) {
4408*38e8c45fSAndroid Build Coastguard Worker     if (auto itr = mNotifyExpectedPresentMap.find(displayId);
4409*38e8c45fSAndroid Build Coastguard Worker         itr == mNotifyExpectedPresentMap.end() ||
4410*38e8c45fSAndroid Build Coastguard Worker         itr->second.hintStatus != NotifyExpectedPresentHintStatus::ScheduleOnPresent) {
4411*38e8c45fSAndroid Build Coastguard Worker         return;
4412*38e8c45fSAndroid Build Coastguard Worker     }
4413*38e8c45fSAndroid Build Coastguard Worker     scheduleNotifyExpectedPresentHint(displayId);
4414*38e8c45fSAndroid Build Coastguard Worker }
4415*38e8c45fSAndroid Build Coastguard Worker 
onCommitNotComposited()4416*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onCommitNotComposited() {
4417*38e8c45fSAndroid Build Coastguard Worker     if (FlagManager::getInstance().commit_not_composited()) {
4418*38e8c45fSAndroid Build Coastguard Worker         mFrameTimeline->onCommitNotComposited();
4419*38e8c45fSAndroid Build Coastguard Worker     }
4420*38e8c45fSAndroid Build Coastguard Worker }
4421*38e8c45fSAndroid Build Coastguard Worker 
initScheduler(const sp<const DisplayDevice> & display)4422*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {
4423*38e8c45fSAndroid Build Coastguard Worker     using namespace scheduler;
4424*38e8c45fSAndroid Build Coastguard Worker 
4425*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(mScheduler);
4426*38e8c45fSAndroid Build Coastguard Worker 
4427*38e8c45fSAndroid Build Coastguard Worker     const auto activeMode = display->refreshRateSelector().getActiveMode();
4428*38e8c45fSAndroid Build Coastguard Worker     const Fps activeRefreshRate = activeMode.fps;
4429*38e8c45fSAndroid Build Coastguard Worker 
4430*38e8c45fSAndroid Build Coastguard Worker     FeatureFlags features;
4431*38e8c45fSAndroid Build Coastguard Worker 
4432*38e8c45fSAndroid Build Coastguard Worker     const auto defaultContentDetectionValue =
4433*38e8c45fSAndroid Build Coastguard Worker             FlagManager::getInstance().enable_fro_dependent_features() &&
4434*38e8c45fSAndroid Build Coastguard Worker             sysprop::enable_frame_rate_override(true);
4435*38e8c45fSAndroid Build Coastguard Worker     if (sysprop::use_content_detection_for_refresh_rate(defaultContentDetectionValue)) {
4436*38e8c45fSAndroid Build Coastguard Worker         features |= Feature::kContentDetection;
4437*38e8c45fSAndroid Build Coastguard Worker         if (FlagManager::getInstance().enable_small_area_detection()) {
4438*38e8c45fSAndroid Build Coastguard Worker             features |= Feature::kSmallDirtyContentDetection;
4439*38e8c45fSAndroid Build Coastguard Worker         }
4440*38e8c45fSAndroid Build Coastguard Worker     }
4441*38e8c45fSAndroid Build Coastguard Worker     if (base::GetBoolProperty("debug.sf.show_predicted_vsync"s, false)) {
4442*38e8c45fSAndroid Build Coastguard Worker         features |= Feature::kTracePredictedVsync;
4443*38e8c45fSAndroid Build Coastguard Worker     }
4444*38e8c45fSAndroid Build Coastguard Worker     if (!base::GetBoolProperty("debug.sf.vsync_reactor_ignore_present_fences"s, false) &&
4445*38e8c45fSAndroid Build Coastguard Worker         mHasReliablePresentFences) {
4446*38e8c45fSAndroid Build Coastguard Worker         features |= Feature::kPresentFences;
4447*38e8c45fSAndroid Build Coastguard Worker     }
4448*38e8c45fSAndroid Build Coastguard Worker     if (display->refreshRateSelector().kernelIdleTimerController()) {
4449*38e8c45fSAndroid Build Coastguard Worker         features |= Feature::kKernelIdleTimer;
4450*38e8c45fSAndroid Build Coastguard Worker     }
4451*38e8c45fSAndroid Build Coastguard Worker     if (mBackpressureGpuComposition) {
4452*38e8c45fSAndroid Build Coastguard Worker         features |= Feature::kBackpressureGpuComposition;
4453*38e8c45fSAndroid Build Coastguard Worker     }
4454*38e8c45fSAndroid Build Coastguard Worker     if (getHwComposer().getComposer()->isSupported(
4455*38e8c45fSAndroid Build Coastguard Worker                 Hwc2::Composer::OptionalFeature::ExpectedPresentTime)) {
4456*38e8c45fSAndroid Build Coastguard Worker         features |= Feature::kExpectedPresentTime;
4457*38e8c45fSAndroid Build Coastguard Worker     }
4458*38e8c45fSAndroid Build Coastguard Worker 
4459*38e8c45fSAndroid Build Coastguard Worker     mScheduler = std::make_unique<Scheduler>(static_cast<ICompositor&>(*this),
4460*38e8c45fSAndroid Build Coastguard Worker                                              static_cast<ISchedulerCallback&>(*this), features,
4461*38e8c45fSAndroid Build Coastguard Worker                                              getFactory(), activeRefreshRate, *mTimeStats);
4462*38e8c45fSAndroid Build Coastguard Worker 
4463*38e8c45fSAndroid Build Coastguard Worker     // The pacesetter must be registered before EventThread creation below.
4464*38e8c45fSAndroid Build Coastguard Worker     mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector(),
4465*38e8c45fSAndroid Build Coastguard Worker                                 mActiveDisplayId);
4466*38e8c45fSAndroid Build Coastguard Worker     if (FlagManager::getInstance().vrr_config()) {
4467*38e8c45fSAndroid Build Coastguard Worker         mScheduler->setRenderRate(display->getPhysicalId(), activeMode.fps,
4468*38e8c45fSAndroid Build Coastguard Worker                                   /*applyImmediately*/ true);
4469*38e8c45fSAndroid Build Coastguard Worker     }
4470*38e8c45fSAndroid Build Coastguard Worker 
4471*38e8c45fSAndroid Build Coastguard Worker     const auto configs = mScheduler->getVsyncConfiguration().getCurrentConfigs();
4472*38e8c45fSAndroid Build Coastguard Worker 
4473*38e8c45fSAndroid Build Coastguard Worker     mScheduler->createEventThread(scheduler::Cycle::Render, mFrameTimeline->getTokenManager(),
4474*38e8c45fSAndroid Build Coastguard Worker                                   /* workDuration */ configs.late.appWorkDuration,
4475*38e8c45fSAndroid Build Coastguard Worker                                   /* readyDuration */ configs.late.sfWorkDuration);
4476*38e8c45fSAndroid Build Coastguard Worker     mScheduler->createEventThread(scheduler::Cycle::LastComposite,
4477*38e8c45fSAndroid Build Coastguard Worker                                   mFrameTimeline->getTokenManager(),
4478*38e8c45fSAndroid Build Coastguard Worker                                   /* workDuration */ activeRefreshRate.getPeriod(),
4479*38e8c45fSAndroid Build Coastguard Worker                                   /* readyDuration */ configs.late.sfWorkDuration);
4480*38e8c45fSAndroid Build Coastguard Worker 
4481*38e8c45fSAndroid Build Coastguard Worker     // Dispatch after EventThread creation, since registerDisplay above skipped dispatch.
4482*38e8c45fSAndroid Build Coastguard Worker     mScheduler->dispatchHotplug(display->getPhysicalId(), scheduler::Scheduler::Hotplug::Connected);
4483*38e8c45fSAndroid Build Coastguard Worker 
4484*38e8c45fSAndroid Build Coastguard Worker     mScheduler->initVsync(*mFrameTimeline->getTokenManager(), configs.late.sfWorkDuration);
4485*38e8c45fSAndroid Build Coastguard Worker 
4486*38e8c45fSAndroid Build Coastguard Worker     mRegionSamplingThread =
4487*38e8c45fSAndroid Build Coastguard Worker             sp<RegionSamplingThread>::make(*this,
4488*38e8c45fSAndroid Build Coastguard Worker                                            RegionSamplingThread::EnvironmentTimingTunables());
4489*38e8c45fSAndroid Build Coastguard Worker     mFpsReporter = sp<FpsReporter>::make(*mFrameTimeline);
4490*38e8c45fSAndroid Build Coastguard Worker 
4491*38e8c45fSAndroid Build Coastguard Worker     // Timer callbacks may fire, so do this last.
4492*38e8c45fSAndroid Build Coastguard Worker     mScheduler->startTimers();
4493*38e8c45fSAndroid Build Coastguard Worker }
4494*38e8c45fSAndroid Build Coastguard Worker 
doCommitTransactions()4495*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::doCommitTransactions() {
4496*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
4497*38e8c45fSAndroid Build Coastguard Worker     mDrawingState = mCurrentState;
4498*38e8c45fSAndroid Build Coastguard Worker     mCurrentState.colorMatrixChanged = false;
4499*38e8c45fSAndroid Build Coastguard Worker }
4500*38e8c45fSAndroid Build Coastguard Worker 
invalidateLayerStack(const ui::LayerFilter & layerFilter,const Region & dirty)4501*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::invalidateLayerStack(const ui::LayerFilter& layerFilter, const Region& dirty) {
4502*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [token, displayDevice] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
4503*38e8c45fSAndroid Build Coastguard Worker         auto display = displayDevice->getCompositionDisplay();
4504*38e8c45fSAndroid Build Coastguard Worker         if (display->includesLayer(layerFilter)) {
4505*38e8c45fSAndroid Build Coastguard Worker             display->editState().dirtyRegion.orSelf(dirty);
4506*38e8c45fSAndroid Build Coastguard Worker         }
4507*38e8c45fSAndroid Build Coastguard Worker     }
4508*38e8c45fSAndroid Build Coastguard Worker }
4509*38e8c45fSAndroid Build Coastguard Worker 
addClientLayer(LayerCreationArgs & args,const sp<IBinder> & handle,const sp<Layer> & layer,const wp<Layer> & parent,uint32_t * outTransformHint)4510*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::addClientLayer(LayerCreationArgs& args, const sp<IBinder>& handle,
4511*38e8c45fSAndroid Build Coastguard Worker                                         const sp<Layer>& layer, const wp<Layer>& parent,
4512*38e8c45fSAndroid Build Coastguard Worker                                         uint32_t* outTransformHint) {
4513*38e8c45fSAndroid Build Coastguard Worker     if (mNumLayers >= MAX_LAYERS) {
4514*38e8c45fSAndroid Build Coastguard Worker         static std::atomic<nsecs_t> lasttime{0};
4515*38e8c45fSAndroid Build Coastguard Worker         nsecs_t now = systemTime();
4516*38e8c45fSAndroid Build Coastguard Worker         if (lasttime != 0 && ns2s(now - lasttime.load()) < 10) {
4517*38e8c45fSAndroid Build Coastguard Worker             ALOGE("AddClientLayer already dumped 10s before");
4518*38e8c45fSAndroid Build Coastguard Worker             return NO_MEMORY;
4519*38e8c45fSAndroid Build Coastguard Worker         } else {
4520*38e8c45fSAndroid Build Coastguard Worker             lasttime = now;
4521*38e8c45fSAndroid Build Coastguard Worker         }
4522*38e8c45fSAndroid Build Coastguard Worker 
4523*38e8c45fSAndroid Build Coastguard Worker         ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(),
4524*38e8c45fSAndroid Build Coastguard Worker               MAX_LAYERS);
4525*38e8c45fSAndroid Build Coastguard Worker         static_cast<void>(mScheduler->schedule([&]() FTL_FAKE_GUARD(kMainThreadContext) {
4526*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Dumping on-screen layers.");
4527*38e8c45fSAndroid Build Coastguard Worker             mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getHierarchy());
4528*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Dumping off-screen layers.");
4529*38e8c45fSAndroid Build Coastguard Worker             mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getOffscreenHierarchy());
4530*38e8c45fSAndroid Build Coastguard Worker         }));
4531*38e8c45fSAndroid Build Coastguard Worker         return NO_MEMORY;
4532*38e8c45fSAndroid Build Coastguard Worker     }
4533*38e8c45fSAndroid Build Coastguard Worker 
4534*38e8c45fSAndroid Build Coastguard Worker     if (outTransformHint) {
4535*38e8c45fSAndroid Build Coastguard Worker         *outTransformHint = mActiveDisplayTransformHint;
4536*38e8c45fSAndroid Build Coastguard Worker     }
4537*38e8c45fSAndroid Build Coastguard Worker     args.parentId = LayerHandle::getLayerId(args.parentHandle.promote());
4538*38e8c45fSAndroid Build Coastguard Worker     args.layerIdToMirror = LayerHandle::getLayerId(args.mirrorLayerHandle.promote());
4539*38e8c45fSAndroid Build Coastguard Worker     {
4540*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
4541*38e8c45fSAndroid Build Coastguard Worker         mCreatedLayers.emplace_back(layer);
4542*38e8c45fSAndroid Build Coastguard Worker         mNewLayers.emplace_back(std::make_unique<frontend::RequestedLayerState>(args));
4543*38e8c45fSAndroid Build Coastguard Worker         args.mirrorLayerHandle.clear();
4544*38e8c45fSAndroid Build Coastguard Worker         args.parentHandle.clear();
4545*38e8c45fSAndroid Build Coastguard Worker         mNewLayerArgs.emplace_back(std::move(args));
4546*38e8c45fSAndroid Build Coastguard Worker     }
4547*38e8c45fSAndroid Build Coastguard Worker 
4548*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eTransactionNeeded);
4549*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
4550*38e8c45fSAndroid Build Coastguard Worker }
4551*38e8c45fSAndroid Build Coastguard Worker 
getTransactionFlags() const4552*38e8c45fSAndroid Build Coastguard Worker uint32_t SurfaceFlinger::getTransactionFlags() const {
4553*38e8c45fSAndroid Build Coastguard Worker     return mTransactionFlags;
4554*38e8c45fSAndroid Build Coastguard Worker }
4555*38e8c45fSAndroid Build Coastguard Worker 
clearTransactionFlags(uint32_t mask)4556*38e8c45fSAndroid Build Coastguard Worker uint32_t SurfaceFlinger::clearTransactionFlags(uint32_t mask) {
4557*38e8c45fSAndroid Build Coastguard Worker     uint32_t transactionFlags = mTransactionFlags.fetch_and(~mask);
4558*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_INT("mTransactionFlags", transactionFlags);
4559*38e8c45fSAndroid Build Coastguard Worker     return transactionFlags & mask;
4560*38e8c45fSAndroid Build Coastguard Worker }
4561*38e8c45fSAndroid Build Coastguard Worker 
setTransactionFlags(uint32_t mask,TransactionSchedule schedule,const sp<IBinder> & applyToken,FrameHint frameHint)4562*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule schedule,
4563*38e8c45fSAndroid Build Coastguard Worker                                          const sp<IBinder>& applyToken, FrameHint frameHint) {
4564*38e8c45fSAndroid Build Coastguard Worker     mScheduler->modulateVsync({}, &VsyncModulator::setTransactionSchedule, schedule, applyToken);
4565*38e8c45fSAndroid Build Coastguard Worker     uint32_t transactionFlags = mTransactionFlags.fetch_or(mask);
4566*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_INT("mTransactionFlags", transactionFlags);
4567*38e8c45fSAndroid Build Coastguard Worker 
4568*38e8c45fSAndroid Build Coastguard Worker     if (const bool scheduled = transactionFlags & mask; !scheduled) {
4569*38e8c45fSAndroid Build Coastguard Worker         mScheduler->resync();
4570*38e8c45fSAndroid Build Coastguard Worker         scheduleCommit(frameHint);
4571*38e8c45fSAndroid Build Coastguard Worker     } else if (frameHint == FrameHint::kActive) {
4572*38e8c45fSAndroid Build Coastguard Worker         // Even if the next frame is already scheduled, we should reset the idle timer
4573*38e8c45fSAndroid Build Coastguard Worker         // as a new activity just happened.
4574*38e8c45fSAndroid Build Coastguard Worker         mScheduler->resetIdleTimer();
4575*38e8c45fSAndroid Build Coastguard Worker     }
4576*38e8c45fSAndroid Build Coastguard Worker }
4577*38e8c45fSAndroid Build Coastguard Worker 
transactionReadyTimelineCheck(const TransactionHandler::TransactionFlushState & flushState)4578*38e8c45fSAndroid Build Coastguard Worker TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyTimelineCheck(
4579*38e8c45fSAndroid Build Coastguard Worker         const TransactionHandler::TransactionFlushState& flushState) {
4580*38e8c45fSAndroid Build Coastguard Worker     const auto& transaction = *flushState.transaction;
4581*38e8c45fSAndroid Build Coastguard Worker 
4582*38e8c45fSAndroid Build Coastguard Worker     const TimePoint desiredPresentTime = TimePoint::fromNs(transaction.desiredPresentTime);
4583*38e8c45fSAndroid Build Coastguard Worker     const TimePoint expectedPresentTime = mScheduler->expectedPresentTimeForPacesetter();
4584*38e8c45fSAndroid Build Coastguard Worker 
4585*38e8c45fSAndroid Build Coastguard Worker     using TransactionReadiness = TransactionHandler::TransactionReadiness;
4586*38e8c45fSAndroid Build Coastguard Worker 
4587*38e8c45fSAndroid Build Coastguard Worker     // Do not present if the desiredPresentTime has not passed unless it is more than
4588*38e8c45fSAndroid Build Coastguard Worker     // one second in the future. We ignore timestamps more than 1 second in the future
4589*38e8c45fSAndroid Build Coastguard Worker     // for stability reasons.
4590*38e8c45fSAndroid Build Coastguard Worker     if (!transaction.isAutoTimestamp && desiredPresentTime >= expectedPresentTime &&
4591*38e8c45fSAndroid Build Coastguard Worker         desiredPresentTime < expectedPresentTime + 1s) {
4592*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_FORMAT("not current desiredPresentTime: %" PRId64 " expectedPresentTime: %" PRId64,
4593*38e8c45fSAndroid Build Coastguard Worker                        desiredPresentTime, expectedPresentTime);
4594*38e8c45fSAndroid Build Coastguard Worker         return TransactionReadiness::NotReady;
4595*38e8c45fSAndroid Build Coastguard Worker     }
4596*38e8c45fSAndroid Build Coastguard Worker 
4597*38e8c45fSAndroid Build Coastguard Worker     const auto vsyncId = VsyncId{transaction.frameTimelineInfo.vsyncId};
4598*38e8c45fSAndroid Build Coastguard Worker 
4599*38e8c45fSAndroid Build Coastguard Worker     // Transactions with VsyncId are already throttled by the vsyncId (i.e. Choreographer issued
4600*38e8c45fSAndroid Build Coastguard Worker     // the vsyncId according to the frame rate override cadence) so we shouldn't throttle again
4601*38e8c45fSAndroid Build Coastguard Worker     // when applying the transaction. Otherwise we might throttle older transactions
4602*38e8c45fSAndroid Build Coastguard Worker     // incorrectly as the frame rate of SF changed before it drained the older transactions.
4603*38e8c45fSAndroid Build Coastguard Worker     if (ftl::to_underlying(vsyncId) == FrameTimelineInfo::INVALID_VSYNC_ID &&
4604*38e8c45fSAndroid Build Coastguard Worker         !mScheduler->isVsyncValid(expectedPresentTime, transaction.originUid)) {
4605*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_FORMAT("!isVsyncValid expectedPresentTime: %" PRId64 " uid: %d",
4606*38e8c45fSAndroid Build Coastguard Worker                        expectedPresentTime, transaction.originUid);
4607*38e8c45fSAndroid Build Coastguard Worker         return TransactionReadiness::NotReady;
4608*38e8c45fSAndroid Build Coastguard Worker     }
4609*38e8c45fSAndroid Build Coastguard Worker 
4610*38e8c45fSAndroid Build Coastguard Worker     // If the client didn't specify desiredPresentTime, use the vsyncId to determine the
4611*38e8c45fSAndroid Build Coastguard Worker     // expected present time of this transaction.
4612*38e8c45fSAndroid Build Coastguard Worker     if (transaction.isAutoTimestamp && frameIsEarly(expectedPresentTime, vsyncId)) {
4613*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_FORMAT("frameIsEarly vsyncId: %" PRId64 " expectedPresentTime: %" PRId64,
4614*38e8c45fSAndroid Build Coastguard Worker                        transaction.frameTimelineInfo.vsyncId, expectedPresentTime);
4615*38e8c45fSAndroid Build Coastguard Worker         return TransactionReadiness::NotReady;
4616*38e8c45fSAndroid Build Coastguard Worker     }
4617*38e8c45fSAndroid Build Coastguard Worker 
4618*38e8c45fSAndroid Build Coastguard Worker     return TransactionReadiness::Ready;
4619*38e8c45fSAndroid Build Coastguard Worker }
4620*38e8c45fSAndroid Build Coastguard Worker 
transactionReadyBufferCheck(const TransactionHandler::TransactionFlushState & flushState)4621*38e8c45fSAndroid Build Coastguard Worker TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferCheck(
4622*38e8c45fSAndroid Build Coastguard Worker         const TransactionHandler::TransactionFlushState& flushState) {
4623*38e8c45fSAndroid Build Coastguard Worker     using TransactionReadiness = TransactionHandler::TransactionReadiness;
4624*38e8c45fSAndroid Build Coastguard Worker     auto ready = TransactionReadiness::Ready;
4625*38e8c45fSAndroid Build Coastguard Worker     flushState.transaction->traverseStatesWithBuffersWhileTrue(
4626*38e8c45fSAndroid Build Coastguard Worker             [&](const ResolvedComposerState& resolvedState) FTL_FAKE_GUARD(
4627*38e8c45fSAndroid Build Coastguard Worker                     kMainThreadContext) -> bool {
4628*38e8c45fSAndroid Build Coastguard Worker                 const frontend::RequestedLayerState* layer =
4629*38e8c45fSAndroid Build Coastguard Worker                         mLayerLifecycleManager.getLayerFromId(resolvedState.layerId);
4630*38e8c45fSAndroid Build Coastguard Worker                 const auto& transaction = *flushState.transaction;
4631*38e8c45fSAndroid Build Coastguard Worker                 const auto& s = resolvedState.state;
4632*38e8c45fSAndroid Build Coastguard Worker                 // check for barrier frames
4633*38e8c45fSAndroid Build Coastguard Worker                 if (s.bufferData->hasBarrier) {
4634*38e8c45fSAndroid Build Coastguard Worker                     // The current producerId is already a newer producer than the buffer that has a
4635*38e8c45fSAndroid Build Coastguard Worker                     // barrier. This means the incoming buffer is older and we can release it here.
4636*38e8c45fSAndroid Build Coastguard Worker                     // We don't wait on the barrier since we know that's stale information.
4637*38e8c45fSAndroid Build Coastguard Worker                     if (layer->barrierProducerId > s.bufferData->producerId) {
4638*38e8c45fSAndroid Build Coastguard Worker                         if (s.bufferData->releaseBufferListener) {
4639*38e8c45fSAndroid Build Coastguard Worker                             uint32_t currentMaxAcquiredBufferCount =
4640*38e8c45fSAndroid Build Coastguard Worker                                     getMaxAcquiredBufferCountForCurrentRefreshRate(
4641*38e8c45fSAndroid Build Coastguard Worker                                             layer->ownerUid.val());
4642*38e8c45fSAndroid Build Coastguard Worker                             SFTRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64,
4643*38e8c45fSAndroid Build Coastguard Worker                                                    layer->name.c_str(), s.bufferData->frameNumber);
4644*38e8c45fSAndroid Build Coastguard Worker                             s.bufferData->releaseBufferListener
4645*38e8c45fSAndroid Build Coastguard Worker                                     ->onReleaseBuffer({resolvedState.externalTexture->getBuffer()
4646*38e8c45fSAndroid Build Coastguard Worker                                                                ->getId(),
4647*38e8c45fSAndroid Build Coastguard Worker                                                        s.bufferData->frameNumber},
4648*38e8c45fSAndroid Build Coastguard Worker                                                       s.bufferData->acquireFence
4649*38e8c45fSAndroid Build Coastguard Worker                                                               ? s.bufferData->acquireFence
4650*38e8c45fSAndroid Build Coastguard Worker                                                               : Fence::NO_FENCE,
4651*38e8c45fSAndroid Build Coastguard Worker                                                       currentMaxAcquiredBufferCount);
4652*38e8c45fSAndroid Build Coastguard Worker                         }
4653*38e8c45fSAndroid Build Coastguard Worker 
4654*38e8c45fSAndroid Build Coastguard Worker                         // Delete the entire state at this point and not just release the buffer
4655*38e8c45fSAndroid Build Coastguard Worker                         // because everything associated with the Layer in this Transaction is now
4656*38e8c45fSAndroid Build Coastguard Worker                         // out of date.
4657*38e8c45fSAndroid Build Coastguard Worker                         SFTRACE_FORMAT("DeleteStaleBuffer %s barrierProducerId:%d > %d",
4658*38e8c45fSAndroid Build Coastguard Worker                                        layer->name.c_str(), layer->barrierProducerId,
4659*38e8c45fSAndroid Build Coastguard Worker                                        s.bufferData->producerId);
4660*38e8c45fSAndroid Build Coastguard Worker                         return TraverseBuffersReturnValues::DELETE_AND_CONTINUE_TRAVERSAL;
4661*38e8c45fSAndroid Build Coastguard Worker                     }
4662*38e8c45fSAndroid Build Coastguard Worker 
4663*38e8c45fSAndroid Build Coastguard Worker                     if (layer->barrierFrameNumber < s.bufferData->barrierFrameNumber) {
4664*38e8c45fSAndroid Build Coastguard Worker                         const bool willApplyBarrierFrame =
4665*38e8c45fSAndroid Build Coastguard Worker                                 flushState.bufferLayersReadyToPresent.contains(s.surface.get()) &&
4666*38e8c45fSAndroid Build Coastguard Worker                                 ((flushState.bufferLayersReadyToPresent.get(s.surface.get()) >=
4667*38e8c45fSAndroid Build Coastguard Worker                                   s.bufferData->barrierFrameNumber));
4668*38e8c45fSAndroid Build Coastguard Worker                         if (!willApplyBarrierFrame) {
4669*38e8c45fSAndroid Build Coastguard Worker                             SFTRACE_FORMAT("NotReadyBarrier %s barrierFrameNumber:%" PRId64
4670*38e8c45fSAndroid Build Coastguard Worker                                            " > %" PRId64,
4671*38e8c45fSAndroid Build Coastguard Worker                                            layer->name.c_str(), layer->barrierFrameNumber,
4672*38e8c45fSAndroid Build Coastguard Worker                                            s.bufferData->barrierFrameNumber);
4673*38e8c45fSAndroid Build Coastguard Worker                             ready = TransactionReadiness::NotReadyBarrier;
4674*38e8c45fSAndroid Build Coastguard Worker                             return TraverseBuffersReturnValues::STOP_TRAVERSAL;
4675*38e8c45fSAndroid Build Coastguard Worker                         }
4676*38e8c45fSAndroid Build Coastguard Worker                     }
4677*38e8c45fSAndroid Build Coastguard Worker                 }
4678*38e8c45fSAndroid Build Coastguard Worker 
4679*38e8c45fSAndroid Build Coastguard Worker                 // If backpressure is enabled and we already have a buffer to commit, keep
4680*38e8c45fSAndroid Build Coastguard Worker                 // the transaction in the queue.
4681*38e8c45fSAndroid Build Coastguard Worker                 const bool hasPendingBuffer =
4682*38e8c45fSAndroid Build Coastguard Worker                         flushState.bufferLayersReadyToPresent.contains(s.surface.get());
4683*38e8c45fSAndroid Build Coastguard Worker                 if (layer->backpressureEnabled() && hasPendingBuffer &&
4684*38e8c45fSAndroid Build Coastguard Worker                     transaction.isAutoTimestamp) {
4685*38e8c45fSAndroid Build Coastguard Worker                     SFTRACE_FORMAT("hasPendingBuffer %s", layer->name.c_str());
4686*38e8c45fSAndroid Build Coastguard Worker                     ready = TransactionReadiness::NotReady;
4687*38e8c45fSAndroid Build Coastguard Worker                     return TraverseBuffersReturnValues::STOP_TRAVERSAL;
4688*38e8c45fSAndroid Build Coastguard Worker                 }
4689*38e8c45fSAndroid Build Coastguard Worker 
4690*38e8c45fSAndroid Build Coastguard Worker                 const bool acquireFenceAvailable = s.bufferData &&
4691*38e8c45fSAndroid Build Coastguard Worker                         s.bufferData->flags.test(BufferData::BufferDataChange::fenceChanged) &&
4692*38e8c45fSAndroid Build Coastguard Worker                         s.bufferData->acquireFence;
4693*38e8c45fSAndroid Build Coastguard Worker                 const bool fenceSignaled = !acquireFenceAvailable ||
4694*38e8c45fSAndroid Build Coastguard Worker                         s.bufferData->acquireFence->getStatus() != Fence::Status::Unsignaled;
4695*38e8c45fSAndroid Build Coastguard Worker                 if (!fenceSignaled) {
4696*38e8c45fSAndroid Build Coastguard Worker                     // check fence status
4697*38e8c45fSAndroid Build Coastguard Worker                     const bool allowLatchUnsignaled =
4698*38e8c45fSAndroid Build Coastguard Worker                             shouldLatchUnsignaled(s, transaction.states.size(),
4699*38e8c45fSAndroid Build Coastguard Worker                                                   flushState.firstTransaction) &&
4700*38e8c45fSAndroid Build Coastguard Worker                             layer->isSimpleBufferUpdate(s);
4701*38e8c45fSAndroid Build Coastguard Worker                     if (allowLatchUnsignaled) {
4702*38e8c45fSAndroid Build Coastguard Worker                         SFTRACE_FORMAT("fence unsignaled try allowLatchUnsignaled %s",
4703*38e8c45fSAndroid Build Coastguard Worker                                        layer->name.c_str());
4704*38e8c45fSAndroid Build Coastguard Worker                         ready = TransactionReadiness::NotReadyUnsignaled;
4705*38e8c45fSAndroid Build Coastguard Worker                     } else {
4706*38e8c45fSAndroid Build Coastguard Worker                         ready = TransactionReadiness::NotReady;
4707*38e8c45fSAndroid Build Coastguard Worker                         auto& listener = s.bufferData->releaseBufferListener;
4708*38e8c45fSAndroid Build Coastguard Worker                         if (listener &&
4709*38e8c45fSAndroid Build Coastguard Worker                             (flushState.queueProcessTime - transaction.postTime) >
4710*38e8c45fSAndroid Build Coastguard Worker                                     std::chrono::nanoseconds(4s).count()) {
4711*38e8c45fSAndroid Build Coastguard Worker                             mTransactionHandler
4712*38e8c45fSAndroid Build Coastguard Worker                                     .onTransactionQueueStalled(transaction.id,
4713*38e8c45fSAndroid Build Coastguard Worker                                                                {.pid = layer->ownerPid.val(),
4714*38e8c45fSAndroid Build Coastguard Worker                                                                 .layerId = layer->id,
4715*38e8c45fSAndroid Build Coastguard Worker                                                                 .layerName = layer->name,
4716*38e8c45fSAndroid Build Coastguard Worker                                                                 .bufferId = s.bufferData->getId(),
4717*38e8c45fSAndroid Build Coastguard Worker                                                                 .frameNumber =
4718*38e8c45fSAndroid Build Coastguard Worker                                                                         s.bufferData->frameNumber});
4719*38e8c45fSAndroid Build Coastguard Worker                         }
4720*38e8c45fSAndroid Build Coastguard Worker                         SFTRACE_FORMAT("fence unsignaled %s", layer->name.c_str());
4721*38e8c45fSAndroid Build Coastguard Worker                         return TraverseBuffersReturnValues::STOP_TRAVERSAL;
4722*38e8c45fSAndroid Build Coastguard Worker                     }
4723*38e8c45fSAndroid Build Coastguard Worker                 }
4724*38e8c45fSAndroid Build Coastguard Worker                 return TraverseBuffersReturnValues::CONTINUE_TRAVERSAL;
4725*38e8c45fSAndroid Build Coastguard Worker             });
4726*38e8c45fSAndroid Build Coastguard Worker     return ready;
4727*38e8c45fSAndroid Build Coastguard Worker }
4728*38e8c45fSAndroid Build Coastguard Worker 
addTransactionReadyFilters()4729*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::addTransactionReadyFilters() {
4730*38e8c45fSAndroid Build Coastguard Worker     mTransactionHandler.addTransactionReadyFilter(
4731*38e8c45fSAndroid Build Coastguard Worker             std::bind(&SurfaceFlinger::transactionReadyTimelineCheck, this, std::placeholders::_1));
4732*38e8c45fSAndroid Build Coastguard Worker     mTransactionHandler.addTransactionReadyFilter(
4733*38e8c45fSAndroid Build Coastguard Worker             std::bind(&SurfaceFlinger::transactionReadyBufferCheck, this, std::placeholders::_1));
4734*38e8c45fSAndroid Build Coastguard Worker }
4735*38e8c45fSAndroid Build Coastguard Worker 
4736*38e8c45fSAndroid Build Coastguard Worker // For tests only
flushTransactionQueues()4737*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::flushTransactionQueues() {
4738*38e8c45fSAndroid Build Coastguard Worker     mTransactionHandler.collectTransactions();
4739*38e8c45fSAndroid Build Coastguard Worker     std::vector<TransactionState> transactions = mTransactionHandler.flushTransactions();
4740*38e8c45fSAndroid Build Coastguard Worker     return applyTransactions(transactions);
4741*38e8c45fSAndroid Build Coastguard Worker }
4742*38e8c45fSAndroid Build Coastguard Worker 
applyTransactions(std::vector<TransactionState> & transactions)4743*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::applyTransactions(std::vector<TransactionState>& transactions) {
4744*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
4745*38e8c45fSAndroid Build Coastguard Worker     return applyTransactionsLocked(transactions);
4746*38e8c45fSAndroid Build Coastguard Worker }
4747*38e8c45fSAndroid Build Coastguard Worker 
applyTransactionsLocked(std::vector<TransactionState> & transactions)4748*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::applyTransactionsLocked(std::vector<TransactionState>& transactions) {
4749*38e8c45fSAndroid Build Coastguard Worker     bool needsTraversal = false;
4750*38e8c45fSAndroid Build Coastguard Worker     // Now apply all transactions.
4751*38e8c45fSAndroid Build Coastguard Worker     for (auto& transaction : transactions) {
4752*38e8c45fSAndroid Build Coastguard Worker         needsTraversal |=
4753*38e8c45fSAndroid Build Coastguard Worker                 applyTransactionState(transaction.frameTimelineInfo, transaction.states,
4754*38e8c45fSAndroid Build Coastguard Worker                                       transaction.displays, transaction.flags,
4755*38e8c45fSAndroid Build Coastguard Worker                                       transaction.inputWindowCommands,
4756*38e8c45fSAndroid Build Coastguard Worker                                       transaction.desiredPresentTime, transaction.isAutoTimestamp,
4757*38e8c45fSAndroid Build Coastguard Worker                                       std::move(transaction.uncacheBufferIds), transaction.postTime,
4758*38e8c45fSAndroid Build Coastguard Worker                                       transaction.hasListenerCallbacks,
4759*38e8c45fSAndroid Build Coastguard Worker                                       transaction.listenerCallbacks, transaction.originPid,
4760*38e8c45fSAndroid Build Coastguard Worker                                       transaction.originUid, transaction.id);
4761*38e8c45fSAndroid Build Coastguard Worker     }
4762*38e8c45fSAndroid Build Coastguard Worker     return needsTraversal;
4763*38e8c45fSAndroid Build Coastguard Worker }
4764*38e8c45fSAndroid Build Coastguard Worker 
transactionFlushNeeded()4765*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::transactionFlushNeeded() {
4766*38e8c45fSAndroid Build Coastguard Worker     return mTransactionHandler.hasPendingTransactions();
4767*38e8c45fSAndroid Build Coastguard Worker }
4768*38e8c45fSAndroid Build Coastguard Worker 
frameIsEarly(TimePoint expectedPresentTime,VsyncId vsyncId) const4769*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::frameIsEarly(TimePoint expectedPresentTime, VsyncId vsyncId) const {
4770*38e8c45fSAndroid Build Coastguard Worker     const auto prediction =
4771*38e8c45fSAndroid Build Coastguard Worker             mFrameTimeline->getTokenManager()->getPredictionsForToken(ftl::to_underlying(vsyncId));
4772*38e8c45fSAndroid Build Coastguard Worker     if (!prediction) {
4773*38e8c45fSAndroid Build Coastguard Worker         return false;
4774*38e8c45fSAndroid Build Coastguard Worker     }
4775*38e8c45fSAndroid Build Coastguard Worker 
4776*38e8c45fSAndroid Build Coastguard Worker     const auto predictedPresentTime = TimePoint::fromNs(prediction->presentTime);
4777*38e8c45fSAndroid Build Coastguard Worker 
4778*38e8c45fSAndroid Build Coastguard Worker     if (std::chrono::abs(predictedPresentTime - expectedPresentTime) >=
4779*38e8c45fSAndroid Build Coastguard Worker         scheduler::VsyncConfig::kEarlyLatchMaxThreshold) {
4780*38e8c45fSAndroid Build Coastguard Worker         return false;
4781*38e8c45fSAndroid Build Coastguard Worker     }
4782*38e8c45fSAndroid Build Coastguard Worker 
4783*38e8c45fSAndroid Build Coastguard Worker     const Duration earlyLatchVsyncThreshold = mScheduler->getVsyncSchedule()->minFramePeriod() / 2;
4784*38e8c45fSAndroid Build Coastguard Worker 
4785*38e8c45fSAndroid Build Coastguard Worker     return predictedPresentTime >= expectedPresentTime &&
4786*38e8c45fSAndroid Build Coastguard Worker             predictedPresentTime - expectedPresentTime >= earlyLatchVsyncThreshold;
4787*38e8c45fSAndroid Build Coastguard Worker }
4788*38e8c45fSAndroid Build Coastguard Worker 
shouldLatchUnsignaled(const layer_state_t & state,size_t numStates,bool firstTransaction) const4789*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::shouldLatchUnsignaled(const layer_state_t& state, size_t numStates,
4790*38e8c45fSAndroid Build Coastguard Worker                                            bool firstTransaction) const {
4791*38e8c45fSAndroid Build Coastguard Worker     if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::Disabled) {
4792*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::Disabled)", __func__);
4793*38e8c45fSAndroid Build Coastguard Worker         return false;
4794*38e8c45fSAndroid Build Coastguard Worker     }
4795*38e8c45fSAndroid Build Coastguard Worker 
4796*38e8c45fSAndroid Build Coastguard Worker     // We only want to latch unsignaled when a single layer is updated in this
4797*38e8c45fSAndroid Build Coastguard Worker     // transaction (i.e. not a blast sync transaction).
4798*38e8c45fSAndroid Build Coastguard Worker     if (numStates != 1) {
4799*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_FORMAT_INSTANT("%s: false (numStates=%zu)", __func__, numStates);
4800*38e8c45fSAndroid Build Coastguard Worker         return false;
4801*38e8c45fSAndroid Build Coastguard Worker     }
4802*38e8c45fSAndroid Build Coastguard Worker 
4803*38e8c45fSAndroid Build Coastguard Worker     if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::AutoSingleLayer) {
4804*38e8c45fSAndroid Build Coastguard Worker         if (!firstTransaction) {
4805*38e8c45fSAndroid Build Coastguard Worker             SFTRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::AutoSingleLayer; not first "
4806*38e8c45fSAndroid Build Coastguard Worker                                    "transaction)",
4807*38e8c45fSAndroid Build Coastguard Worker                                    __func__);
4808*38e8c45fSAndroid Build Coastguard Worker             return false;
4809*38e8c45fSAndroid Build Coastguard Worker         }
4810*38e8c45fSAndroid Build Coastguard Worker 
4811*38e8c45fSAndroid Build Coastguard Worker         // We don't want to latch unsignaled if are in early / client composition
4812*38e8c45fSAndroid Build Coastguard Worker         // as it leads to jank due to RenderEngine waiting for unsignaled buffer
4813*38e8c45fSAndroid Build Coastguard Worker         // or window animations being slow.
4814*38e8c45fSAndroid Build Coastguard Worker         if (mScheduler->vsyncModulator().isVsyncConfigEarly()) {
4815*38e8c45fSAndroid Build Coastguard Worker             SFTRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::AutoSingleLayer; "
4816*38e8c45fSAndroid Build Coastguard Worker                                    "isVsyncConfigEarly)",
4817*38e8c45fSAndroid Build Coastguard Worker                                    __func__);
4818*38e8c45fSAndroid Build Coastguard Worker             return false;
4819*38e8c45fSAndroid Build Coastguard Worker         }
4820*38e8c45fSAndroid Build Coastguard Worker     }
4821*38e8c45fSAndroid Build Coastguard Worker 
4822*38e8c45fSAndroid Build Coastguard Worker     return true;
4823*38e8c45fSAndroid Build Coastguard Worker }
4824*38e8c45fSAndroid Build Coastguard Worker 
setTransactionState(const FrameTimelineInfo & frameTimelineInfo,Vector<ComposerState> & states,Vector<DisplayState> & displays,uint32_t flags,const sp<IBinder> & applyToken,InputWindowCommands inputWindowCommands,int64_t desiredPresentTime,bool isAutoTimestamp,const std::vector<client_cache_t> & uncacheBuffers,bool hasListenerCallbacks,const std::vector<ListenerCallbacks> & listenerCallbacks,uint64_t transactionId,const std::vector<uint64_t> & mergedTransactionIds)4825*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setTransactionState(
4826*38e8c45fSAndroid Build Coastguard Worker         const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& states,
4827*38e8c45fSAndroid Build Coastguard Worker         Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
4828*38e8c45fSAndroid Build Coastguard Worker         InputWindowCommands inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp,
4829*38e8c45fSAndroid Build Coastguard Worker         const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks,
4830*38e8c45fSAndroid Build Coastguard Worker         const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId,
4831*38e8c45fSAndroid Build Coastguard Worker         const std::vector<uint64_t>& mergedTransactionIds) {
4832*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
4833*38e8c45fSAndroid Build Coastguard Worker 
4834*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
4835*38e8c45fSAndroid Build Coastguard Worker     const int originPid = ipc->getCallingPid();
4836*38e8c45fSAndroid Build Coastguard Worker     const int originUid = ipc->getCallingUid();
4837*38e8c45fSAndroid Build Coastguard Worker     uint32_t permissions = LayerStatePermissions::getTransactionPermissions(originPid, originUid);
4838*38e8c45fSAndroid Build Coastguard Worker     for (auto& composerState : states) {
4839*38e8c45fSAndroid Build Coastguard Worker         composerState.state.sanitize(permissions);
4840*38e8c45fSAndroid Build Coastguard Worker     }
4841*38e8c45fSAndroid Build Coastguard Worker 
4842*38e8c45fSAndroid Build Coastguard Worker     for (DisplayState& display : displays) {
4843*38e8c45fSAndroid Build Coastguard Worker         display.sanitize(permissions);
4844*38e8c45fSAndroid Build Coastguard Worker     }
4845*38e8c45fSAndroid Build Coastguard Worker 
4846*38e8c45fSAndroid Build Coastguard Worker     if (!inputWindowCommands.empty() &&
4847*38e8c45fSAndroid Build Coastguard Worker         (permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) == 0) {
4848*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Only privileged callers are allowed to send input commands.");
4849*38e8c45fSAndroid Build Coastguard Worker         inputWindowCommands.clear();
4850*38e8c45fSAndroid Build Coastguard Worker     }
4851*38e8c45fSAndroid Build Coastguard Worker 
4852*38e8c45fSAndroid Build Coastguard Worker     if (flags & (eEarlyWakeupStart | eEarlyWakeupEnd)) {
4853*38e8c45fSAndroid Build Coastguard Worker         const bool hasPermission =
4854*38e8c45fSAndroid Build Coastguard Worker                 (permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) ||
4855*38e8c45fSAndroid Build Coastguard Worker                 callingThreadHasPermission(sWakeupSurfaceFlinger);
4856*38e8c45fSAndroid Build Coastguard Worker         if (!hasPermission) {
4857*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Caller needs permission android.permission.WAKEUP_SURFACE_FLINGER to use "
4858*38e8c45fSAndroid Build Coastguard Worker                   "eEarlyWakeup[Start|End] flags");
4859*38e8c45fSAndroid Build Coastguard Worker             flags &= ~(eEarlyWakeupStart | eEarlyWakeupEnd);
4860*38e8c45fSAndroid Build Coastguard Worker         }
4861*38e8c45fSAndroid Build Coastguard Worker     }
4862*38e8c45fSAndroid Build Coastguard Worker 
4863*38e8c45fSAndroid Build Coastguard Worker     const int64_t postTime = systemTime();
4864*38e8c45fSAndroid Build Coastguard Worker 
4865*38e8c45fSAndroid Build Coastguard Worker     std::vector<uint64_t> uncacheBufferIds;
4866*38e8c45fSAndroid Build Coastguard Worker     uncacheBufferIds.reserve(uncacheBuffers.size());
4867*38e8c45fSAndroid Build Coastguard Worker     for (const auto& uncacheBuffer : uncacheBuffers) {
4868*38e8c45fSAndroid Build Coastguard Worker         sp<GraphicBuffer> buffer = ClientCache::getInstance().erase(uncacheBuffer);
4869*38e8c45fSAndroid Build Coastguard Worker         if (buffer != nullptr) {
4870*38e8c45fSAndroid Build Coastguard Worker             uncacheBufferIds.push_back(buffer->getId());
4871*38e8c45fSAndroid Build Coastguard Worker         }
4872*38e8c45fSAndroid Build Coastguard Worker     }
4873*38e8c45fSAndroid Build Coastguard Worker 
4874*38e8c45fSAndroid Build Coastguard Worker     std::vector<ResolvedComposerState> resolvedStates;
4875*38e8c45fSAndroid Build Coastguard Worker     resolvedStates.reserve(states.size());
4876*38e8c45fSAndroid Build Coastguard Worker     for (auto& state : states) {
4877*38e8c45fSAndroid Build Coastguard Worker         resolvedStates.emplace_back(std::move(state));
4878*38e8c45fSAndroid Build Coastguard Worker         auto& resolvedState = resolvedStates.back();
4879*38e8c45fSAndroid Build Coastguard Worker         resolvedState.layerId = LayerHandle::getLayerId(resolvedState.state.surface);
4880*38e8c45fSAndroid Build Coastguard Worker         if (resolvedState.state.hasBufferChanges() && resolvedState.state.hasValidBuffer() &&
4881*38e8c45fSAndroid Build Coastguard Worker             resolvedState.state.surface) {
4882*38e8c45fSAndroid Build Coastguard Worker             sp<Layer> layer = LayerHandle::getLayer(resolvedState.state.surface);
4883*38e8c45fSAndroid Build Coastguard Worker             std::string layerName = (layer) ?
4884*38e8c45fSAndroid Build Coastguard Worker                     layer->getDebugName() : std::to_string(resolvedState.state.layerId);
4885*38e8c45fSAndroid Build Coastguard Worker             resolvedState.externalTexture =
4886*38e8c45fSAndroid Build Coastguard Worker                     getExternalTextureFromBufferData(*resolvedState.state.bufferData,
4887*38e8c45fSAndroid Build Coastguard Worker                                                      layerName.c_str(), transactionId);
4888*38e8c45fSAndroid Build Coastguard Worker             if (resolvedState.externalTexture) {
4889*38e8c45fSAndroid Build Coastguard Worker                 resolvedState.state.bufferData->buffer = resolvedState.externalTexture->getBuffer();
4890*38e8c45fSAndroid Build Coastguard Worker             }
4891*38e8c45fSAndroid Build Coastguard Worker             mBufferCountTracker.increment(resolvedState.layerId);
4892*38e8c45fSAndroid Build Coastguard Worker         }
4893*38e8c45fSAndroid Build Coastguard Worker         if (resolvedState.state.what & layer_state_t::eReparent) {
4894*38e8c45fSAndroid Build Coastguard Worker             resolvedState.parentId =
4895*38e8c45fSAndroid Build Coastguard Worker                     getLayerIdFromSurfaceControl(resolvedState.state.parentSurfaceControlForChild);
4896*38e8c45fSAndroid Build Coastguard Worker         }
4897*38e8c45fSAndroid Build Coastguard Worker         if (resolvedState.state.what & layer_state_t::eRelativeLayerChanged) {
4898*38e8c45fSAndroid Build Coastguard Worker             resolvedState.relativeParentId =
4899*38e8c45fSAndroid Build Coastguard Worker                     getLayerIdFromSurfaceControl(resolvedState.state.relativeLayerSurfaceControl);
4900*38e8c45fSAndroid Build Coastguard Worker         }
4901*38e8c45fSAndroid Build Coastguard Worker         if (resolvedState.state.what & layer_state_t::eInputInfoChanged) {
4902*38e8c45fSAndroid Build Coastguard Worker             wp<IBinder>& touchableRegionCropHandle =
4903*38e8c45fSAndroid Build Coastguard Worker                     resolvedState.state.windowInfoHandle->editInfo()->touchableRegionCropHandle;
4904*38e8c45fSAndroid Build Coastguard Worker             resolvedState.touchCropId =
4905*38e8c45fSAndroid Build Coastguard Worker                     LayerHandle::getLayerId(touchableRegionCropHandle.promote());
4906*38e8c45fSAndroid Build Coastguard Worker         }
4907*38e8c45fSAndroid Build Coastguard Worker     }
4908*38e8c45fSAndroid Build Coastguard Worker 
4909*38e8c45fSAndroid Build Coastguard Worker     TransactionState state{frameTimelineInfo,
4910*38e8c45fSAndroid Build Coastguard Worker                            resolvedStates,
4911*38e8c45fSAndroid Build Coastguard Worker                            displays,
4912*38e8c45fSAndroid Build Coastguard Worker                            flags,
4913*38e8c45fSAndroid Build Coastguard Worker                            applyToken,
4914*38e8c45fSAndroid Build Coastguard Worker                            std::move(inputWindowCommands),
4915*38e8c45fSAndroid Build Coastguard Worker                            desiredPresentTime,
4916*38e8c45fSAndroid Build Coastguard Worker                            isAutoTimestamp,
4917*38e8c45fSAndroid Build Coastguard Worker                            std::move(uncacheBufferIds),
4918*38e8c45fSAndroid Build Coastguard Worker                            postTime,
4919*38e8c45fSAndroid Build Coastguard Worker                            hasListenerCallbacks,
4920*38e8c45fSAndroid Build Coastguard Worker                            listenerCallbacks,
4921*38e8c45fSAndroid Build Coastguard Worker                            originPid,
4922*38e8c45fSAndroid Build Coastguard Worker                            originUid,
4923*38e8c45fSAndroid Build Coastguard Worker                            transactionId,
4924*38e8c45fSAndroid Build Coastguard Worker                            mergedTransactionIds};
4925*38e8c45fSAndroid Build Coastguard Worker 
4926*38e8c45fSAndroid Build Coastguard Worker     if (mTransactionTracing) {
4927*38e8c45fSAndroid Build Coastguard Worker         mTransactionTracing->addQueuedTransaction(state);
4928*38e8c45fSAndroid Build Coastguard Worker     }
4929*38e8c45fSAndroid Build Coastguard Worker 
4930*38e8c45fSAndroid Build Coastguard Worker     const auto schedule = [](uint32_t flags) {
4931*38e8c45fSAndroid Build Coastguard Worker         if (flags & eEarlyWakeupEnd) return TransactionSchedule::EarlyEnd;
4932*38e8c45fSAndroid Build Coastguard Worker         if (flags & eEarlyWakeupStart) return TransactionSchedule::EarlyStart;
4933*38e8c45fSAndroid Build Coastguard Worker         return TransactionSchedule::Late;
4934*38e8c45fSAndroid Build Coastguard Worker     }(state.flags);
4935*38e8c45fSAndroid Build Coastguard Worker 
4936*38e8c45fSAndroid Build Coastguard Worker     const auto frameHint = state.isFrameActive() ? FrameHint::kActive : FrameHint::kNone;
4937*38e8c45fSAndroid Build Coastguard Worker     {
4938*38e8c45fSAndroid Build Coastguard Worker         // Transactions are added via a lockless queue and does not need to be added from the main
4939*38e8c45fSAndroid Build Coastguard Worker         // thread.
4940*38e8c45fSAndroid Build Coastguard Worker         ftl::FakeGuard guard(kMainThreadContext);
4941*38e8c45fSAndroid Build Coastguard Worker         mTransactionHandler.queueTransaction(std::move(state));
4942*38e8c45fSAndroid Build Coastguard Worker     }
4943*38e8c45fSAndroid Build Coastguard Worker 
4944*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [displayId, data] : mNotifyExpectedPresentMap) {
4945*38e8c45fSAndroid Build Coastguard Worker         if (data.hintStatus.load() == NotifyExpectedPresentHintStatus::ScheduleOnTx) {
4946*38e8c45fSAndroid Build Coastguard Worker             scheduleNotifyExpectedPresentHint(displayId, VsyncId{frameTimelineInfo.vsyncId});
4947*38e8c45fSAndroid Build Coastguard Worker         }
4948*38e8c45fSAndroid Build Coastguard Worker     }
4949*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eTransactionFlushNeeded, schedule, applyToken, frameHint);
4950*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
4951*38e8c45fSAndroid Build Coastguard Worker }
4952*38e8c45fSAndroid Build Coastguard Worker 
applyTransactionState(const FrameTimelineInfo & frameTimelineInfo,std::vector<ResolvedComposerState> & states,Vector<DisplayState> & displays,uint32_t flags,const InputWindowCommands & inputWindowCommands,const int64_t desiredPresentTime,bool isAutoTimestamp,const std::vector<uint64_t> & uncacheBufferIds,const int64_t postTime,bool hasListenerCallbacks,const std::vector<ListenerCallbacks> & listenerCallbacks,int originPid,int originUid,uint64_t transactionId)4953*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelineInfo,
4954*38e8c45fSAndroid Build Coastguard Worker                                            std::vector<ResolvedComposerState>& states,
4955*38e8c45fSAndroid Build Coastguard Worker                                            Vector<DisplayState>& displays, uint32_t flags,
4956*38e8c45fSAndroid Build Coastguard Worker                                            const InputWindowCommands& inputWindowCommands,
4957*38e8c45fSAndroid Build Coastguard Worker                                            const int64_t desiredPresentTime, bool isAutoTimestamp,
4958*38e8c45fSAndroid Build Coastguard Worker                                            const std::vector<uint64_t>& uncacheBufferIds,
4959*38e8c45fSAndroid Build Coastguard Worker                                            const int64_t postTime, bool hasListenerCallbacks,
4960*38e8c45fSAndroid Build Coastguard Worker                                            const std::vector<ListenerCallbacks>& listenerCallbacks,
4961*38e8c45fSAndroid Build Coastguard Worker                                            int originPid, int originUid, uint64_t transactionId) {
4962*38e8c45fSAndroid Build Coastguard Worker     uint32_t transactionFlags = 0;
4963*38e8c45fSAndroid Build Coastguard Worker 
4964*38e8c45fSAndroid Build Coastguard Worker     // start and end registration for listeners w/ no surface so they can get their callback.  Note
4965*38e8c45fSAndroid Build Coastguard Worker     // that listeners with SurfaceControls will start registration during setClientStateLocked
4966*38e8c45fSAndroid Build Coastguard Worker     // below.
4967*38e8c45fSAndroid Build Coastguard Worker     for (const auto& listener : listenerCallbacks) {
4968*38e8c45fSAndroid Build Coastguard Worker         mTransactionCallbackInvoker.addEmptyTransaction(listener);
4969*38e8c45fSAndroid Build Coastguard Worker     }
4970*38e8c45fSAndroid Build Coastguard Worker     uint32_t clientStateFlags = 0;
4971*38e8c45fSAndroid Build Coastguard Worker     for (auto& resolvedState : states) {
4972*38e8c45fSAndroid Build Coastguard Worker         clientStateFlags |=
4973*38e8c45fSAndroid Build Coastguard Worker                 updateLayerCallbacksAndStats(frameTimelineInfo, resolvedState, desiredPresentTime,
4974*38e8c45fSAndroid Build Coastguard Worker                                              isAutoTimestamp, postTime, transactionId);
4975*38e8c45fSAndroid Build Coastguard Worker     }
4976*38e8c45fSAndroid Build Coastguard Worker 
4977*38e8c45fSAndroid Build Coastguard Worker     transactionFlags |= clientStateFlags;
4978*38e8c45fSAndroid Build Coastguard Worker     transactionFlags |= addInputWindowCommands(inputWindowCommands);
4979*38e8c45fSAndroid Build Coastguard Worker 
4980*38e8c45fSAndroid Build Coastguard Worker     for (uint64_t uncacheBufferId : uncacheBufferIds) {
4981*38e8c45fSAndroid Build Coastguard Worker         mBufferIdsToUncache.push_back(uncacheBufferId);
4982*38e8c45fSAndroid Build Coastguard Worker     }
4983*38e8c45fSAndroid Build Coastguard Worker 
4984*38e8c45fSAndroid Build Coastguard Worker     // If a synchronous transaction is explicitly requested without any changes, force a transaction
4985*38e8c45fSAndroid Build Coastguard Worker     // anyway. This can be used as a flush mechanism for previous async transactions.
4986*38e8c45fSAndroid Build Coastguard Worker     // Empty animation transaction can be used to simulate back-pressure, so also force a
4987*38e8c45fSAndroid Build Coastguard Worker     // transaction for empty animation transactions.
4988*38e8c45fSAndroid Build Coastguard Worker     if (transactionFlags == 0 && (flags & eAnimation)) {
4989*38e8c45fSAndroid Build Coastguard Worker         transactionFlags = eTransactionNeeded;
4990*38e8c45fSAndroid Build Coastguard Worker     }
4991*38e8c45fSAndroid Build Coastguard Worker 
4992*38e8c45fSAndroid Build Coastguard Worker     bool needsTraversal = false;
4993*38e8c45fSAndroid Build Coastguard Worker     if (transactionFlags) {
4994*38e8c45fSAndroid Build Coastguard Worker         // We are on the main thread, we are about to perform a traversal. Clear the traversal bit
4995*38e8c45fSAndroid Build Coastguard Worker         // so we don't have to wake up again next frame to perform an unnecessary traversal.
4996*38e8c45fSAndroid Build Coastguard Worker         if (transactionFlags & eTraversalNeeded) {
4997*38e8c45fSAndroid Build Coastguard Worker             transactionFlags = transactionFlags & (~eTraversalNeeded);
4998*38e8c45fSAndroid Build Coastguard Worker             needsTraversal = true;
4999*38e8c45fSAndroid Build Coastguard Worker         }
5000*38e8c45fSAndroid Build Coastguard Worker         if (transactionFlags) {
5001*38e8c45fSAndroid Build Coastguard Worker             setTransactionFlags(transactionFlags);
5002*38e8c45fSAndroid Build Coastguard Worker         }
5003*38e8c45fSAndroid Build Coastguard Worker     }
5004*38e8c45fSAndroid Build Coastguard Worker 
5005*38e8c45fSAndroid Build Coastguard Worker     return needsTraversal;
5006*38e8c45fSAndroid Build Coastguard Worker }
5007*38e8c45fSAndroid Build Coastguard Worker 
applyAndCommitDisplayTransactionStatesLocked(std::vector<TransactionState> & transactions)5008*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::applyAndCommitDisplayTransactionStatesLocked(
5009*38e8c45fSAndroid Build Coastguard Worker         std::vector<TransactionState>& transactions) {
5010*38e8c45fSAndroid Build Coastguard Worker     bool needsTraversal = false;
5011*38e8c45fSAndroid Build Coastguard Worker     uint32_t transactionFlags = 0;
5012*38e8c45fSAndroid Build Coastguard Worker     for (auto& transaction : transactions) {
5013*38e8c45fSAndroid Build Coastguard Worker         for (DisplayState& display : transaction.displays) {
5014*38e8c45fSAndroid Build Coastguard Worker             transactionFlags |= setDisplayStateLocked(display);
5015*38e8c45fSAndroid Build Coastguard Worker         }
5016*38e8c45fSAndroid Build Coastguard Worker     }
5017*38e8c45fSAndroid Build Coastguard Worker 
5018*38e8c45fSAndroid Build Coastguard Worker     if (transactionFlags) {
5019*38e8c45fSAndroid Build Coastguard Worker         // We are on the main thread, we are about to perform a traversal. Clear the traversal bit
5020*38e8c45fSAndroid Build Coastguard Worker         // so we don't have to wake up again next frame to perform an unnecessary traversal.
5021*38e8c45fSAndroid Build Coastguard Worker         if (transactionFlags & eTraversalNeeded) {
5022*38e8c45fSAndroid Build Coastguard Worker             transactionFlags = transactionFlags & (~eTraversalNeeded);
5023*38e8c45fSAndroid Build Coastguard Worker             needsTraversal = true;
5024*38e8c45fSAndroid Build Coastguard Worker         }
5025*38e8c45fSAndroid Build Coastguard Worker         if (transactionFlags) {
5026*38e8c45fSAndroid Build Coastguard Worker             setTransactionFlags(transactionFlags);
5027*38e8c45fSAndroid Build Coastguard Worker         }
5028*38e8c45fSAndroid Build Coastguard Worker     }
5029*38e8c45fSAndroid Build Coastguard Worker 
5030*38e8c45fSAndroid Build Coastguard Worker     mFrontEndDisplayInfosChanged = mTransactionFlags & eDisplayTransactionNeeded;
5031*38e8c45fSAndroid Build Coastguard Worker     if (mFrontEndDisplayInfosChanged) {
5032*38e8c45fSAndroid Build Coastguard Worker         processDisplayChangesLocked();
5033*38e8c45fSAndroid Build Coastguard Worker         mFrontEndDisplayInfos.clear();
5034*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [_, display] : mDisplays) {
5035*38e8c45fSAndroid Build Coastguard Worker             mFrontEndDisplayInfos.try_emplace(display->getLayerStack(), display->getFrontEndInfo());
5036*38e8c45fSAndroid Build Coastguard Worker         }
5037*38e8c45fSAndroid Build Coastguard Worker         needsTraversal = true;
5038*38e8c45fSAndroid Build Coastguard Worker     }
5039*38e8c45fSAndroid Build Coastguard Worker 
5040*38e8c45fSAndroid Build Coastguard Worker     return needsTraversal;
5041*38e8c45fSAndroid Build Coastguard Worker }
5042*38e8c45fSAndroid Build Coastguard Worker 
setDisplayStateLocked(const DisplayState & s)5043*38e8c45fSAndroid Build Coastguard Worker uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) {
5044*38e8c45fSAndroid Build Coastguard Worker     const ssize_t index = mCurrentState.displays.indexOfKey(s.token);
5045*38e8c45fSAndroid Build Coastguard Worker     if (index < 0) return 0;
5046*38e8c45fSAndroid Build Coastguard Worker 
5047*38e8c45fSAndroid Build Coastguard Worker     uint32_t flags = 0;
5048*38e8c45fSAndroid Build Coastguard Worker     DisplayDeviceState& state = mCurrentState.displays.editValueAt(index);
5049*38e8c45fSAndroid Build Coastguard Worker 
5050*38e8c45fSAndroid Build Coastguard Worker     const uint32_t what = s.what;
5051*38e8c45fSAndroid Build Coastguard Worker     if (what & DisplayState::eSurfaceChanged) {
5052*38e8c45fSAndroid Build Coastguard Worker         if (IInterface::asBinder(state.surface) != IInterface::asBinder(s.surface)) {
5053*38e8c45fSAndroid Build Coastguard Worker             state.surface = s.surface;
5054*38e8c45fSAndroid Build Coastguard Worker             flags |= eDisplayTransactionNeeded;
5055*38e8c45fSAndroid Build Coastguard Worker         }
5056*38e8c45fSAndroid Build Coastguard Worker     }
5057*38e8c45fSAndroid Build Coastguard Worker     if (what & DisplayState::eLayerStackChanged) {
5058*38e8c45fSAndroid Build Coastguard Worker         if (state.layerStack != s.layerStack) {
5059*38e8c45fSAndroid Build Coastguard Worker             state.layerStack = s.layerStack;
5060*38e8c45fSAndroid Build Coastguard Worker             flags |= eDisplayTransactionNeeded;
5061*38e8c45fSAndroid Build Coastguard Worker         }
5062*38e8c45fSAndroid Build Coastguard Worker     }
5063*38e8c45fSAndroid Build Coastguard Worker     if (what & DisplayState::eFlagsChanged) {
5064*38e8c45fSAndroid Build Coastguard Worker         if (state.flags != s.flags) {
5065*38e8c45fSAndroid Build Coastguard Worker             state.flags = s.flags;
5066*38e8c45fSAndroid Build Coastguard Worker             flags |= eDisplayTransactionNeeded;
5067*38e8c45fSAndroid Build Coastguard Worker         }
5068*38e8c45fSAndroid Build Coastguard Worker     }
5069*38e8c45fSAndroid Build Coastguard Worker     if (what & DisplayState::eDisplayProjectionChanged) {
5070*38e8c45fSAndroid Build Coastguard Worker         if (state.orientation != s.orientation) {
5071*38e8c45fSAndroid Build Coastguard Worker             state.orientation = s.orientation;
5072*38e8c45fSAndroid Build Coastguard Worker             flags |= eDisplayTransactionNeeded;
5073*38e8c45fSAndroid Build Coastguard Worker         }
5074*38e8c45fSAndroid Build Coastguard Worker         if (state.orientedDisplaySpaceRect != s.orientedDisplaySpaceRect) {
5075*38e8c45fSAndroid Build Coastguard Worker             state.orientedDisplaySpaceRect = s.orientedDisplaySpaceRect;
5076*38e8c45fSAndroid Build Coastguard Worker             flags |= eDisplayTransactionNeeded;
5077*38e8c45fSAndroid Build Coastguard Worker         }
5078*38e8c45fSAndroid Build Coastguard Worker         if (state.layerStackSpaceRect != s.layerStackSpaceRect) {
5079*38e8c45fSAndroid Build Coastguard Worker             state.layerStackSpaceRect = s.layerStackSpaceRect;
5080*38e8c45fSAndroid Build Coastguard Worker             flags |= eDisplayTransactionNeeded;
5081*38e8c45fSAndroid Build Coastguard Worker         }
5082*38e8c45fSAndroid Build Coastguard Worker     }
5083*38e8c45fSAndroid Build Coastguard Worker     if (what & DisplayState::eDisplaySizeChanged) {
5084*38e8c45fSAndroid Build Coastguard Worker         if (state.width != s.width) {
5085*38e8c45fSAndroid Build Coastguard Worker             state.width = s.width;
5086*38e8c45fSAndroid Build Coastguard Worker             flags |= eDisplayTransactionNeeded;
5087*38e8c45fSAndroid Build Coastguard Worker         }
5088*38e8c45fSAndroid Build Coastguard Worker         if (state.height != s.height) {
5089*38e8c45fSAndroid Build Coastguard Worker             state.height = s.height;
5090*38e8c45fSAndroid Build Coastguard Worker             flags |= eDisplayTransactionNeeded;
5091*38e8c45fSAndroid Build Coastguard Worker         }
5092*38e8c45fSAndroid Build Coastguard Worker     }
5093*38e8c45fSAndroid Build Coastguard Worker 
5094*38e8c45fSAndroid Build Coastguard Worker     return flags;
5095*38e8c45fSAndroid Build Coastguard Worker }
5096*38e8c45fSAndroid Build Coastguard Worker 
callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermissionCache)5097*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermissionCache) {
5098*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
5099*38e8c45fSAndroid Build Coastguard Worker     const int pid = ipc->getCallingPid();
5100*38e8c45fSAndroid Build Coastguard Worker     const int uid = ipc->getCallingUid();
5101*38e8c45fSAndroid Build Coastguard Worker     if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) &&
5102*38e8c45fSAndroid Build Coastguard Worker         (usePermissionCache ? !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)
5103*38e8c45fSAndroid Build Coastguard Worker                             : !checkPermission(sAccessSurfaceFlinger, pid, uid))) {
5104*38e8c45fSAndroid Build Coastguard Worker         return false;
5105*38e8c45fSAndroid Build Coastguard Worker     }
5106*38e8c45fSAndroid Build Coastguard Worker     return true;
5107*38e8c45fSAndroid Build Coastguard Worker }
5108*38e8c45fSAndroid Build Coastguard Worker 
updateLayerCallbacksAndStats(const FrameTimelineInfo & frameTimelineInfo,ResolvedComposerState & composerState,int64_t desiredPresentTime,bool isAutoTimestamp,int64_t postTime,uint64_t transactionId)5109*38e8c45fSAndroid Build Coastguard Worker uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& frameTimelineInfo,
5110*38e8c45fSAndroid Build Coastguard Worker                                                       ResolvedComposerState& composerState,
5111*38e8c45fSAndroid Build Coastguard Worker                                                       int64_t desiredPresentTime,
5112*38e8c45fSAndroid Build Coastguard Worker                                                       bool isAutoTimestamp, int64_t postTime,
5113*38e8c45fSAndroid Build Coastguard Worker                                                       uint64_t transactionId) {
5114*38e8c45fSAndroid Build Coastguard Worker     layer_state_t& s = composerState.state;
5115*38e8c45fSAndroid Build Coastguard Worker 
5116*38e8c45fSAndroid Build Coastguard Worker     std::vector<ListenerCallbacks> filteredListeners;
5117*38e8c45fSAndroid Build Coastguard Worker     for (auto& listener : s.listeners) {
5118*38e8c45fSAndroid Build Coastguard Worker         // Starts a registration but separates the callback ids according to callback type. This
5119*38e8c45fSAndroid Build Coastguard Worker         // allows the callback invoker to send on latch callbacks earlier.
5120*38e8c45fSAndroid Build Coastguard Worker         // note that startRegistration will not re-register if the listener has
5121*38e8c45fSAndroid Build Coastguard Worker         // already be registered for a prior surface control
5122*38e8c45fSAndroid Build Coastguard Worker 
5123*38e8c45fSAndroid Build Coastguard Worker         ListenerCallbacks onCommitCallbacks = listener.filter(CallbackId::Type::ON_COMMIT);
5124*38e8c45fSAndroid Build Coastguard Worker         if (!onCommitCallbacks.callbackIds.empty()) {
5125*38e8c45fSAndroid Build Coastguard Worker             filteredListeners.push_back(onCommitCallbacks);
5126*38e8c45fSAndroid Build Coastguard Worker         }
5127*38e8c45fSAndroid Build Coastguard Worker 
5128*38e8c45fSAndroid Build Coastguard Worker         ListenerCallbacks onCompleteCallbacks = listener.filter(CallbackId::Type::ON_COMPLETE);
5129*38e8c45fSAndroid Build Coastguard Worker         if (!onCompleteCallbacks.callbackIds.empty()) {
5130*38e8c45fSAndroid Build Coastguard Worker             filteredListeners.push_back(onCompleteCallbacks);
5131*38e8c45fSAndroid Build Coastguard Worker         }
5132*38e8c45fSAndroid Build Coastguard Worker     }
5133*38e8c45fSAndroid Build Coastguard Worker 
5134*38e8c45fSAndroid Build Coastguard Worker     const uint64_t what = s.what;
5135*38e8c45fSAndroid Build Coastguard Worker     uint32_t flags = 0;
5136*38e8c45fSAndroid Build Coastguard Worker     sp<Layer> layer = nullptr;
5137*38e8c45fSAndroid Build Coastguard Worker     if (s.surface) {
5138*38e8c45fSAndroid Build Coastguard Worker         layer = LayerHandle::getLayer(s.surface);
5139*38e8c45fSAndroid Build Coastguard Worker     } else {
5140*38e8c45fSAndroid Build Coastguard Worker         // The client may provide us a null handle. Treat it as if the layer was removed.
5141*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Attempt to set client state with a null layer handle");
5142*38e8c45fSAndroid Build Coastguard Worker     }
5143*38e8c45fSAndroid Build Coastguard Worker     if (layer == nullptr) {
5144*38e8c45fSAndroid Build Coastguard Worker         for (auto& [listener, callbackIds] : s.listeners) {
5145*38e8c45fSAndroid Build Coastguard Worker             mTransactionCallbackInvoker.addCallbackHandle(
5146*38e8c45fSAndroid Build Coastguard Worker                     sp<CallbackHandle>::make(listener, callbackIds, s.surface));
5147*38e8c45fSAndroid Build Coastguard Worker         }
5148*38e8c45fSAndroid Build Coastguard Worker         return 0;
5149*38e8c45fSAndroid Build Coastguard Worker     }
5150*38e8c45fSAndroid Build Coastguard Worker     if (what & layer_state_t::eProducerDisconnect) {
5151*38e8c45fSAndroid Build Coastguard Worker         layer->onDisconnect();
5152*38e8c45fSAndroid Build Coastguard Worker     }
5153*38e8c45fSAndroid Build Coastguard Worker 
5154*38e8c45fSAndroid Build Coastguard Worker     std::vector<sp<CallbackHandle>> callbackHandles;
5155*38e8c45fSAndroid Build Coastguard Worker     if ((what & layer_state_t::eHasListenerCallbacksChanged) && (!filteredListeners.empty())) {
5156*38e8c45fSAndroid Build Coastguard Worker         for (auto& [listener, callbackIds] : filteredListeners) {
5157*38e8c45fSAndroid Build Coastguard Worker             callbackHandles.emplace_back(
5158*38e8c45fSAndroid Build Coastguard Worker                     sp<CallbackHandle>::make(listener, callbackIds, s.surface));
5159*38e8c45fSAndroid Build Coastguard Worker         }
5160*38e8c45fSAndroid Build Coastguard Worker     }
5161*38e8c45fSAndroid Build Coastguard Worker 
5162*38e8c45fSAndroid Build Coastguard Worker     frontend::LayerSnapshot* snapshot = nullptr;
5163*38e8c45fSAndroid Build Coastguard Worker     gui::GameMode gameMode = gui::GameMode::Unsupported;
5164*38e8c45fSAndroid Build Coastguard Worker     if (what & (layer_state_t::eSidebandStreamChanged | layer_state_t::eBufferChanged) ||
5165*38e8c45fSAndroid Build Coastguard Worker         frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
5166*38e8c45fSAndroid Build Coastguard Worker         snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence);
5167*38e8c45fSAndroid Build Coastguard Worker         if (snapshot) {
5168*38e8c45fSAndroid Build Coastguard Worker             gameMode = snapshot->gameMode;
5169*38e8c45fSAndroid Build Coastguard Worker         }
5170*38e8c45fSAndroid Build Coastguard Worker     }
5171*38e8c45fSAndroid Build Coastguard Worker 
5172*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/238781169) remove after screenshot refactor, currently screenshots
5173*38e8c45fSAndroid Build Coastguard Worker     // requires to read drawing state from binder thread. So we need to fix that
5174*38e8c45fSAndroid Build Coastguard Worker     // before removing this.
5175*38e8c45fSAndroid Build Coastguard Worker     if (what & layer_state_t::eBufferTransformChanged) {
5176*38e8c45fSAndroid Build Coastguard Worker         if (layer->setTransform(s.bufferTransform)) flags |= eTraversalNeeded;
5177*38e8c45fSAndroid Build Coastguard Worker     }
5178*38e8c45fSAndroid Build Coastguard Worker     if (what & layer_state_t::eTransformToDisplayInverseChanged) {
5179*38e8c45fSAndroid Build Coastguard Worker         if (layer->setTransformToDisplayInverse(s.transformToDisplayInverse))
5180*38e8c45fSAndroid Build Coastguard Worker             flags |= eTraversalNeeded;
5181*38e8c45fSAndroid Build Coastguard Worker     }
5182*38e8c45fSAndroid Build Coastguard Worker     if (what & layer_state_t::eCropChanged) {
5183*38e8c45fSAndroid Build Coastguard Worker         if (layer->setCrop(s.crop)) flags |= eTraversalNeeded;
5184*38e8c45fSAndroid Build Coastguard Worker     }
5185*38e8c45fSAndroid Build Coastguard Worker     if (what & layer_state_t::eSidebandStreamChanged) {
5186*38e8c45fSAndroid Build Coastguard Worker         if (layer->setSidebandStream(s.sidebandStream, frameTimelineInfo, postTime, gameMode))
5187*38e8c45fSAndroid Build Coastguard Worker             flags |= eTraversalNeeded;
5188*38e8c45fSAndroid Build Coastguard Worker     }
5189*38e8c45fSAndroid Build Coastguard Worker     if (what & layer_state_t::eDataspaceChanged) {
5190*38e8c45fSAndroid Build Coastguard Worker         if (layer->setDataspace(s.dataspace)) flags |= eTraversalNeeded;
5191*38e8c45fSAndroid Build Coastguard Worker     }
5192*38e8c45fSAndroid Build Coastguard Worker     if (what & layer_state_t::eExtendedRangeBrightnessChanged) {
5193*38e8c45fSAndroid Build Coastguard Worker         if (layer->setExtendedRangeBrightness(s.currentHdrSdrRatio, s.desiredHdrSdrRatio)) {
5194*38e8c45fSAndroid Build Coastguard Worker             flags |= eTraversalNeeded;
5195*38e8c45fSAndroid Build Coastguard Worker         }
5196*38e8c45fSAndroid Build Coastguard Worker     }
5197*38e8c45fSAndroid Build Coastguard Worker     if (what & layer_state_t::eDesiredHdrHeadroomChanged) {
5198*38e8c45fSAndroid Build Coastguard Worker         if (layer->setDesiredHdrHeadroom(s.desiredHdrSdrRatio)) {
5199*38e8c45fSAndroid Build Coastguard Worker             flags |= eTraversalNeeded;
5200*38e8c45fSAndroid Build Coastguard Worker         }
5201*38e8c45fSAndroid Build Coastguard Worker     }
5202*38e8c45fSAndroid Build Coastguard Worker     if (what & layer_state_t::eBufferChanged) {
5203*38e8c45fSAndroid Build Coastguard Worker         std::optional<ui::Transform::RotationFlags> transformHint = std::nullopt;
5204*38e8c45fSAndroid Build Coastguard Worker         if (snapshot) {
5205*38e8c45fSAndroid Build Coastguard Worker             transformHint = snapshot->transformHint;
5206*38e8c45fSAndroid Build Coastguard Worker         }
5207*38e8c45fSAndroid Build Coastguard Worker         layer->setTransformHint(transformHint);
5208*38e8c45fSAndroid Build Coastguard Worker         if (layer->setBuffer(composerState.externalTexture, *s.bufferData, postTime,
5209*38e8c45fSAndroid Build Coastguard Worker                              desiredPresentTime, isAutoTimestamp, frameTimelineInfo, gameMode)) {
5210*38e8c45fSAndroid Build Coastguard Worker             flags |= eTraversalNeeded;
5211*38e8c45fSAndroid Build Coastguard Worker         }
5212*38e8c45fSAndroid Build Coastguard Worker         mLayersWithQueuedFrames.emplace(layer, gameMode);
5213*38e8c45fSAndroid Build Coastguard Worker     } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
5214*38e8c45fSAndroid Build Coastguard Worker         layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime, gameMode);
5215*38e8c45fSAndroid Build Coastguard Worker     }
5216*38e8c45fSAndroid Build Coastguard Worker 
5217*38e8c45fSAndroid Build Coastguard Worker     if ((what & layer_state_t::eBufferChanged) == 0) {
5218*38e8c45fSAndroid Build Coastguard Worker         layer->setDesiredPresentTime(desiredPresentTime, isAutoTimestamp);
5219*38e8c45fSAndroid Build Coastguard Worker     }
5220*38e8c45fSAndroid Build Coastguard Worker 
5221*38e8c45fSAndroid Build Coastguard Worker     if (what & layer_state_t::eTrustedPresentationInfoChanged) {
5222*38e8c45fSAndroid Build Coastguard Worker         if (layer->setTrustedPresentationInfo(s.trustedPresentationThresholds,
5223*38e8c45fSAndroid Build Coastguard Worker                                               s.trustedPresentationListener)) {
5224*38e8c45fSAndroid Build Coastguard Worker             flags |= eTraversalNeeded;
5225*38e8c45fSAndroid Build Coastguard Worker         }
5226*38e8c45fSAndroid Build Coastguard Worker     }
5227*38e8c45fSAndroid Build Coastguard Worker 
5228*38e8c45fSAndroid Build Coastguard Worker     if (what & layer_state_t::eBufferReleaseChannelChanged) {
5229*38e8c45fSAndroid Build Coastguard Worker         layer->setBufferReleaseChannel(s.bufferReleaseChannel);
5230*38e8c45fSAndroid Build Coastguard Worker     }
5231*38e8c45fSAndroid Build Coastguard Worker 
5232*38e8c45fSAndroid Build Coastguard Worker     const auto& requestedLayerState = mLayerLifecycleManager.getLayerFromId(layer->getSequence());
5233*38e8c45fSAndroid Build Coastguard Worker     bool willPresentCurrentTransaction = requestedLayerState &&
5234*38e8c45fSAndroid Build Coastguard Worker             (requestedLayerState->hasReadyFrame() ||
5235*38e8c45fSAndroid Build Coastguard Worker              requestedLayerState->willReleaseBufferOnLatch());
5236*38e8c45fSAndroid Build Coastguard Worker     if (layer->setTransactionCompletedListeners(callbackHandles, willPresentCurrentTransaction))
5237*38e8c45fSAndroid Build Coastguard Worker         flags |= eTraversalNeeded;
5238*38e8c45fSAndroid Build Coastguard Worker 
5239*38e8c45fSAndroid Build Coastguard Worker     return flags;
5240*38e8c45fSAndroid Build Coastguard Worker }
5241*38e8c45fSAndroid Build Coastguard Worker 
addInputWindowCommands(const InputWindowCommands & inputWindowCommands)5242*38e8c45fSAndroid Build Coastguard Worker uint32_t SurfaceFlinger::addInputWindowCommands(const InputWindowCommands& inputWindowCommands) {
5243*38e8c45fSAndroid Build Coastguard Worker     bool hasChanges = mInputWindowCommands.merge(inputWindowCommands);
5244*38e8c45fSAndroid Build Coastguard Worker     return hasChanges ? eTraversalNeeded : 0;
5245*38e8c45fSAndroid Build Coastguard Worker }
5246*38e8c45fSAndroid Build Coastguard Worker 
mirrorLayer(const LayerCreationArgs & args,const sp<IBinder> & mirrorFromHandle,gui::CreateSurfaceResult & outResult)5247*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::mirrorLayer(const LayerCreationArgs& args,
5248*38e8c45fSAndroid Build Coastguard Worker                                      const sp<IBinder>& mirrorFromHandle,
5249*38e8c45fSAndroid Build Coastguard Worker                                      gui::CreateSurfaceResult& outResult) {
5250*38e8c45fSAndroid Build Coastguard Worker     if (!mirrorFromHandle) {
5251*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
5252*38e8c45fSAndroid Build Coastguard Worker     }
5253*38e8c45fSAndroid Build Coastguard Worker 
5254*38e8c45fSAndroid Build Coastguard Worker     sp<Layer> mirrorLayer;
5255*38e8c45fSAndroid Build Coastguard Worker     sp<Layer> mirrorFrom;
5256*38e8c45fSAndroid Build Coastguard Worker     LayerCreationArgs mirrorArgs = LayerCreationArgs::fromOtherArgs(args);
5257*38e8c45fSAndroid Build Coastguard Worker     {
5258*38e8c45fSAndroid Build Coastguard Worker         Mutex::Autolock _l(mStateLock);
5259*38e8c45fSAndroid Build Coastguard Worker         mirrorFrom = LayerHandle::getLayer(mirrorFromHandle);
5260*38e8c45fSAndroid Build Coastguard Worker         if (!mirrorFrom) {
5261*38e8c45fSAndroid Build Coastguard Worker             return NAME_NOT_FOUND;
5262*38e8c45fSAndroid Build Coastguard Worker         }
5263*38e8c45fSAndroid Build Coastguard Worker         mirrorArgs.flags |= ISurfaceComposerClient::eNoColorFill;
5264*38e8c45fSAndroid Build Coastguard Worker         mirrorArgs.mirrorLayerHandle = mirrorFromHandle;
5265*38e8c45fSAndroid Build Coastguard Worker         mirrorArgs.addToRoot = false;
5266*38e8c45fSAndroid Build Coastguard Worker         status_t result = createEffectLayer(mirrorArgs, &outResult.handle, &mirrorLayer);
5267*38e8c45fSAndroid Build Coastguard Worker         if (result != NO_ERROR) {
5268*38e8c45fSAndroid Build Coastguard Worker             return result;
5269*38e8c45fSAndroid Build Coastguard Worker         }
5270*38e8c45fSAndroid Build Coastguard Worker     }
5271*38e8c45fSAndroid Build Coastguard Worker 
5272*38e8c45fSAndroid Build Coastguard Worker     outResult.layerId = mirrorLayer->sequence;
5273*38e8c45fSAndroid Build Coastguard Worker     outResult.layerName = String16(mirrorLayer->getDebugName());
5274*38e8c45fSAndroid Build Coastguard Worker     return addClientLayer(mirrorArgs, outResult.handle, mirrorLayer /* layer */,
5275*38e8c45fSAndroid Build Coastguard Worker                           nullptr /* parent */, nullptr /* outTransformHint */);
5276*38e8c45fSAndroid Build Coastguard Worker }
5277*38e8c45fSAndroid Build Coastguard Worker 
mirrorDisplay(DisplayId displayId,const LayerCreationArgs & args,gui::CreateSurfaceResult & outResult)5278*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::mirrorDisplay(DisplayId displayId, const LayerCreationArgs& args,
5279*38e8c45fSAndroid Build Coastguard Worker                                        gui::CreateSurfaceResult& outResult) {
5280*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
5281*38e8c45fSAndroid Build Coastguard Worker     const int uid = ipc->getCallingUid();
5282*38e8c45fSAndroid Build Coastguard Worker     if (uid != AID_ROOT && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != AID_SHELL) {
5283*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Permission denied when trying to mirror display");
5284*38e8c45fSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
5285*38e8c45fSAndroid Build Coastguard Worker     }
5286*38e8c45fSAndroid Build Coastguard Worker 
5287*38e8c45fSAndroid Build Coastguard Worker     ui::LayerStack layerStack;
5288*38e8c45fSAndroid Build Coastguard Worker     sp<Layer> rootMirrorLayer;
5289*38e8c45fSAndroid Build Coastguard Worker     status_t result = 0;
5290*38e8c45fSAndroid Build Coastguard Worker 
5291*38e8c45fSAndroid Build Coastguard Worker     {
5292*38e8c45fSAndroid Build Coastguard Worker         Mutex::Autolock lock(mStateLock);
5293*38e8c45fSAndroid Build Coastguard Worker 
5294*38e8c45fSAndroid Build Coastguard Worker         const auto display = getDisplayDeviceLocked(displayId);
5295*38e8c45fSAndroid Build Coastguard Worker         if (!display) {
5296*38e8c45fSAndroid Build Coastguard Worker             return NAME_NOT_FOUND;
5297*38e8c45fSAndroid Build Coastguard Worker         }
5298*38e8c45fSAndroid Build Coastguard Worker 
5299*38e8c45fSAndroid Build Coastguard Worker         layerStack = display->getLayerStack();
5300*38e8c45fSAndroid Build Coastguard Worker         LayerCreationArgs mirrorArgs = LayerCreationArgs::fromOtherArgs(args);
5301*38e8c45fSAndroid Build Coastguard Worker         mirrorArgs.flags |= ISurfaceComposerClient::eNoColorFill;
5302*38e8c45fSAndroid Build Coastguard Worker         mirrorArgs.addToRoot = true;
5303*38e8c45fSAndroid Build Coastguard Worker         mirrorArgs.layerStackToMirror = layerStack;
5304*38e8c45fSAndroid Build Coastguard Worker         result = createEffectLayer(mirrorArgs, &outResult.handle, &rootMirrorLayer);
5305*38e8c45fSAndroid Build Coastguard Worker         outResult.layerId = rootMirrorLayer->sequence;
5306*38e8c45fSAndroid Build Coastguard Worker         outResult.layerName = String16(rootMirrorLayer->getDebugName());
5307*38e8c45fSAndroid Build Coastguard Worker         result |= addClientLayer(mirrorArgs, outResult.handle, rootMirrorLayer /* layer */,
5308*38e8c45fSAndroid Build Coastguard Worker                                  nullptr /* parent */, nullptr /* outTransformHint */);
5309*38e8c45fSAndroid Build Coastguard Worker     }
5310*38e8c45fSAndroid Build Coastguard Worker 
5311*38e8c45fSAndroid Build Coastguard Worker     if (result != NO_ERROR) {
5312*38e8c45fSAndroid Build Coastguard Worker         return result;
5313*38e8c45fSAndroid Build Coastguard Worker     }
5314*38e8c45fSAndroid Build Coastguard Worker 
5315*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eTransactionFlushNeeded);
5316*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
5317*38e8c45fSAndroid Build Coastguard Worker }
5318*38e8c45fSAndroid Build Coastguard Worker 
createLayer(LayerCreationArgs & args,gui::CreateSurfaceResult & outResult)5319*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, gui::CreateSurfaceResult& outResult) {
5320*38e8c45fSAndroid Build Coastguard Worker     status_t result = NO_ERROR;
5321*38e8c45fSAndroid Build Coastguard Worker 
5322*38e8c45fSAndroid Build Coastguard Worker     sp<Layer> layer;
5323*38e8c45fSAndroid Build Coastguard Worker 
5324*38e8c45fSAndroid Build Coastguard Worker     switch (args.flags & ISurfaceComposerClient::eFXSurfaceMask) {
5325*38e8c45fSAndroid Build Coastguard Worker         case ISurfaceComposerClient::eFXSurfaceBufferQueue:
5326*38e8c45fSAndroid Build Coastguard Worker         case ISurfaceComposerClient::eFXSurfaceContainer:
5327*38e8c45fSAndroid Build Coastguard Worker         case ISurfaceComposerClient::eFXSurfaceBufferState:
5328*38e8c45fSAndroid Build Coastguard Worker             args.flags |= ISurfaceComposerClient::eNoColorFill;
5329*38e8c45fSAndroid Build Coastguard Worker             [[fallthrough]];
5330*38e8c45fSAndroid Build Coastguard Worker         case ISurfaceComposerClient::eFXSurfaceEffect: {
5331*38e8c45fSAndroid Build Coastguard Worker             result = createBufferStateLayer(args, &outResult.handle, &layer);
5332*38e8c45fSAndroid Build Coastguard Worker             std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter();
5333*38e8c45fSAndroid Build Coastguard Worker             if (pendingBufferCounter) {
5334*38e8c45fSAndroid Build Coastguard Worker                 std::string counterName = layer->getPendingBufferCounterName();
5335*38e8c45fSAndroid Build Coastguard Worker                 mBufferCountTracker.add(LayerHandle::getLayerId(outResult.handle), counterName,
5336*38e8c45fSAndroid Build Coastguard Worker                                         pendingBufferCounter);
5337*38e8c45fSAndroid Build Coastguard Worker                 args.pendingBuffers = pendingBufferCounter;
5338*38e8c45fSAndroid Build Coastguard Worker             }
5339*38e8c45fSAndroid Build Coastguard Worker         } break;
5340*38e8c45fSAndroid Build Coastguard Worker         default:
5341*38e8c45fSAndroid Build Coastguard Worker             result = BAD_VALUE;
5342*38e8c45fSAndroid Build Coastguard Worker             break;
5343*38e8c45fSAndroid Build Coastguard Worker     }
5344*38e8c45fSAndroid Build Coastguard Worker 
5345*38e8c45fSAndroid Build Coastguard Worker     if (result != NO_ERROR) {
5346*38e8c45fSAndroid Build Coastguard Worker         return result;
5347*38e8c45fSAndroid Build Coastguard Worker     }
5348*38e8c45fSAndroid Build Coastguard Worker 
5349*38e8c45fSAndroid Build Coastguard Worker     args.addToRoot = args.addToRoot && callingThreadHasUnscopedSurfaceFlingerAccess();
5350*38e8c45fSAndroid Build Coastguard Worker     // We can safely promote the parent layer in binder thread because we have a strong reference
5351*38e8c45fSAndroid Build Coastguard Worker     // to the layer's handle inside this scope.
5352*38e8c45fSAndroid Build Coastguard Worker     sp<Layer> parent = LayerHandle::getLayer(args.parentHandle.promote());
5353*38e8c45fSAndroid Build Coastguard Worker     if (args.parentHandle != nullptr && parent == nullptr) {
5354*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Invalid parent handle %p", args.parentHandle.promote().get());
5355*38e8c45fSAndroid Build Coastguard Worker         args.addToRoot = false;
5356*38e8c45fSAndroid Build Coastguard Worker     }
5357*38e8c45fSAndroid Build Coastguard Worker 
5358*38e8c45fSAndroid Build Coastguard Worker     uint32_t outTransformHint;
5359*38e8c45fSAndroid Build Coastguard Worker     result = addClientLayer(args, outResult.handle, layer, parent, &outTransformHint);
5360*38e8c45fSAndroid Build Coastguard Worker     if (result != NO_ERROR) {
5361*38e8c45fSAndroid Build Coastguard Worker         return result;
5362*38e8c45fSAndroid Build Coastguard Worker     }
5363*38e8c45fSAndroid Build Coastguard Worker 
5364*38e8c45fSAndroid Build Coastguard Worker     outResult.transformHint = static_cast<int32_t>(outTransformHint);
5365*38e8c45fSAndroid Build Coastguard Worker     outResult.layerId = layer->sequence;
5366*38e8c45fSAndroid Build Coastguard Worker     outResult.layerName = String16(layer->getDebugName());
5367*38e8c45fSAndroid Build Coastguard Worker     return result;
5368*38e8c45fSAndroid Build Coastguard Worker }
5369*38e8c45fSAndroid Build Coastguard Worker 
createBufferStateLayer(LayerCreationArgs & args,sp<IBinder> * handle,sp<Layer> * outLayer)5370*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::createBufferStateLayer(LayerCreationArgs& args, sp<IBinder>* handle,
5371*38e8c45fSAndroid Build Coastguard Worker                                                 sp<Layer>* outLayer) {
5372*38e8c45fSAndroid Build Coastguard Worker     *outLayer = getFactory().createBufferStateLayer(args);
5373*38e8c45fSAndroid Build Coastguard Worker     *handle = (*outLayer)->getHandle();
5374*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
5375*38e8c45fSAndroid Build Coastguard Worker }
5376*38e8c45fSAndroid Build Coastguard Worker 
createEffectLayer(const LayerCreationArgs & args,sp<IBinder> * handle,sp<Layer> * outLayer)5377*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::createEffectLayer(const LayerCreationArgs& args, sp<IBinder>* handle,
5378*38e8c45fSAndroid Build Coastguard Worker                                            sp<Layer>* outLayer) {
5379*38e8c45fSAndroid Build Coastguard Worker     *outLayer = getFactory().createEffectLayer(args);
5380*38e8c45fSAndroid Build Coastguard Worker     *handle = (*outLayer)->getHandle();
5381*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
5382*38e8c45fSAndroid Build Coastguard Worker }
5383*38e8c45fSAndroid Build Coastguard Worker 
onHandleDestroyed(sp<Layer> & layer,uint32_t layerId)5384*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onHandleDestroyed(sp<Layer>& layer, uint32_t layerId) {
5385*38e8c45fSAndroid Build Coastguard Worker     {
5386*38e8c45fSAndroid Build Coastguard Worker         // Used to remove stalled transactions which uses an internal lock.
5387*38e8c45fSAndroid Build Coastguard Worker         ftl::FakeGuard guard(kMainThreadContext);
5388*38e8c45fSAndroid Build Coastguard Worker         mTransactionHandler.onLayerDestroyed(layerId);
5389*38e8c45fSAndroid Build Coastguard Worker     }
5390*38e8c45fSAndroid Build Coastguard Worker     JankTracker::flushJankData(layerId);
5391*38e8c45fSAndroid Build Coastguard Worker 
5392*38e8c45fSAndroid Build Coastguard Worker     std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
5393*38e8c45fSAndroid Build Coastguard Worker     mDestroyedHandles.emplace_back(layerId, layer->getDebugName());
5394*38e8c45fSAndroid Build Coastguard Worker 
5395*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock stateLock(mStateLock);
5396*38e8c45fSAndroid Build Coastguard Worker     layer->onHandleDestroyed();
5397*38e8c45fSAndroid Build Coastguard Worker     mBufferCountTracker.remove(layerId);
5398*38e8c45fSAndroid Build Coastguard Worker     layer.clear();
5399*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eTransactionFlushNeeded | eTransactionNeeded);
5400*38e8c45fSAndroid Build Coastguard Worker }
5401*38e8c45fSAndroid Build Coastguard Worker 
initializeDisplays()5402*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::initializeDisplays() {
5403*38e8c45fSAndroid Build Coastguard Worker     TransactionState state;
5404*38e8c45fSAndroid Build Coastguard Worker     state.inputWindowCommands = mInputWindowCommands;
5405*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t now = systemTime();
5406*38e8c45fSAndroid Build Coastguard Worker     state.desiredPresentTime = now;
5407*38e8c45fSAndroid Build Coastguard Worker     state.postTime = now;
5408*38e8c45fSAndroid Build Coastguard Worker     state.originPid = mPid;
5409*38e8c45fSAndroid Build Coastguard Worker     state.originUid = static_cast<int>(getuid());
5410*38e8c45fSAndroid Build Coastguard Worker     const uint64_t transactionId = (static_cast<uint64_t>(mPid) << 32) | mUniqueTransactionId++;
5411*38e8c45fSAndroid Build Coastguard Worker     state.id = transactionId;
5412*38e8c45fSAndroid Build Coastguard Worker 
5413*38e8c45fSAndroid Build Coastguard Worker     auto layerStack = ui::DEFAULT_LAYER_STACK.id;
5414*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [id, display] : FTL_FAKE_GUARD(mStateLock, mPhysicalDisplays)) {
5415*38e8c45fSAndroid Build Coastguard Worker         state.displays.push(DisplayState(display.token(), ui::LayerStack::fromValue(layerStack++)));
5416*38e8c45fSAndroid Build Coastguard Worker     }
5417*38e8c45fSAndroid Build Coastguard Worker 
5418*38e8c45fSAndroid Build Coastguard Worker     std::vector<TransactionState> transactions;
5419*38e8c45fSAndroid Build Coastguard Worker     transactions.emplace_back(state);
5420*38e8c45fSAndroid Build Coastguard Worker 
5421*38e8c45fSAndroid Build Coastguard Worker     {
5422*38e8c45fSAndroid Build Coastguard Worker         Mutex::Autolock lock(mStateLock);
5423*38e8c45fSAndroid Build Coastguard Worker         applyAndCommitDisplayTransactionStatesLocked(transactions);
5424*38e8c45fSAndroid Build Coastguard Worker     }
5425*38e8c45fSAndroid Build Coastguard Worker 
5426*38e8c45fSAndroid Build Coastguard Worker     {
5427*38e8c45fSAndroid Build Coastguard Worker         ftl::FakeGuard guard(mStateLock);
5428*38e8c45fSAndroid Build Coastguard Worker 
5429*38e8c45fSAndroid Build Coastguard Worker         // In case of a restart, ensure all displays are off.
5430*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [id, display] : mPhysicalDisplays) {
5431*38e8c45fSAndroid Build Coastguard Worker             setPowerModeInternal(getDisplayDeviceLocked(id), hal::PowerMode::OFF);
5432*38e8c45fSAndroid Build Coastguard Worker         }
5433*38e8c45fSAndroid Build Coastguard Worker 
5434*38e8c45fSAndroid Build Coastguard Worker         // Power on all displays. The primary display is first, so becomes the active display. Also,
5435*38e8c45fSAndroid Build Coastguard Worker         // the DisplayCapability set of a display is populated on its first powering on. Do this now
5436*38e8c45fSAndroid Build Coastguard Worker         // before responding to any Binder query from DisplayManager about display capabilities.
5437*38e8c45fSAndroid Build Coastguard Worker         // Additionally, do not turn on displays if the boot should be quiescent.
5438*38e8c45fSAndroid Build Coastguard Worker         if (!mSkipPowerOnForQuiescent) {
5439*38e8c45fSAndroid Build Coastguard Worker             for (const auto& [id, display] : mPhysicalDisplays) {
5440*38e8c45fSAndroid Build Coastguard Worker                 setPowerModeInternal(getDisplayDeviceLocked(id), hal::PowerMode::ON);
5441*38e8c45fSAndroid Build Coastguard Worker             }
5442*38e8c45fSAndroid Build Coastguard Worker         }
5443*38e8c45fSAndroid Build Coastguard Worker     }
5444*38e8c45fSAndroid Build Coastguard Worker }
5445*38e8c45fSAndroid Build Coastguard Worker 
setPowerModeInternal(const sp<DisplayDevice> & display,hal::PowerMode mode)5446*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode) {
5447*38e8c45fSAndroid Build Coastguard Worker     if (display->isVirtual()) {
5448*38e8c45fSAndroid Build Coastguard Worker         // TODO(b/241285876): This code path should not be reachable, so enforce this at compile
5449*38e8c45fSAndroid Build Coastguard Worker         // time.
5450*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: Invalid operation on virtual display", __func__);
5451*38e8c45fSAndroid Build Coastguard Worker         return;
5452*38e8c45fSAndroid Build Coastguard Worker     }
5453*38e8c45fSAndroid Build Coastguard Worker 
5454*38e8c45fSAndroid Build Coastguard Worker     const auto displayId = display->getPhysicalId();
5455*38e8c45fSAndroid Build Coastguard Worker     ALOGD("Setting power mode %d on display %s", mode, to_string(displayId).c_str());
5456*38e8c45fSAndroid Build Coastguard Worker 
5457*38e8c45fSAndroid Build Coastguard Worker     const auto currentMode = display->getPowerMode();
5458*38e8c45fSAndroid Build Coastguard Worker     if (currentMode == mode) {
5459*38e8c45fSAndroid Build Coastguard Worker         return;
5460*38e8c45fSAndroid Build Coastguard Worker     }
5461*38e8c45fSAndroid Build Coastguard Worker 
5462*38e8c45fSAndroid Build Coastguard Worker     const bool isInternalDisplay = mPhysicalDisplays.get(displayId)
5463*38e8c45fSAndroid Build Coastguard Worker                                            .transform(&PhysicalDisplay::isInternal)
5464*38e8c45fSAndroid Build Coastguard Worker                                            .value_or(false);
5465*38e8c45fSAndroid Build Coastguard Worker 
5466*38e8c45fSAndroid Build Coastguard Worker     const auto activeDisplay = getDisplayDeviceLocked(mActiveDisplayId);
5467*38e8c45fSAndroid Build Coastguard Worker 
5468*38e8c45fSAndroid Build Coastguard Worker     ALOGW_IF(display != activeDisplay && isInternalDisplay && activeDisplay &&
5469*38e8c45fSAndroid Build Coastguard Worker                      activeDisplay->isPoweredOn(),
5470*38e8c45fSAndroid Build Coastguard Worker              "Trying to change power mode on inactive display without powering off active display");
5471*38e8c45fSAndroid Build Coastguard Worker 
5472*38e8c45fSAndroid Build Coastguard Worker     const bool couldRefresh = display->isRefreshable();
5473*38e8c45fSAndroid Build Coastguard Worker     display->setPowerMode(mode);
5474*38e8c45fSAndroid Build Coastguard Worker     const bool canRefresh = display->isRefreshable();
5475*38e8c45fSAndroid Build Coastguard Worker 
5476*38e8c45fSAndroid Build Coastguard Worker     if (couldRefresh && !canRefresh) {
5477*38e8c45fSAndroid Build Coastguard Worker         decRefreshableDisplays();
5478*38e8c45fSAndroid Build Coastguard Worker     } else if (!couldRefresh && canRefresh) {
5479*38e8c45fSAndroid Build Coastguard Worker         incRefreshableDisplays();
5480*38e8c45fSAndroid Build Coastguard Worker     }
5481*38e8c45fSAndroid Build Coastguard Worker 
5482*38e8c45fSAndroid Build Coastguard Worker     const auto activeMode = display->refreshRateSelector().getActiveMode().modePtr;
5483*38e8c45fSAndroid Build Coastguard Worker     if (currentMode == hal::PowerMode::OFF) {
5484*38e8c45fSAndroid Build Coastguard Worker         // Turn on the display
5485*38e8c45fSAndroid Build Coastguard Worker 
5486*38e8c45fSAndroid Build Coastguard Worker         // Activate the display (which involves a modeset to the active mode) when the inner or
5487*38e8c45fSAndroid Build Coastguard Worker         // outer display of a foldable is powered on. This condition relies on the above
5488*38e8c45fSAndroid Build Coastguard Worker         // DisplayDevice::setPowerMode. If `display` and `activeDisplay` are the same display,
5489*38e8c45fSAndroid Build Coastguard Worker         // then the `activeDisplay->isPoweredOn()` below is true, such that the display is not
5490*38e8c45fSAndroid Build Coastguard Worker         // activated every time it is powered on.
5491*38e8c45fSAndroid Build Coastguard Worker         //
5492*38e8c45fSAndroid Build Coastguard Worker         // TODO(b/255635821): Remove the concept of active display.
5493*38e8c45fSAndroid Build Coastguard Worker         if (isInternalDisplay && (!activeDisplay || !activeDisplay->isPoweredOn())) {
5494*38e8c45fSAndroid Build Coastguard Worker             onActiveDisplayChangedLocked(activeDisplay.get(), *display);
5495*38e8c45fSAndroid Build Coastguard Worker         }
5496*38e8c45fSAndroid Build Coastguard Worker 
5497*38e8c45fSAndroid Build Coastguard Worker         if (displayId == mActiveDisplayId) {
5498*38e8c45fSAndroid Build Coastguard Worker             // TODO(b/281692563): Merge the syscalls. For now, keep uclamp in a separate syscall and
5499*38e8c45fSAndroid Build Coastguard Worker             // set it before SCHED_FIFO due to b/190237315.
5500*38e8c45fSAndroid Build Coastguard Worker             if (setSchedAttr(true) != NO_ERROR) {
5501*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("Failed to set uclamp.min after powering on active display: %s",
5502*38e8c45fSAndroid Build Coastguard Worker                       strerror(errno));
5503*38e8c45fSAndroid Build Coastguard Worker             }
5504*38e8c45fSAndroid Build Coastguard Worker             if (setSchedFifo(true) != NO_ERROR) {
5505*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("Failed to set SCHED_FIFO after powering on active display: %s",
5506*38e8c45fSAndroid Build Coastguard Worker                       strerror(errno));
5507*38e8c45fSAndroid Build Coastguard Worker             }
5508*38e8c45fSAndroid Build Coastguard Worker         }
5509*38e8c45fSAndroid Build Coastguard Worker 
5510*38e8c45fSAndroid Build Coastguard Worker         getHwComposer().setPowerMode(displayId, mode);
5511*38e8c45fSAndroid Build Coastguard Worker         if (mode != hal::PowerMode::DOZE_SUSPEND &&
5512*38e8c45fSAndroid Build Coastguard Worker             (displayId == mActiveDisplayId || FlagManager::getInstance().multithreaded_present())) {
5513*38e8c45fSAndroid Build Coastguard Worker             const bool enable =
5514*38e8c45fSAndroid Build Coastguard Worker                     mScheduler->getVsyncSchedule(displayId)->getPendingHardwareVsyncState();
5515*38e8c45fSAndroid Build Coastguard Worker             requestHardwareVsync(displayId, enable);
5516*38e8c45fSAndroid Build Coastguard Worker 
5517*38e8c45fSAndroid Build Coastguard Worker             if (displayId == mActiveDisplayId) {
5518*38e8c45fSAndroid Build Coastguard Worker                 mScheduler->enableSyntheticVsync(false);
5519*38e8c45fSAndroid Build Coastguard Worker             }
5520*38e8c45fSAndroid Build Coastguard Worker 
5521*38e8c45fSAndroid Build Coastguard Worker             constexpr bool kAllowToEnable = true;
5522*38e8c45fSAndroid Build Coastguard Worker             mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable, activeMode.get());
5523*38e8c45fSAndroid Build Coastguard Worker         }
5524*38e8c45fSAndroid Build Coastguard Worker 
5525*38e8c45fSAndroid Build Coastguard Worker         mVisibleRegionsDirty = true;
5526*38e8c45fSAndroid Build Coastguard Worker         scheduleComposite(FrameHint::kActive);
5527*38e8c45fSAndroid Build Coastguard Worker     } else if (mode == hal::PowerMode::OFF) {
5528*38e8c45fSAndroid Build Coastguard Worker         const bool currentModeNotDozeSuspend = (currentMode != hal::PowerMode::DOZE_SUSPEND);
5529*38e8c45fSAndroid Build Coastguard Worker         // Turn off the display
5530*38e8c45fSAndroid Build Coastguard Worker         if (displayId == mActiveDisplayId) {
5531*38e8c45fSAndroid Build Coastguard Worker             if (const auto display = getActivatableDisplay()) {
5532*38e8c45fSAndroid Build Coastguard Worker                 onActiveDisplayChangedLocked(activeDisplay.get(), *display);
5533*38e8c45fSAndroid Build Coastguard Worker             } else {
5534*38e8c45fSAndroid Build Coastguard Worker                 if (setSchedFifo(false) != NO_ERROR) {
5535*38e8c45fSAndroid Build Coastguard Worker                     ALOGW("Failed to set SCHED_OTHER after powering off active display: %s",
5536*38e8c45fSAndroid Build Coastguard Worker                           strerror(errno));
5537*38e8c45fSAndroid Build Coastguard Worker                 }
5538*38e8c45fSAndroid Build Coastguard Worker                 if (setSchedAttr(false) != NO_ERROR) {
5539*38e8c45fSAndroid Build Coastguard Worker                     ALOGW("Failed set uclamp.min after powering off active display: %s",
5540*38e8c45fSAndroid Build Coastguard Worker                           strerror(errno));
5541*38e8c45fSAndroid Build Coastguard Worker                 }
5542*38e8c45fSAndroid Build Coastguard Worker 
5543*38e8c45fSAndroid Build Coastguard Worker                 if (currentModeNotDozeSuspend) {
5544*38e8c45fSAndroid Build Coastguard Worker                     if (!FlagManager::getInstance().multithreaded_present()) {
5545*38e8c45fSAndroid Build Coastguard Worker                         mScheduler->disableHardwareVsync(displayId, true);
5546*38e8c45fSAndroid Build Coastguard Worker                     }
5547*38e8c45fSAndroid Build Coastguard Worker                     mScheduler->enableSyntheticVsync();
5548*38e8c45fSAndroid Build Coastguard Worker                 }
5549*38e8c45fSAndroid Build Coastguard Worker             }
5550*38e8c45fSAndroid Build Coastguard Worker         }
5551*38e8c45fSAndroid Build Coastguard Worker         if (currentModeNotDozeSuspend && FlagManager::getInstance().multithreaded_present()) {
5552*38e8c45fSAndroid Build Coastguard Worker             constexpr bool kDisallow = true;
5553*38e8c45fSAndroid Build Coastguard Worker             mScheduler->disableHardwareVsync(displayId, kDisallow);
5554*38e8c45fSAndroid Build Coastguard Worker         }
5555*38e8c45fSAndroid Build Coastguard Worker 
5556*38e8c45fSAndroid Build Coastguard Worker         // We must disable VSYNC *before* turning off the display. The call to
5557*38e8c45fSAndroid Build Coastguard Worker         // disableHardwareVsync, above, schedules a task to turn it off after
5558*38e8c45fSAndroid Build Coastguard Worker         // this method returns. But by that point, the display is OFF, so the
5559*38e8c45fSAndroid Build Coastguard Worker         // call just updates the pending state, without actually disabling
5560*38e8c45fSAndroid Build Coastguard Worker         // VSYNC.
5561*38e8c45fSAndroid Build Coastguard Worker         requestHardwareVsync(displayId, false);
5562*38e8c45fSAndroid Build Coastguard Worker         getHwComposer().setPowerMode(displayId, mode);
5563*38e8c45fSAndroid Build Coastguard Worker 
5564*38e8c45fSAndroid Build Coastguard Worker         mVisibleRegionsDirty = true;
5565*38e8c45fSAndroid Build Coastguard Worker         // from this point on, SF will stop drawing on this display
5566*38e8c45fSAndroid Build Coastguard Worker     } else if (mode == hal::PowerMode::DOZE || mode == hal::PowerMode::ON) {
5567*38e8c45fSAndroid Build Coastguard Worker         // Update display while dozing
5568*38e8c45fSAndroid Build Coastguard Worker         getHwComposer().setPowerMode(displayId, mode);
5569*38e8c45fSAndroid Build Coastguard Worker         if (currentMode == hal::PowerMode::DOZE_SUSPEND &&
5570*38e8c45fSAndroid Build Coastguard Worker             (displayId == mActiveDisplayId || FlagManager::getInstance().multithreaded_present())) {
5571*38e8c45fSAndroid Build Coastguard Worker             if (displayId == mActiveDisplayId) {
5572*38e8c45fSAndroid Build Coastguard Worker                 ALOGI("Force repainting for DOZE_SUSPEND -> DOZE or ON.");
5573*38e8c45fSAndroid Build Coastguard Worker                 mVisibleRegionsDirty = true;
5574*38e8c45fSAndroid Build Coastguard Worker                 scheduleRepaint();
5575*38e8c45fSAndroid Build Coastguard Worker                 mScheduler->enableSyntheticVsync(false);
5576*38e8c45fSAndroid Build Coastguard Worker             }
5577*38e8c45fSAndroid Build Coastguard Worker             constexpr bool kAllowToEnable = true;
5578*38e8c45fSAndroid Build Coastguard Worker             mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable, activeMode.get());
5579*38e8c45fSAndroid Build Coastguard Worker         }
5580*38e8c45fSAndroid Build Coastguard Worker     } else if (mode == hal::PowerMode::DOZE_SUSPEND) {
5581*38e8c45fSAndroid Build Coastguard Worker         // Leave display going to doze
5582*38e8c45fSAndroid Build Coastguard Worker         if (displayId == mActiveDisplayId || FlagManager::getInstance().multithreaded_present()) {
5583*38e8c45fSAndroid Build Coastguard Worker             constexpr bool kDisallow = true;
5584*38e8c45fSAndroid Build Coastguard Worker             mScheduler->disableHardwareVsync(displayId, kDisallow);
5585*38e8c45fSAndroid Build Coastguard Worker         }
5586*38e8c45fSAndroid Build Coastguard Worker         if (displayId == mActiveDisplayId) {
5587*38e8c45fSAndroid Build Coastguard Worker             mScheduler->enableSyntheticVsync();
5588*38e8c45fSAndroid Build Coastguard Worker         }
5589*38e8c45fSAndroid Build Coastguard Worker         getHwComposer().setPowerMode(displayId, mode);
5590*38e8c45fSAndroid Build Coastguard Worker     } else {
5591*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Attempting to set unknown power mode: %d\n", mode);
5592*38e8c45fSAndroid Build Coastguard Worker         getHwComposer().setPowerMode(displayId, mode);
5593*38e8c45fSAndroid Build Coastguard Worker     }
5594*38e8c45fSAndroid Build Coastguard Worker 
5595*38e8c45fSAndroid Build Coastguard Worker     if (displayId == mActiveDisplayId) {
5596*38e8c45fSAndroid Build Coastguard Worker         mTimeStats->setPowerMode(mode);
5597*38e8c45fSAndroid Build Coastguard Worker         mScheduler->setActiveDisplayPowerModeForRefreshRateStats(mode);
5598*38e8c45fSAndroid Build Coastguard Worker     }
5599*38e8c45fSAndroid Build Coastguard Worker 
5600*38e8c45fSAndroid Build Coastguard Worker     mScheduler->setDisplayPowerMode(displayId, mode);
5601*38e8c45fSAndroid Build Coastguard Worker 
5602*38e8c45fSAndroid Build Coastguard Worker     ALOGD("Finished setting power mode %d on display %s", mode, to_string(displayId).c_str());
5603*38e8c45fSAndroid Build Coastguard Worker }
5604*38e8c45fSAndroid Build Coastguard Worker 
setPowerMode(const sp<IBinder> & displayToken,int mode)5605*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
5606*38e8c45fSAndroid Build Coastguard Worker     auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(
5607*38e8c45fSAndroid Build Coastguard Worker                                                kMainThreadContext) {
5608*38e8c45fSAndroid Build Coastguard Worker         mSkipPowerOnForQuiescent = false;
5609*38e8c45fSAndroid Build Coastguard Worker         const auto display = getDisplayDeviceLocked(displayToken);
5610*38e8c45fSAndroid Build Coastguard Worker         if (!display) {
5611*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Attempt to set power mode %d for invalid display token %p", mode,
5612*38e8c45fSAndroid Build Coastguard Worker                   displayToken.get());
5613*38e8c45fSAndroid Build Coastguard Worker         } else if (display->isVirtual()) {
5614*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Attempt to set power mode %d for virtual display", mode);
5615*38e8c45fSAndroid Build Coastguard Worker         } else {
5616*38e8c45fSAndroid Build Coastguard Worker             setPowerModeInternal(display, static_cast<hal::PowerMode>(mode));
5617*38e8c45fSAndroid Build Coastguard Worker         }
5618*38e8c45fSAndroid Build Coastguard Worker     });
5619*38e8c45fSAndroid Build Coastguard Worker 
5620*38e8c45fSAndroid Build Coastguard Worker     future.wait();
5621*38e8c45fSAndroid Build Coastguard Worker }
5622*38e8c45fSAndroid Build Coastguard Worker 
doDump(int fd,const DumpArgs & args,bool asProto)5623*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, bool asProto) {
5624*38e8c45fSAndroid Build Coastguard Worker     std::string result;
5625*38e8c45fSAndroid Build Coastguard Worker 
5626*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
5627*38e8c45fSAndroid Build Coastguard Worker     const int pid = ipc->getCallingPid();
5628*38e8c45fSAndroid Build Coastguard Worker     const int uid = ipc->getCallingUid();
5629*38e8c45fSAndroid Build Coastguard Worker 
5630*38e8c45fSAndroid Build Coastguard Worker     if ((uid != AID_SHELL) &&
5631*38e8c45fSAndroid Build Coastguard Worker             !PermissionCache::checkPermission(sDump, pid, uid)) {
5632*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&result, "Permission Denial: can't dump SurfaceFlinger from pid=%d, uid=%d\n",
5633*38e8c45fSAndroid Build Coastguard Worker                       pid, uid);
5634*38e8c45fSAndroid Build Coastguard Worker         write(fd, result.c_str(), result.size());
5635*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
5636*38e8c45fSAndroid Build Coastguard Worker     }
5637*38e8c45fSAndroid Build Coastguard Worker 
5638*38e8c45fSAndroid Build Coastguard Worker     if (asProto && args.empty()) {
5639*38e8c45fSAndroid Build Coastguard Worker         perfetto::protos::LayersTraceFileProto traceFileProto =
5640*38e8c45fSAndroid Build Coastguard Worker                 mLayerTracing.createTraceFileProto();
5641*38e8c45fSAndroid Build Coastguard Worker         perfetto::protos::LayersSnapshotProto* layersTrace = traceFileProto.add_entry();
5642*38e8c45fSAndroid Build Coastguard Worker         perfetto::protos::LayersProto layersProto = dumpProtoFromMainThread();
5643*38e8c45fSAndroid Build Coastguard Worker         layersTrace->mutable_layers()->Swap(&layersProto);
5644*38e8c45fSAndroid Build Coastguard Worker         auto displayProtos = dumpDisplayProto();
5645*38e8c45fSAndroid Build Coastguard Worker         layersTrace->mutable_displays()->Swap(&displayProtos);
5646*38e8c45fSAndroid Build Coastguard Worker         result.append(traceFileProto.SerializeAsString());
5647*38e8c45fSAndroid Build Coastguard Worker         write(fd, result.c_str(), result.size());
5648*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
5649*38e8c45fSAndroid Build Coastguard Worker     }
5650*38e8c45fSAndroid Build Coastguard Worker 
5651*38e8c45fSAndroid Build Coastguard Worker     static const std::unordered_map<std::string, Dumper> dumpers = {
5652*38e8c45fSAndroid Build Coastguard Worker             {"--comp-displays"s, dumper(&SurfaceFlinger::dumpCompositionDisplays)},
5653*38e8c45fSAndroid Build Coastguard Worker             {"--display-id"s, dumper(&SurfaceFlinger::dumpDisplayIdentificationData)},
5654*38e8c45fSAndroid Build Coastguard Worker             {"--displays"s, dumper(&SurfaceFlinger::dumpDisplays)},
5655*38e8c45fSAndroid Build Coastguard Worker             {"--edid"s, argsDumper(&SurfaceFlinger::dumpRawDisplayIdentificationData)},
5656*38e8c45fSAndroid Build Coastguard Worker             {"--events"s, dumper(&SurfaceFlinger::dumpEvents)},
5657*38e8c45fSAndroid Build Coastguard Worker             {"--frametimeline"s, argsDumper(&SurfaceFlinger::dumpFrameTimeline)},
5658*38e8c45fSAndroid Build Coastguard Worker             {"--frontend"s, mainThreadDumper(&SurfaceFlinger::dumpFrontEnd)},
5659*38e8c45fSAndroid Build Coastguard Worker             {"--hdrinfo"s, dumper(&SurfaceFlinger::dumpHdrInfo)},
5660*38e8c45fSAndroid Build Coastguard Worker             {"--hwclayers"s, mainThreadDumper(&SurfaceFlinger::dumpHwcLayersMinidump)},
5661*38e8c45fSAndroid Build Coastguard Worker             {"--latency"s, argsMainThreadDumper(&SurfaceFlinger::dumpStats)},
5662*38e8c45fSAndroid Build Coastguard Worker             {"--latency-clear"s, argsMainThreadDumper(&SurfaceFlinger::clearStats)},
5663*38e8c45fSAndroid Build Coastguard Worker             {"--list"s, mainThreadDumper(&SurfaceFlinger::listLayers)},
5664*38e8c45fSAndroid Build Coastguard Worker             {"--planner"s, argsDumper(&SurfaceFlinger::dumpPlannerInfo)},
5665*38e8c45fSAndroid Build Coastguard Worker             {"--scheduler"s, dumper(&SurfaceFlinger::dumpScheduler)},
5666*38e8c45fSAndroid Build Coastguard Worker             {"--timestats"s, protoDumper(&SurfaceFlinger::dumpTimeStats)},
5667*38e8c45fSAndroid Build Coastguard Worker             {"--vsync"s, dumper(&SurfaceFlinger::dumpVsync)},
5668*38e8c45fSAndroid Build Coastguard Worker             {"--wide-color"s, dumper(&SurfaceFlinger::dumpWideColorInfo)},
5669*38e8c45fSAndroid Build Coastguard Worker     };
5670*38e8c45fSAndroid Build Coastguard Worker 
5671*38e8c45fSAndroid Build Coastguard Worker     const auto flag = args.empty() ? ""s : std::string(String8(args[0]));
5672*38e8c45fSAndroid Build Coastguard Worker     if (const auto it = dumpers.find(flag); it != dumpers.end()) {
5673*38e8c45fSAndroid Build Coastguard Worker         (it->second)(args, asProto, result);
5674*38e8c45fSAndroid Build Coastguard Worker         write(fd, result.c_str(), result.size());
5675*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
5676*38e8c45fSAndroid Build Coastguard Worker     }
5677*38e8c45fSAndroid Build Coastguard Worker 
5678*38e8c45fSAndroid Build Coastguard Worker     // Collect debug data from main thread
5679*38e8c45fSAndroid Build Coastguard Worker     std::string compositionLayers;
5680*38e8c45fSAndroid Build Coastguard Worker     mScheduler
5681*38e8c45fSAndroid Build Coastguard Worker             ->schedule([&]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(kMainThreadContext) {
5682*38e8c45fSAndroid Build Coastguard Worker                 dumpVisibleFrontEnd(compositionLayers);
5683*38e8c45fSAndroid Build Coastguard Worker             })
5684*38e8c45fSAndroid Build Coastguard Worker             .get();
5685*38e8c45fSAndroid Build Coastguard Worker     // get window info listener data without the state lock
5686*38e8c45fSAndroid Build Coastguard Worker     auto windowInfosDebug = mWindowInfosListenerInvoker->getDebugInfo();
5687*38e8c45fSAndroid Build Coastguard Worker     compositionLayers.append("Window Infos:\n");
5688*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&compositionLayers, "  max send vsync id: %" PRId64 "\n",
5689*38e8c45fSAndroid Build Coastguard Worker                   ftl::to_underlying(windowInfosDebug.maxSendDelayVsyncId));
5690*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&compositionLayers, "  max send delay (ns): %" PRId64 " ns\n",
5691*38e8c45fSAndroid Build Coastguard Worker                   windowInfosDebug.maxSendDelayDuration);
5692*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&compositionLayers, "  unsent messages: %zu\n",
5693*38e8c45fSAndroid Build Coastguard Worker                   windowInfosDebug.pendingMessageCount);
5694*38e8c45fSAndroid Build Coastguard Worker     compositionLayers.append("\n");
5695*38e8c45fSAndroid Build Coastguard Worker     dumpAll(args, compositionLayers, result);
5696*38e8c45fSAndroid Build Coastguard Worker     write(fd, result.c_str(), result.size());
5697*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
5698*38e8c45fSAndroid Build Coastguard Worker }
5699*38e8c45fSAndroid Build Coastguard Worker 
dumpCritical(int fd,const DumpArgs &,bool asProto)5700*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::dumpCritical(int fd, const DumpArgs&, bool asProto) {
5701*38e8c45fSAndroid Build Coastguard Worker     return doDump(fd, DumpArgs(), asProto);
5702*38e8c45fSAndroid Build Coastguard Worker }
5703*38e8c45fSAndroid Build Coastguard Worker 
listLayers(std::string & result) const5704*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::listLayers(std::string& result) const {
5705*38e8c45fSAndroid Build Coastguard Worker     for (const auto& layer : mLayerLifecycleManager.getLayers()) {
5706*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&result, "%s\n", layer->getDebugString().c_str());
5707*38e8c45fSAndroid Build Coastguard Worker     }
5708*38e8c45fSAndroid Build Coastguard Worker }
5709*38e8c45fSAndroid Build Coastguard Worker 
dumpStats(const DumpArgs & args,std::string & result) const5710*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpStats(const DumpArgs& args, std::string& result) const {
5711*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "%" PRId64 "\n", mScheduler->getPacesetterVsyncPeriod().ns());
5712*38e8c45fSAndroid Build Coastguard Worker     if (args.size() < 2) return;
5713*38e8c45fSAndroid Build Coastguard Worker 
5714*38e8c45fSAndroid Build Coastguard Worker     const auto name = String8(args[1]);
5715*38e8c45fSAndroid Build Coastguard Worker     traverseLegacyLayers([&](Layer* layer) {
5716*38e8c45fSAndroid Build Coastguard Worker         if (layer->getName() == name.c_str()) {
5717*38e8c45fSAndroid Build Coastguard Worker             layer->dumpFrameStats(result);
5718*38e8c45fSAndroid Build Coastguard Worker         }
5719*38e8c45fSAndroid Build Coastguard Worker     });
5720*38e8c45fSAndroid Build Coastguard Worker }
5721*38e8c45fSAndroid Build Coastguard Worker 
clearStats(const DumpArgs & args,std::string &)5722*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::clearStats(const DumpArgs& args, std::string&) {
5723*38e8c45fSAndroid Build Coastguard Worker     const bool clearAll = args.size() < 2;
5724*38e8c45fSAndroid Build Coastguard Worker     const auto name = clearAll ? String8() : String8(args[1]);
5725*38e8c45fSAndroid Build Coastguard Worker 
5726*38e8c45fSAndroid Build Coastguard Worker     traverseLegacyLayers([&](Layer* layer) {
5727*38e8c45fSAndroid Build Coastguard Worker         if (clearAll || layer->getName() == name.c_str()) {
5728*38e8c45fSAndroid Build Coastguard Worker             layer->clearFrameStats();
5729*38e8c45fSAndroid Build Coastguard Worker         }
5730*38e8c45fSAndroid Build Coastguard Worker     });
5731*38e8c45fSAndroid Build Coastguard Worker }
5732*38e8c45fSAndroid Build Coastguard Worker 
dumpTimeStats(const DumpArgs & args,bool asProto,std::string & result) const5733*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpTimeStats(const DumpArgs& args, bool asProto, std::string& result) const {
5734*38e8c45fSAndroid Build Coastguard Worker     mTimeStats->parseArgs(asProto, args, result);
5735*38e8c45fSAndroid Build Coastguard Worker }
5736*38e8c45fSAndroid Build Coastguard Worker 
dumpFrameTimeline(const DumpArgs & args,std::string & result) const5737*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpFrameTimeline(const DumpArgs& args, std::string& result) const {
5738*38e8c45fSAndroid Build Coastguard Worker     mFrameTimeline->parseArgs(args, result);
5739*38e8c45fSAndroid Build Coastguard Worker }
5740*38e8c45fSAndroid Build Coastguard Worker 
logFrameStats(TimePoint now)5741*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::logFrameStats(TimePoint now) {
5742*38e8c45fSAndroid Build Coastguard Worker     static TimePoint sTimestamp = now;
5743*38e8c45fSAndroid Build Coastguard Worker     if (now - sTimestamp < 30min) return;
5744*38e8c45fSAndroid Build Coastguard Worker     sTimestamp = now;
5745*38e8c45fSAndroid Build Coastguard Worker 
5746*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
5747*38e8c45fSAndroid Build Coastguard Worker     traverseLegacyLayers([&](Layer* layer) { layer->logFrameStats(); });
5748*38e8c45fSAndroid Build Coastguard Worker }
5749*38e8c45fSAndroid Build Coastguard Worker 
appendSfConfigString(std::string & result) const5750*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::appendSfConfigString(std::string& result) const {
5751*38e8c45fSAndroid Build Coastguard Worker     result.append(" [sf");
5752*38e8c45fSAndroid Build Coastguard Worker 
5753*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, " PRESENT_TIME_OFFSET=%" PRId64, dispSyncPresentTimeOffset);
5754*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, " FORCE_HWC_FOR_RBG_TO_YUV=%d", useHwcForRgbToYuv);
5755*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, " MAX_VIRT_DISPLAY_DIM=%zu",
5756*38e8c45fSAndroid Build Coastguard Worker                   getHwComposer().getMaxVirtualDisplayDimension());
5757*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, " RUNNING_WITHOUT_SYNC_FRAMEWORK=%d", !hasSyncFramework);
5758*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, " NUM_FRAMEBUFFER_SURFACE_BUFFERS=%" PRId64,
5759*38e8c45fSAndroid Build Coastguard Worker                   maxFrameBufferAcquiredBuffers);
5760*38e8c45fSAndroid Build Coastguard Worker     result.append("]");
5761*38e8c45fSAndroid Build Coastguard Worker }
5762*38e8c45fSAndroid Build Coastguard Worker 
dumpScheduler(std::string & result) const5763*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpScheduler(std::string& result) const {
5764*38e8c45fSAndroid Build Coastguard Worker     utils::Dumper dumper{result};
5765*38e8c45fSAndroid Build Coastguard Worker 
5766*38e8c45fSAndroid Build Coastguard Worker     mScheduler->dump(dumper);
5767*38e8c45fSAndroid Build Coastguard Worker 
5768*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/241285876): Move to DisplayModeController.
5769*38e8c45fSAndroid Build Coastguard Worker     dumper.dump("debugDisplayModeSetByBackdoor"sv, mDebugDisplayModeSetByBackdoor);
5770*38e8c45fSAndroid Build Coastguard Worker     dumper.eol();
5771*38e8c45fSAndroid Build Coastguard Worker }
5772*38e8c45fSAndroid Build Coastguard Worker 
dumpEvents(std::string & result) const5773*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpEvents(std::string& result) const {
5774*38e8c45fSAndroid Build Coastguard Worker     mScheduler->dump(scheduler::Cycle::Render, result);
5775*38e8c45fSAndroid Build Coastguard Worker }
5776*38e8c45fSAndroid Build Coastguard Worker 
dumpVsync(std::string & result) const5777*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpVsync(std::string& result) const {
5778*38e8c45fSAndroid Build Coastguard Worker     mScheduler->dumpVsync(result);
5779*38e8c45fSAndroid Build Coastguard Worker }
5780*38e8c45fSAndroid Build Coastguard Worker 
dumpPlannerInfo(const DumpArgs & args,std::string & result) const5781*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpPlannerInfo(const DumpArgs& args, std::string& result) const {
5782*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [token, display] : mDisplays) {
5783*38e8c45fSAndroid Build Coastguard Worker         const auto compositionDisplay = display->getCompositionDisplay();
5784*38e8c45fSAndroid Build Coastguard Worker         compositionDisplay->dumpPlannerInfo(args, result);
5785*38e8c45fSAndroid Build Coastguard Worker     }
5786*38e8c45fSAndroid Build Coastguard Worker }
5787*38e8c45fSAndroid Build Coastguard Worker 
dumpCompositionDisplays(std::string & result) const5788*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpCompositionDisplays(std::string& result) const {
5789*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [token, display] : mDisplays) {
5790*38e8c45fSAndroid Build Coastguard Worker         display->getCompositionDisplay()->dump(result);
5791*38e8c45fSAndroid Build Coastguard Worker         result += '\n';
5792*38e8c45fSAndroid Build Coastguard Worker     }
5793*38e8c45fSAndroid Build Coastguard Worker }
5794*38e8c45fSAndroid Build Coastguard Worker 
dumpDisplays(std::string & result) const5795*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpDisplays(std::string& result) const {
5796*38e8c45fSAndroid Build Coastguard Worker     utils::Dumper dumper{result};
5797*38e8c45fSAndroid Build Coastguard Worker 
5798*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [id, display] : mPhysicalDisplays) {
5799*38e8c45fSAndroid Build Coastguard Worker         utils::Dumper::Section section(dumper, ftl::Concat("Display ", id.value).str());
5800*38e8c45fSAndroid Build Coastguard Worker 
5801*38e8c45fSAndroid Build Coastguard Worker         display.snapshot().dump(dumper);
5802*38e8c45fSAndroid Build Coastguard Worker 
5803*38e8c45fSAndroid Build Coastguard Worker         if (const auto device = getDisplayDeviceLocked(id)) {
5804*38e8c45fSAndroid Build Coastguard Worker             device->dump(dumper);
5805*38e8c45fSAndroid Build Coastguard Worker         }
5806*38e8c45fSAndroid Build Coastguard Worker     }
5807*38e8c45fSAndroid Build Coastguard Worker 
5808*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [token, display] : mDisplays) {
5809*38e8c45fSAndroid Build Coastguard Worker         if (display->isVirtual()) {
5810*38e8c45fSAndroid Build Coastguard Worker             const auto displayId = display->getId();
5811*38e8c45fSAndroid Build Coastguard Worker             utils::Dumper::Section section(dumper,
5812*38e8c45fSAndroid Build Coastguard Worker                                            ftl::Concat("Virtual Display ", displayId.value).str());
5813*38e8c45fSAndroid Build Coastguard Worker             display->dump(dumper);
5814*38e8c45fSAndroid Build Coastguard Worker 
5815*38e8c45fSAndroid Build Coastguard Worker             if (const auto virtualIdOpt = VirtualDisplayId::tryCast(displayId)) {
5816*38e8c45fSAndroid Build Coastguard Worker                 std::lock_guard lock(mVirtualDisplaysMutex);
5817*38e8c45fSAndroid Build Coastguard Worker                 const auto virtualSnapshotIt = mVirtualDisplays.find(virtualIdOpt.value());
5818*38e8c45fSAndroid Build Coastguard Worker                 if (virtualSnapshotIt != mVirtualDisplays.end()) {
5819*38e8c45fSAndroid Build Coastguard Worker                     virtualSnapshotIt->second.dump(dumper);
5820*38e8c45fSAndroid Build Coastguard Worker                 }
5821*38e8c45fSAndroid Build Coastguard Worker             }
5822*38e8c45fSAndroid Build Coastguard Worker         }
5823*38e8c45fSAndroid Build Coastguard Worker     }
5824*38e8c45fSAndroid Build Coastguard Worker }
5825*38e8c45fSAndroid Build Coastguard Worker 
dumpDisplayIdentificationData(std::string & result) const5826*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpDisplayIdentificationData(std::string& result) const {
5827*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [token, display] : mDisplays) {
5828*38e8c45fSAndroid Build Coastguard Worker         const auto displayId = PhysicalDisplayId::tryCast(display->getId());
5829*38e8c45fSAndroid Build Coastguard Worker         if (!displayId) {
5830*38e8c45fSAndroid Build Coastguard Worker             continue;
5831*38e8c45fSAndroid Build Coastguard Worker         }
5832*38e8c45fSAndroid Build Coastguard Worker         const auto hwcDisplayId = getHwComposer().fromPhysicalDisplayId(*displayId);
5833*38e8c45fSAndroid Build Coastguard Worker         if (!hwcDisplayId) {
5834*38e8c45fSAndroid Build Coastguard Worker             continue;
5835*38e8c45fSAndroid Build Coastguard Worker         }
5836*38e8c45fSAndroid Build Coastguard Worker 
5837*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&result,
5838*38e8c45fSAndroid Build Coastguard Worker                       "Display %s (HWC display %" PRIu64 "): ", to_string(*displayId).c_str(),
5839*38e8c45fSAndroid Build Coastguard Worker                       *hwcDisplayId);
5840*38e8c45fSAndroid Build Coastguard Worker         uint8_t port;
5841*38e8c45fSAndroid Build Coastguard Worker         DisplayIdentificationData data;
5842*38e8c45fSAndroid Build Coastguard Worker         if (!getHwComposer().getDisplayIdentificationData(*hwcDisplayId, &port, &data)) {
5843*38e8c45fSAndroid Build Coastguard Worker             result.append("no display identification data\n");
5844*38e8c45fSAndroid Build Coastguard Worker             continue;
5845*38e8c45fSAndroid Build Coastguard Worker         }
5846*38e8c45fSAndroid Build Coastguard Worker 
5847*38e8c45fSAndroid Build Coastguard Worker         if (data.empty()) {
5848*38e8c45fSAndroid Build Coastguard Worker             result.append("empty display identification data\n");
5849*38e8c45fSAndroid Build Coastguard Worker             continue;
5850*38e8c45fSAndroid Build Coastguard Worker         }
5851*38e8c45fSAndroid Build Coastguard Worker 
5852*38e8c45fSAndroid Build Coastguard Worker         if (!isEdid(data)) {
5853*38e8c45fSAndroid Build Coastguard Worker             result.append("unknown format for display identification data\n");
5854*38e8c45fSAndroid Build Coastguard Worker             continue;
5855*38e8c45fSAndroid Build Coastguard Worker         }
5856*38e8c45fSAndroid Build Coastguard Worker 
5857*38e8c45fSAndroid Build Coastguard Worker         const auto edid = parseEdid(data);
5858*38e8c45fSAndroid Build Coastguard Worker         if (!edid) {
5859*38e8c45fSAndroid Build Coastguard Worker             result.append("invalid EDID\n");
5860*38e8c45fSAndroid Build Coastguard Worker             continue;
5861*38e8c45fSAndroid Build Coastguard Worker         }
5862*38e8c45fSAndroid Build Coastguard Worker 
5863*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&result, "port=%u pnpId=%s displayName=\"", port, edid->pnpId.data());
5864*38e8c45fSAndroid Build Coastguard Worker         result.append(edid->displayName.data(), edid->displayName.length());
5865*38e8c45fSAndroid Build Coastguard Worker         result.append("\"\n");
5866*38e8c45fSAndroid Build Coastguard Worker     }
5867*38e8c45fSAndroid Build Coastguard Worker }
5868*38e8c45fSAndroid Build Coastguard Worker 
dumpRawDisplayIdentificationData(const DumpArgs & args,std::string & result) const5869*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpRawDisplayIdentificationData(const DumpArgs& args,
5870*38e8c45fSAndroid Build Coastguard Worker                                                       std::string& result) const {
5871*38e8c45fSAndroid Build Coastguard Worker     hal::HWDisplayId hwcDisplayId;
5872*38e8c45fSAndroid Build Coastguard Worker     uint8_t port;
5873*38e8c45fSAndroid Build Coastguard Worker     DisplayIdentificationData data;
5874*38e8c45fSAndroid Build Coastguard Worker 
5875*38e8c45fSAndroid Build Coastguard Worker     if (args.size() > 1 && base::ParseUint(String8(args[1]), &hwcDisplayId) &&
5876*38e8c45fSAndroid Build Coastguard Worker         getHwComposer().getDisplayIdentificationData(hwcDisplayId, &port, &data)) {
5877*38e8c45fSAndroid Build Coastguard Worker         result.append(reinterpret_cast<const char*>(data.data()), data.size());
5878*38e8c45fSAndroid Build Coastguard Worker     }
5879*38e8c45fSAndroid Build Coastguard Worker }
5880*38e8c45fSAndroid Build Coastguard Worker 
dumpWideColorInfo(std::string & result) const5881*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpWideColorInfo(std::string& result) const {
5882*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "Device supports wide color: %d\n", mSupportsWideColor);
5883*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "DisplayColorSetting: %s\n",
5884*38e8c45fSAndroid Build Coastguard Worker                   decodeDisplayColorSetting(mDisplayColorSetting).c_str());
5885*38e8c45fSAndroid Build Coastguard Worker 
5886*38e8c45fSAndroid Build Coastguard Worker     // TODO: print out if wide-color mode is active or not.
5887*38e8c45fSAndroid Build Coastguard Worker 
5888*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [id, display] : mPhysicalDisplays) {
5889*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&result, "Display %s color modes:\n", to_string(id).c_str());
5890*38e8c45fSAndroid Build Coastguard Worker         for (const auto mode : display.snapshot().colorModes()) {
5891*38e8c45fSAndroid Build Coastguard Worker             StringAppendF(&result, "    %s (%d)\n", decodeColorMode(mode).c_str(),
5892*38e8c45fSAndroid Build Coastguard Worker                           fmt::underlying(mode));
5893*38e8c45fSAndroid Build Coastguard Worker         }
5894*38e8c45fSAndroid Build Coastguard Worker 
5895*38e8c45fSAndroid Build Coastguard Worker         if (const auto display = getDisplayDeviceLocked(id)) {
5896*38e8c45fSAndroid Build Coastguard Worker             ui::ColorMode currentMode = display->getCompositionDisplay()->getState().colorMode;
5897*38e8c45fSAndroid Build Coastguard Worker             StringAppendF(&result, "    Current color mode: %s (%d)\n",
5898*38e8c45fSAndroid Build Coastguard Worker                           decodeColorMode(currentMode).c_str(), fmt::underlying(currentMode));
5899*38e8c45fSAndroid Build Coastguard Worker         }
5900*38e8c45fSAndroid Build Coastguard Worker     }
5901*38e8c45fSAndroid Build Coastguard Worker     result.append("\n");
5902*38e8c45fSAndroid Build Coastguard Worker }
5903*38e8c45fSAndroid Build Coastguard Worker 
dumpHdrInfo(std::string & result) const5904*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpHdrInfo(std::string& result) const {
5905*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [displayId, listener] : mHdrLayerInfoListeners) {
5906*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&result, "HDR events for display %" PRIu64 "\n", displayId.value);
5907*38e8c45fSAndroid Build Coastguard Worker         listener->dump(result);
5908*38e8c45fSAndroid Build Coastguard Worker         result.append("\n");
5909*38e8c45fSAndroid Build Coastguard Worker     }
5910*38e8c45fSAndroid Build Coastguard Worker }
5911*38e8c45fSAndroid Build Coastguard Worker 
dumpFrontEnd(std::string & result)5912*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpFrontEnd(std::string& result) {
5913*38e8c45fSAndroid Build Coastguard Worker     std::ostringstream out;
5914*38e8c45fSAndroid Build Coastguard Worker     out << "\nComposition list (bottom to top)\n";
5915*38e8c45fSAndroid Build Coastguard Worker     ui::LayerStack lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
5916*38e8c45fSAndroid Build Coastguard Worker     for (const auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) {
5917*38e8c45fSAndroid Build Coastguard Worker         if (lastPrintedLayerStackHeader != snapshot->outputFilter.layerStack) {
5918*38e8c45fSAndroid Build Coastguard Worker             lastPrintedLayerStackHeader = snapshot->outputFilter.layerStack;
5919*38e8c45fSAndroid Build Coastguard Worker             out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
5920*38e8c45fSAndroid Build Coastguard Worker         }
5921*38e8c45fSAndroid Build Coastguard Worker         out << "  " << *snapshot << "\n";
5922*38e8c45fSAndroid Build Coastguard Worker     }
5923*38e8c45fSAndroid Build Coastguard Worker 
5924*38e8c45fSAndroid Build Coastguard Worker     out << "\nInput list\n";
5925*38e8c45fSAndroid Build Coastguard Worker     lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
5926*38e8c45fSAndroid Build Coastguard Worker     mLayerSnapshotBuilder.forEachInputSnapshot([&](const frontend::LayerSnapshot& snapshot) {
5927*38e8c45fSAndroid Build Coastguard Worker         if (lastPrintedLayerStackHeader != snapshot.outputFilter.layerStack) {
5928*38e8c45fSAndroid Build Coastguard Worker             lastPrintedLayerStackHeader = snapshot.outputFilter.layerStack;
5929*38e8c45fSAndroid Build Coastguard Worker             out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
5930*38e8c45fSAndroid Build Coastguard Worker         }
5931*38e8c45fSAndroid Build Coastguard Worker         out << "  " << snapshot << "\n";
5932*38e8c45fSAndroid Build Coastguard Worker     });
5933*38e8c45fSAndroid Build Coastguard Worker 
5934*38e8c45fSAndroid Build Coastguard Worker     out << "\nLayer Hierarchy\n"
5935*38e8c45fSAndroid Build Coastguard Worker         << mLayerHierarchyBuilder.getHierarchy().dump() << "\nOffscreen Hierarchy\n"
5936*38e8c45fSAndroid Build Coastguard Worker         << mLayerHierarchyBuilder.getOffscreenHierarchy().dump() << "\n\n";
5937*38e8c45fSAndroid Build Coastguard Worker     result.append(out.str());
5938*38e8c45fSAndroid Build Coastguard Worker }
5939*38e8c45fSAndroid Build Coastguard Worker 
dumpVisibleFrontEnd(std::string & result)5940*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpVisibleFrontEnd(std::string& result) {
5941*38e8c45fSAndroid Build Coastguard Worker     std::ostringstream out;
5942*38e8c45fSAndroid Build Coastguard Worker     out << "\nComposition list (bottom to top)\n";
5943*38e8c45fSAndroid Build Coastguard Worker     ui::LayerStack lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
5944*38e8c45fSAndroid Build Coastguard Worker     mLayerSnapshotBuilder.forEachVisibleSnapshot(
5945*38e8c45fSAndroid Build Coastguard Worker             [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) {
5946*38e8c45fSAndroid Build Coastguard Worker                 if (snapshot->hasSomethingToDraw()) {
5947*38e8c45fSAndroid Build Coastguard Worker                     if (lastPrintedLayerStackHeader != snapshot->outputFilter.layerStack) {
5948*38e8c45fSAndroid Build Coastguard Worker                         lastPrintedLayerStackHeader = snapshot->outputFilter.layerStack;
5949*38e8c45fSAndroid Build Coastguard Worker                         out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
5950*38e8c45fSAndroid Build Coastguard Worker                     }
5951*38e8c45fSAndroid Build Coastguard Worker                     out << "  " << *snapshot << "\n";
5952*38e8c45fSAndroid Build Coastguard Worker                 }
5953*38e8c45fSAndroid Build Coastguard Worker             });
5954*38e8c45fSAndroid Build Coastguard Worker 
5955*38e8c45fSAndroid Build Coastguard Worker     out << "\nInput list\n";
5956*38e8c45fSAndroid Build Coastguard Worker     lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
5957*38e8c45fSAndroid Build Coastguard Worker     mLayerSnapshotBuilder.forEachInputSnapshot([&](const frontend::LayerSnapshot& snapshot) {
5958*38e8c45fSAndroid Build Coastguard Worker         if (lastPrintedLayerStackHeader != snapshot.outputFilter.layerStack) {
5959*38e8c45fSAndroid Build Coastguard Worker             lastPrintedLayerStackHeader = snapshot.outputFilter.layerStack;
5960*38e8c45fSAndroid Build Coastguard Worker             out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
5961*38e8c45fSAndroid Build Coastguard Worker         }
5962*38e8c45fSAndroid Build Coastguard Worker         out << "  " << snapshot << "\n";
5963*38e8c45fSAndroid Build Coastguard Worker     });
5964*38e8c45fSAndroid Build Coastguard Worker 
5965*38e8c45fSAndroid Build Coastguard Worker     out << "\nLayer Hierarchy\n"
5966*38e8c45fSAndroid Build Coastguard Worker         << mLayerHierarchyBuilder.getHierarchy() << "\nOffscreen Hierarchy\n"
5967*38e8c45fSAndroid Build Coastguard Worker         << mLayerHierarchyBuilder.getOffscreenHierarchy() << "\n\n";
5968*38e8c45fSAndroid Build Coastguard Worker     result = out.str();
5969*38e8c45fSAndroid Build Coastguard Worker     dumpHwcLayersMinidump(result);
5970*38e8c45fSAndroid Build Coastguard Worker }
5971*38e8c45fSAndroid Build Coastguard Worker 
dumpDrawingStateProto(uint32_t traceFlags) const5972*38e8c45fSAndroid Build Coastguard Worker perfetto::protos::LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {
5973*38e8c45fSAndroid Build Coastguard Worker     std::unordered_set<uint64_t> stackIdsToSkip;
5974*38e8c45fSAndroid Build Coastguard Worker 
5975*38e8c45fSAndroid Build Coastguard Worker     // Determine if virtual layers display should be skipped
5976*38e8c45fSAndroid Build Coastguard Worker     if ((traceFlags & LayerTracing::TRACE_VIRTUAL_DISPLAYS) == 0) {
5977*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
5978*38e8c45fSAndroid Build Coastguard Worker             if (display->isVirtual()) {
5979*38e8c45fSAndroid Build Coastguard Worker                 stackIdsToSkip.insert(display->getLayerStack().id);
5980*38e8c45fSAndroid Build Coastguard Worker             }
5981*38e8c45fSAndroid Build Coastguard Worker         }
5982*38e8c45fSAndroid Build Coastguard Worker     }
5983*38e8c45fSAndroid Build Coastguard Worker 
5984*38e8c45fSAndroid Build Coastguard Worker     auto traceGenerator =
5985*38e8c45fSAndroid Build Coastguard Worker             LayerProtoFromSnapshotGenerator(mLayerSnapshotBuilder, mFrontEndDisplayInfos,
5986*38e8c45fSAndroid Build Coastguard Worker                                             mLegacyLayers, traceFlags)
5987*38e8c45fSAndroid Build Coastguard Worker                     .with(mLayerHierarchyBuilder.getHierarchy());
5988*38e8c45fSAndroid Build Coastguard Worker 
5989*38e8c45fSAndroid Build Coastguard Worker     if (traceFlags & LayerTracing::Flag::TRACE_EXTRA) {
5990*38e8c45fSAndroid Build Coastguard Worker         traceGenerator.withOffscreenLayers(mLayerHierarchyBuilder.getOffscreenHierarchy());
5991*38e8c45fSAndroid Build Coastguard Worker     }
5992*38e8c45fSAndroid Build Coastguard Worker 
5993*38e8c45fSAndroid Build Coastguard Worker     return traceGenerator.generate();
5994*38e8c45fSAndroid Build Coastguard Worker }
5995*38e8c45fSAndroid Build Coastguard Worker 
5996*38e8c45fSAndroid Build Coastguard Worker google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto>
dumpDisplayProto() const5997*38e8c45fSAndroid Build Coastguard Worker SurfaceFlinger::dumpDisplayProto() const {
5998*38e8c45fSAndroid Build Coastguard Worker     google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto> displays;
5999*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
6000*38e8c45fSAndroid Build Coastguard Worker         perfetto::protos::DisplayProto* displayProto = displays.Add();
6001*38e8c45fSAndroid Build Coastguard Worker         displayProto->set_id(display->getId().value);
6002*38e8c45fSAndroid Build Coastguard Worker         displayProto->set_name(display->getDisplayName());
6003*38e8c45fSAndroid Build Coastguard Worker         displayProto->set_layer_stack(display->getLayerStack().id);
6004*38e8c45fSAndroid Build Coastguard Worker 
6005*38e8c45fSAndroid Build Coastguard Worker         if (!display->isVirtual()) {
6006*38e8c45fSAndroid Build Coastguard Worker             const auto dpi = display->refreshRateSelector().getActiveMode().modePtr->getDpi();
6007*38e8c45fSAndroid Build Coastguard Worker             displayProto->set_dpi_x(dpi.x);
6008*38e8c45fSAndroid Build Coastguard Worker             displayProto->set_dpi_y(dpi.y);
6009*38e8c45fSAndroid Build Coastguard Worker         }
6010*38e8c45fSAndroid Build Coastguard Worker 
6011*38e8c45fSAndroid Build Coastguard Worker         LayerProtoHelper::writeSizeToProto(display->getWidth(), display->getHeight(),
6012*38e8c45fSAndroid Build Coastguard Worker                                            [&]() { return displayProto->mutable_size(); });
6013*38e8c45fSAndroid Build Coastguard Worker         LayerProtoHelper::writeToProto(display->getLayerStackSpaceRect(), [&]() {
6014*38e8c45fSAndroid Build Coastguard Worker             return displayProto->mutable_layer_stack_space_rect();
6015*38e8c45fSAndroid Build Coastguard Worker         });
6016*38e8c45fSAndroid Build Coastguard Worker         LayerProtoHelper::writeTransformToProto(display->getTransform(),
6017*38e8c45fSAndroid Build Coastguard Worker                                                 displayProto->mutable_transform());
6018*38e8c45fSAndroid Build Coastguard Worker         displayProto->set_is_virtual(display->isVirtual());
6019*38e8c45fSAndroid Build Coastguard Worker     }
6020*38e8c45fSAndroid Build Coastguard Worker     return displays;
6021*38e8c45fSAndroid Build Coastguard Worker }
6022*38e8c45fSAndroid Build Coastguard Worker 
dumpHwc(std::string & result) const6023*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpHwc(std::string& result) const {
6024*38e8c45fSAndroid Build Coastguard Worker     getHwComposer().dump(result);
6025*38e8c45fSAndroid Build Coastguard Worker }
6026*38e8c45fSAndroid Build Coastguard Worker 
dumpProtoFromMainThread(uint32_t traceFlags)6027*38e8c45fSAndroid Build Coastguard Worker perfetto::protos::LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) {
6028*38e8c45fSAndroid Build Coastguard Worker     return mScheduler
6029*38e8c45fSAndroid Build Coastguard Worker             ->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) {
6030*38e8c45fSAndroid Build Coastguard Worker                 return dumpDrawingStateProto(traceFlags);
6031*38e8c45fSAndroid Build Coastguard Worker             })
6032*38e8c45fSAndroid Build Coastguard Worker             .get();
6033*38e8c45fSAndroid Build Coastguard Worker }
6034*38e8c45fSAndroid Build Coastguard Worker 
dumpHwcLayersMinidump(std::string & result) const6035*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpHwcLayersMinidump(std::string& result) const {
6036*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [token, display] : mDisplays) {
6037*38e8c45fSAndroid Build Coastguard Worker         const auto displayId = HalDisplayId::tryCast(display->getId());
6038*38e8c45fSAndroid Build Coastguard Worker         if (!displayId) {
6039*38e8c45fSAndroid Build Coastguard Worker             continue;
6040*38e8c45fSAndroid Build Coastguard Worker         }
6041*38e8c45fSAndroid Build Coastguard Worker 
6042*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&result, "Display %s (%s) HWC layers:\n", to_string(*displayId).c_str(),
6043*38e8c45fSAndroid Build Coastguard Worker                       displayId == mActiveDisplayId ? "active" : "inactive");
6044*38e8c45fSAndroid Build Coastguard Worker         Layer::miniDumpHeader(result);
6045*38e8c45fSAndroid Build Coastguard Worker 
6046*38e8c45fSAndroid Build Coastguard Worker         const DisplayDevice& ref = *display;
6047*38e8c45fSAndroid Build Coastguard Worker         mLayerSnapshotBuilder.forEachVisibleSnapshot(
6048*38e8c45fSAndroid Build Coastguard Worker                 [&](const frontend::LayerSnapshot& snapshot) FTL_FAKE_GUARD(kMainThreadContext) {
6049*38e8c45fSAndroid Build Coastguard Worker                     if (!snapshot.hasSomethingToDraw() ||
6050*38e8c45fSAndroid Build Coastguard Worker                         ref.getLayerStack() != snapshot.outputFilter.layerStack) {
6051*38e8c45fSAndroid Build Coastguard Worker                         return;
6052*38e8c45fSAndroid Build Coastguard Worker                     }
6053*38e8c45fSAndroid Build Coastguard Worker                     auto it = mLegacyLayers.find(snapshot.sequence);
6054*38e8c45fSAndroid Build Coastguard Worker                     LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
6055*38e8c45fSAndroid Build Coastguard Worker                                                     "Couldnt find layer object for %s",
6056*38e8c45fSAndroid Build Coastguard Worker                                                     snapshot.getDebugString().c_str());
6057*38e8c45fSAndroid Build Coastguard Worker                     it->second->miniDump(result, snapshot, ref);
6058*38e8c45fSAndroid Build Coastguard Worker                 });
6059*38e8c45fSAndroid Build Coastguard Worker         result.append("\n");
6060*38e8c45fSAndroid Build Coastguard Worker     }
6061*38e8c45fSAndroid Build Coastguard Worker }
6062*38e8c45fSAndroid Build Coastguard Worker 
dumpAll(const DumpArgs & args,const std::string & compositionLayers,std::string & result) const6063*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::dumpAll(const DumpArgs& args, const std::string& compositionLayers,
6064*38e8c45fSAndroid Build Coastguard Worker                              std::string& result) const {
6065*38e8c45fSAndroid Build Coastguard Worker     TimedLock lock(mStateLock, s2ns(1), __func__);
6066*38e8c45fSAndroid Build Coastguard Worker     if (!lock.locked()) {
6067*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&result, "Dumping without lock after timeout: %s (%d)\n",
6068*38e8c45fSAndroid Build Coastguard Worker                       strerror(-lock.status), lock.status);
6069*38e8c45fSAndroid Build Coastguard Worker     }
6070*38e8c45fSAndroid Build Coastguard Worker 
6071*38e8c45fSAndroid Build Coastguard Worker     const bool colorize = !args.empty() && args[0] == String16("--color");
6072*38e8c45fSAndroid Build Coastguard Worker     Colorizer colorizer(colorize);
6073*38e8c45fSAndroid Build Coastguard Worker 
6074*38e8c45fSAndroid Build Coastguard Worker     // figure out if we're stuck somewhere
6075*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t now = systemTime();
6076*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t inTransaction(mDebugInTransaction);
6077*38e8c45fSAndroid Build Coastguard Worker     nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
6078*38e8c45fSAndroid Build Coastguard Worker 
6079*38e8c45fSAndroid Build Coastguard Worker     /*
6080*38e8c45fSAndroid Build Coastguard Worker      * Dump library configuration.
6081*38e8c45fSAndroid Build Coastguard Worker      */
6082*38e8c45fSAndroid Build Coastguard Worker 
6083*38e8c45fSAndroid Build Coastguard Worker     colorizer.bold(result);
6084*38e8c45fSAndroid Build Coastguard Worker     result.append("Build configuration:");
6085*38e8c45fSAndroid Build Coastguard Worker     colorizer.reset(result);
6086*38e8c45fSAndroid Build Coastguard Worker     appendSfConfigString(result);
6087*38e8c45fSAndroid Build Coastguard Worker     result.append("\n");
6088*38e8c45fSAndroid Build Coastguard Worker 
6089*38e8c45fSAndroid Build Coastguard Worker     result.append("\nDisplay identification data:\n");
6090*38e8c45fSAndroid Build Coastguard Worker     dumpDisplayIdentificationData(result);
6091*38e8c45fSAndroid Build Coastguard Worker 
6092*38e8c45fSAndroid Build Coastguard Worker     result.append("\nWide-Color information:\n");
6093*38e8c45fSAndroid Build Coastguard Worker     dumpWideColorInfo(result);
6094*38e8c45fSAndroid Build Coastguard Worker 
6095*38e8c45fSAndroid Build Coastguard Worker     dumpHdrInfo(result);
6096*38e8c45fSAndroid Build Coastguard Worker 
6097*38e8c45fSAndroid Build Coastguard Worker     colorizer.bold(result);
6098*38e8c45fSAndroid Build Coastguard Worker     result.append("Sync configuration: ");
6099*38e8c45fSAndroid Build Coastguard Worker     colorizer.reset(result);
6100*38e8c45fSAndroid Build Coastguard Worker     result.append(SyncFeatures::getInstance().toString());
6101*38e8c45fSAndroid Build Coastguard Worker     result.append("\n\n");
6102*38e8c45fSAndroid Build Coastguard Worker 
6103*38e8c45fSAndroid Build Coastguard Worker     colorizer.bold(result);
6104*38e8c45fSAndroid Build Coastguard Worker     result.append("Scheduler:\n");
6105*38e8c45fSAndroid Build Coastguard Worker     colorizer.reset(result);
6106*38e8c45fSAndroid Build Coastguard Worker     dumpScheduler(result);
6107*38e8c45fSAndroid Build Coastguard Worker     dumpEvents(result);
6108*38e8c45fSAndroid Build Coastguard Worker     dumpVsync(result);
6109*38e8c45fSAndroid Build Coastguard Worker     result.append("\n");
6110*38e8c45fSAndroid Build Coastguard Worker 
6111*38e8c45fSAndroid Build Coastguard Worker     /*
6112*38e8c45fSAndroid Build Coastguard Worker      * Dump the visible layer list
6113*38e8c45fSAndroid Build Coastguard Worker      */
6114*38e8c45fSAndroid Build Coastguard Worker     colorizer.bold(result);
6115*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "SurfaceFlinger New Frontend Enabled:%s\n", "true");
6116*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "Active Layers - layers with client handles (count = %zu)\n",
6117*38e8c45fSAndroid Build Coastguard Worker                   mNumLayers.load());
6118*38e8c45fSAndroid Build Coastguard Worker     colorizer.reset(result);
6119*38e8c45fSAndroid Build Coastguard Worker 
6120*38e8c45fSAndroid Build Coastguard Worker     result.append(compositionLayers);
6121*38e8c45fSAndroid Build Coastguard Worker 
6122*38e8c45fSAndroid Build Coastguard Worker     colorizer.bold(result);
6123*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "Displays (%zu entries)\n", mDisplays.size());
6124*38e8c45fSAndroid Build Coastguard Worker     colorizer.reset(result);
6125*38e8c45fSAndroid Build Coastguard Worker     dumpDisplays(result);
6126*38e8c45fSAndroid Build Coastguard Worker     dumpCompositionDisplays(result);
6127*38e8c45fSAndroid Build Coastguard Worker     result.push_back('\n');
6128*38e8c45fSAndroid Build Coastguard Worker 
6129*38e8c45fSAndroid Build Coastguard Worker     mCompositionEngine->dump(result);
6130*38e8c45fSAndroid Build Coastguard Worker 
6131*38e8c45fSAndroid Build Coastguard Worker     /*
6132*38e8c45fSAndroid Build Coastguard Worker      * Dump SurfaceFlinger global state
6133*38e8c45fSAndroid Build Coastguard Worker      */
6134*38e8c45fSAndroid Build Coastguard Worker 
6135*38e8c45fSAndroid Build Coastguard Worker     colorizer.bold(result);
6136*38e8c45fSAndroid Build Coastguard Worker     result.append("SurfaceFlinger global state:\n");
6137*38e8c45fSAndroid Build Coastguard Worker     colorizer.reset(result);
6138*38e8c45fSAndroid Build Coastguard Worker 
6139*38e8c45fSAndroid Build Coastguard Worker     getRenderEngine().dump(result);
6140*38e8c45fSAndroid Build Coastguard Worker 
6141*38e8c45fSAndroid Build Coastguard Worker     result.append("ClientCache state:\n");
6142*38e8c45fSAndroid Build Coastguard Worker     ClientCache::getInstance().dump(result);
6143*38e8c45fSAndroid Build Coastguard Worker     DebugEGLImageTracker::getInstance()->dump(result);
6144*38e8c45fSAndroid Build Coastguard Worker 
6145*38e8c45fSAndroid Build Coastguard Worker     if (const auto display = getDefaultDisplayDeviceLocked()) {
6146*38e8c45fSAndroid Build Coastguard Worker         display->getCompositionDisplay()->getState().undefinedRegion.dump(result,
6147*38e8c45fSAndroid Build Coastguard Worker                                                                           "undefinedRegion");
6148*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&result, "  orientation=%s, isPoweredOn=%d\n",
6149*38e8c45fSAndroid Build Coastguard Worker                       toCString(display->getOrientation()), display->isPoweredOn());
6150*38e8c45fSAndroid Build Coastguard Worker     }
6151*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "  transaction-flags         : %08x\n", mTransactionFlags.load());
6152*38e8c45fSAndroid Build Coastguard Worker 
6153*38e8c45fSAndroid Build Coastguard Worker     if (const auto display = getDefaultDisplayDeviceLocked()) {
6154*38e8c45fSAndroid Build Coastguard Worker         std::string peakFps, xDpi, yDpi;
6155*38e8c45fSAndroid Build Coastguard Worker         const auto activeMode = display->refreshRateSelector().getActiveMode();
6156*38e8c45fSAndroid Build Coastguard Worker         if (const auto activeModePtr = activeMode.modePtr.get()) {
6157*38e8c45fSAndroid Build Coastguard Worker             peakFps = to_string(activeMode.modePtr->getPeakFps());
6158*38e8c45fSAndroid Build Coastguard Worker             const auto dpi = activeModePtr->getDpi();
6159*38e8c45fSAndroid Build Coastguard Worker             xDpi = base::StringPrintf("%.2f", dpi.x);
6160*38e8c45fSAndroid Build Coastguard Worker             yDpi = base::StringPrintf("%.2f", dpi.y);
6161*38e8c45fSAndroid Build Coastguard Worker         } else {
6162*38e8c45fSAndroid Build Coastguard Worker             peakFps = "unknown";
6163*38e8c45fSAndroid Build Coastguard Worker             xDpi = "unknown";
6164*38e8c45fSAndroid Build Coastguard Worker             yDpi = "unknown";
6165*38e8c45fSAndroid Build Coastguard Worker         }
6166*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&result,
6167*38e8c45fSAndroid Build Coastguard Worker                       "  peak-refresh-rate         : %s\n"
6168*38e8c45fSAndroid Build Coastguard Worker                       "  x-dpi                     : %s\n"
6169*38e8c45fSAndroid Build Coastguard Worker                       "  y-dpi                     : %s\n",
6170*38e8c45fSAndroid Build Coastguard Worker                       peakFps.c_str(), xDpi.c_str(), yDpi.c_str());
6171*38e8c45fSAndroid Build Coastguard Worker     }
6172*38e8c45fSAndroid Build Coastguard Worker 
6173*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "  transaction time: %f us\n", inTransactionDuration / 1000.0);
6174*38e8c45fSAndroid Build Coastguard Worker 
6175*38e8c45fSAndroid Build Coastguard Worker     result.append("\nTransaction tracing: ");
6176*38e8c45fSAndroid Build Coastguard Worker     if (mTransactionTracing) {
6177*38e8c45fSAndroid Build Coastguard Worker         result.append("enabled\n");
6178*38e8c45fSAndroid Build Coastguard Worker         mTransactionTracing->dump(result);
6179*38e8c45fSAndroid Build Coastguard Worker     } else {
6180*38e8c45fSAndroid Build Coastguard Worker         result.append("disabled\n");
6181*38e8c45fSAndroid Build Coastguard Worker     }
6182*38e8c45fSAndroid Build Coastguard Worker     result.push_back('\n');
6183*38e8c45fSAndroid Build Coastguard Worker 
6184*38e8c45fSAndroid Build Coastguard Worker     {
6185*38e8c45fSAndroid Build Coastguard Worker         DumpArgs plannerArgs;
6186*38e8c45fSAndroid Build Coastguard Worker         plannerArgs.add(); // first argument is ignored
6187*38e8c45fSAndroid Build Coastguard Worker         plannerArgs.add(String16("--layers"));
6188*38e8c45fSAndroid Build Coastguard Worker         dumpPlannerInfo(plannerArgs, result);
6189*38e8c45fSAndroid Build Coastguard Worker     }
6190*38e8c45fSAndroid Build Coastguard Worker 
6191*38e8c45fSAndroid Build Coastguard Worker     /*
6192*38e8c45fSAndroid Build Coastguard Worker      * Dump HWComposer state
6193*38e8c45fSAndroid Build Coastguard Worker      */
6194*38e8c45fSAndroid Build Coastguard Worker     colorizer.bold(result);
6195*38e8c45fSAndroid Build Coastguard Worker     result.append("h/w composer state:\n");
6196*38e8c45fSAndroid Build Coastguard Worker     colorizer.reset(result);
6197*38e8c45fSAndroid Build Coastguard Worker     const bool hwcDisabled = mDebugDisableHWC || mDebugFlashDelay;
6198*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "  h/w composer %s\n", hwcDisabled ? "disabled" : "enabled");
6199*38e8c45fSAndroid Build Coastguard Worker     dumpHwc(result);
6200*38e8c45fSAndroid Build Coastguard Worker 
6201*38e8c45fSAndroid Build Coastguard Worker     /*
6202*38e8c45fSAndroid Build Coastguard Worker      * Dump gralloc state
6203*38e8c45fSAndroid Build Coastguard Worker      */
6204*38e8c45fSAndroid Build Coastguard Worker     const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
6205*38e8c45fSAndroid Build Coastguard Worker     alloc.dump(result);
6206*38e8c45fSAndroid Build Coastguard Worker 
6207*38e8c45fSAndroid Build Coastguard Worker     /*
6208*38e8c45fSAndroid Build Coastguard Worker      * Dump flag/property manager state
6209*38e8c45fSAndroid Build Coastguard Worker      */
6210*38e8c45fSAndroid Build Coastguard Worker     FlagManager::getInstance().dump(result);
6211*38e8c45fSAndroid Build Coastguard Worker 
6212*38e8c45fSAndroid Build Coastguard Worker     result.append(mTimeStats->miniDump());
6213*38e8c45fSAndroid Build Coastguard Worker     result.append("\n");
6214*38e8c45fSAndroid Build Coastguard Worker }
6215*38e8c45fSAndroid Build Coastguard Worker 
calculateColorMatrix(float saturation)6216*38e8c45fSAndroid Build Coastguard Worker mat4 SurfaceFlinger::calculateColorMatrix(float saturation) {
6217*38e8c45fSAndroid Build Coastguard Worker     if (saturation == 1) {
6218*38e8c45fSAndroid Build Coastguard Worker         return mat4();
6219*38e8c45fSAndroid Build Coastguard Worker     }
6220*38e8c45fSAndroid Build Coastguard Worker 
6221*38e8c45fSAndroid Build Coastguard Worker     float3 luminance{0.213f, 0.715f, 0.072f};
6222*38e8c45fSAndroid Build Coastguard Worker     luminance *= 1.0f - saturation;
6223*38e8c45fSAndroid Build Coastguard Worker     mat4 saturationMatrix = mat4(vec4{luminance.r + saturation, luminance.r, luminance.r, 0.0f},
6224*38e8c45fSAndroid Build Coastguard Worker                                  vec4{luminance.g, luminance.g + saturation, luminance.g, 0.0f},
6225*38e8c45fSAndroid Build Coastguard Worker                                  vec4{luminance.b, luminance.b, luminance.b + saturation, 0.0f},
6226*38e8c45fSAndroid Build Coastguard Worker                                  vec4{0.0f, 0.0f, 0.0f, 1.0f});
6227*38e8c45fSAndroid Build Coastguard Worker     return saturationMatrix;
6228*38e8c45fSAndroid Build Coastguard Worker }
6229*38e8c45fSAndroid Build Coastguard Worker 
updateColorMatrixLocked()6230*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::updateColorMatrixLocked() {
6231*38e8c45fSAndroid Build Coastguard Worker     mat4 colorMatrix =
6232*38e8c45fSAndroid Build Coastguard Worker             mClientColorMatrix * calculateColorMatrix(mGlobalSaturationFactor) * mDaltonizer();
6233*38e8c45fSAndroid Build Coastguard Worker 
6234*38e8c45fSAndroid Build Coastguard Worker     if (mCurrentState.colorMatrix != colorMatrix) {
6235*38e8c45fSAndroid Build Coastguard Worker         mCurrentState.colorMatrix = colorMatrix;
6236*38e8c45fSAndroid Build Coastguard Worker         mCurrentState.colorMatrixChanged = true;
6237*38e8c45fSAndroid Build Coastguard Worker         setTransactionFlags(eTransactionNeeded);
6238*38e8c45fSAndroid Build Coastguard Worker     }
6239*38e8c45fSAndroid Build Coastguard Worker }
6240*38e8c45fSAndroid Build Coastguard Worker 
CheckTransactCodeCredentials(uint32_t code)6241*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) {
6242*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic push
6243*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic error "-Wswitch-enum"
6244*38e8c45fSAndroid Build Coastguard Worker     switch (static_cast<ISurfaceComposerTag>(code)) {
6245*38e8c45fSAndroid Build Coastguard Worker         // These methods should at minimum make sure that the client requested
6246*38e8c45fSAndroid Build Coastguard Worker         // access to SF.
6247*38e8c45fSAndroid Build Coastguard Worker         case GET_HDR_CAPABILITIES:
6248*38e8c45fSAndroid Build Coastguard Worker         case GET_AUTO_LOW_LATENCY_MODE_SUPPORT:
6249*38e8c45fSAndroid Build Coastguard Worker         case GET_GAME_CONTENT_TYPE_SUPPORT:
6250*38e8c45fSAndroid Build Coastguard Worker         case ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN: {
6251*38e8c45fSAndroid Build Coastguard Worker             // OVERRIDE_HDR_TYPES is used by CTS tests, which acquire the necessary
6252*38e8c45fSAndroid Build Coastguard Worker             // permission dynamically. Don't use the permission cache for this check.
6253*38e8c45fSAndroid Build Coastguard Worker             bool usePermissionCache = code != OVERRIDE_HDR_TYPES;
6254*38e8c45fSAndroid Build Coastguard Worker             if (!callingThreadHasUnscopedSurfaceFlingerAccess(usePermissionCache)) {
6255*38e8c45fSAndroid Build Coastguard Worker                 IPCThreadState* ipc = IPCThreadState::self();
6256*38e8c45fSAndroid Build Coastguard Worker                 ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d",
6257*38e8c45fSAndroid Build Coastguard Worker                         ipc->getCallingPid(), ipc->getCallingUid());
6258*38e8c45fSAndroid Build Coastguard Worker                 return PERMISSION_DENIED;
6259*38e8c45fSAndroid Build Coastguard Worker             }
6260*38e8c45fSAndroid Build Coastguard Worker             return OK;
6261*38e8c45fSAndroid Build Coastguard Worker         }
6262*38e8c45fSAndroid Build Coastguard Worker         // The following calls are currently used by clients that do not
6263*38e8c45fSAndroid Build Coastguard Worker         // request necessary permissions. However, they do not expose any secret
6264*38e8c45fSAndroid Build Coastguard Worker         // information, so it is OK to pass them.
6265*38e8c45fSAndroid Build Coastguard Worker         case GET_ACTIVE_COLOR_MODE:
6266*38e8c45fSAndroid Build Coastguard Worker         case GET_ACTIVE_DISPLAY_MODE:
6267*38e8c45fSAndroid Build Coastguard Worker         case GET_DISPLAY_COLOR_MODES:
6268*38e8c45fSAndroid Build Coastguard Worker         case GET_DISPLAY_MODES:
6269*38e8c45fSAndroid Build Coastguard Worker         case GET_SCHEDULING_POLICY:
6270*38e8c45fSAndroid Build Coastguard Worker         // Calling setTransactionState is safe, because you need to have been
6271*38e8c45fSAndroid Build Coastguard Worker         // granted a reference to Client* and Handle* to do anything with it.
6272*38e8c45fSAndroid Build Coastguard Worker         case SET_TRANSACTION_STATE: {
6273*38e8c45fSAndroid Build Coastguard Worker             // This is not sensitive information, so should not require permission control.
6274*38e8c45fSAndroid Build Coastguard Worker             return OK;
6275*38e8c45fSAndroid Build Coastguard Worker         }
6276*38e8c45fSAndroid Build Coastguard Worker         case BOOT_FINISHED:
6277*38e8c45fSAndroid Build Coastguard Worker         // Used by apps to hook Choreographer to SurfaceFlinger.
6278*38e8c45fSAndroid Build Coastguard Worker         case CREATE_DISPLAY_EVENT_CONNECTION:
6279*38e8c45fSAndroid Build Coastguard Worker         case CREATE_CONNECTION:
6280*38e8c45fSAndroid Build Coastguard Worker         case CREATE_VIRTUAL_DISPLAY:
6281*38e8c45fSAndroid Build Coastguard Worker         case DESTROY_VIRTUAL_DISPLAY:
6282*38e8c45fSAndroid Build Coastguard Worker         case GET_PRIMARY_PHYSICAL_DISPLAY_ID:
6283*38e8c45fSAndroid Build Coastguard Worker         case GET_PHYSICAL_DISPLAY_IDS:
6284*38e8c45fSAndroid Build Coastguard Worker         case GET_PHYSICAL_DISPLAY_TOKEN:
6285*38e8c45fSAndroid Build Coastguard Worker         case AUTHENTICATE_SURFACE:
6286*38e8c45fSAndroid Build Coastguard Worker         case SET_POWER_MODE:
6287*38e8c45fSAndroid Build Coastguard Worker         case GET_SUPPORTED_FRAME_TIMESTAMPS:
6288*38e8c45fSAndroid Build Coastguard Worker         case GET_DISPLAY_STATE:
6289*38e8c45fSAndroid Build Coastguard Worker         case GET_DISPLAY_STATS:
6290*38e8c45fSAndroid Build Coastguard Worker         case GET_STATIC_DISPLAY_INFO:
6291*38e8c45fSAndroid Build Coastguard Worker         case GET_DYNAMIC_DISPLAY_INFO:
6292*38e8c45fSAndroid Build Coastguard Worker         case GET_DISPLAY_NATIVE_PRIMARIES:
6293*38e8c45fSAndroid Build Coastguard Worker         case SET_ACTIVE_COLOR_MODE:
6294*38e8c45fSAndroid Build Coastguard Worker         case SET_BOOT_DISPLAY_MODE:
6295*38e8c45fSAndroid Build Coastguard Worker         case CLEAR_BOOT_DISPLAY_MODE:
6296*38e8c45fSAndroid Build Coastguard Worker         case GET_BOOT_DISPLAY_MODE_SUPPORT:
6297*38e8c45fSAndroid Build Coastguard Worker         case SET_AUTO_LOW_LATENCY_MODE:
6298*38e8c45fSAndroid Build Coastguard Worker         case SET_GAME_CONTENT_TYPE:
6299*38e8c45fSAndroid Build Coastguard Worker         case CAPTURE_LAYERS:
6300*38e8c45fSAndroid Build Coastguard Worker         case CAPTURE_DISPLAY:
6301*38e8c45fSAndroid Build Coastguard Worker         case CAPTURE_DISPLAY_BY_ID:
6302*38e8c45fSAndroid Build Coastguard Worker         case CLEAR_ANIMATION_FRAME_STATS:
6303*38e8c45fSAndroid Build Coastguard Worker         case GET_ANIMATION_FRAME_STATS:
6304*38e8c45fSAndroid Build Coastguard Worker         case OVERRIDE_HDR_TYPES:
6305*38e8c45fSAndroid Build Coastguard Worker         case ON_PULL_ATOM:
6306*38e8c45fSAndroid Build Coastguard Worker         case ENABLE_VSYNC_INJECTIONS:
6307*38e8c45fSAndroid Build Coastguard Worker         case INJECT_VSYNC:
6308*38e8c45fSAndroid Build Coastguard Worker         case GET_LAYER_DEBUG_INFO:
6309*38e8c45fSAndroid Build Coastguard Worker         case GET_COLOR_MANAGEMENT:
6310*38e8c45fSAndroid Build Coastguard Worker         case GET_COMPOSITION_PREFERENCE:
6311*38e8c45fSAndroid Build Coastguard Worker         case GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES:
6312*38e8c45fSAndroid Build Coastguard Worker         case SET_DISPLAY_CONTENT_SAMPLING_ENABLED:
6313*38e8c45fSAndroid Build Coastguard Worker         case GET_DISPLAYED_CONTENT_SAMPLE:
6314*38e8c45fSAndroid Build Coastguard Worker         case GET_PROTECTED_CONTENT_SUPPORT:
6315*38e8c45fSAndroid Build Coastguard Worker         case IS_WIDE_COLOR_DISPLAY:
6316*38e8c45fSAndroid Build Coastguard Worker         case ADD_REGION_SAMPLING_LISTENER:
6317*38e8c45fSAndroid Build Coastguard Worker         case REMOVE_REGION_SAMPLING_LISTENER:
6318*38e8c45fSAndroid Build Coastguard Worker         case ADD_FPS_LISTENER:
6319*38e8c45fSAndroid Build Coastguard Worker         case REMOVE_FPS_LISTENER:
6320*38e8c45fSAndroid Build Coastguard Worker         case ADD_TUNNEL_MODE_ENABLED_LISTENER:
6321*38e8c45fSAndroid Build Coastguard Worker         case REMOVE_TUNNEL_MODE_ENABLED_LISTENER:
6322*38e8c45fSAndroid Build Coastguard Worker         case ADD_WINDOW_INFOS_LISTENER:
6323*38e8c45fSAndroid Build Coastguard Worker         case REMOVE_WINDOW_INFOS_LISTENER:
6324*38e8c45fSAndroid Build Coastguard Worker         case SET_DESIRED_DISPLAY_MODE_SPECS:
6325*38e8c45fSAndroid Build Coastguard Worker         case GET_DESIRED_DISPLAY_MODE_SPECS:
6326*38e8c45fSAndroid Build Coastguard Worker         case GET_DISPLAY_BRIGHTNESS_SUPPORT:
6327*38e8c45fSAndroid Build Coastguard Worker         case SET_DISPLAY_BRIGHTNESS:
6328*38e8c45fSAndroid Build Coastguard Worker         case ADD_HDR_LAYER_INFO_LISTENER:
6329*38e8c45fSAndroid Build Coastguard Worker         case REMOVE_HDR_LAYER_INFO_LISTENER:
6330*38e8c45fSAndroid Build Coastguard Worker         case NOTIFY_POWER_BOOST:
6331*38e8c45fSAndroid Build Coastguard Worker         case SET_GLOBAL_SHADOW_SETTINGS:
6332*38e8c45fSAndroid Build Coastguard Worker         case GET_DISPLAY_DECORATION_SUPPORT:
6333*38e8c45fSAndroid Build Coastguard Worker         case SET_FRAME_RATE:
6334*38e8c45fSAndroid Build Coastguard Worker         case SET_OVERRIDE_FRAME_RATE:
6335*38e8c45fSAndroid Build Coastguard Worker         case SET_FRAME_TIMELINE_INFO:
6336*38e8c45fSAndroid Build Coastguard Worker         case ADD_TRANSACTION_TRACE_LISTENER:
6337*38e8c45fSAndroid Build Coastguard Worker         case GET_GPU_CONTEXT_PRIORITY:
6338*38e8c45fSAndroid Build Coastguard Worker         case GET_MAX_ACQUIRED_BUFFER_COUNT:
6339*38e8c45fSAndroid Build Coastguard Worker             LOG_FATAL("Deprecated opcode: %d, migrated to AIDL", code);
6340*38e8c45fSAndroid Build Coastguard Worker             return PERMISSION_DENIED;
6341*38e8c45fSAndroid Build Coastguard Worker     }
6342*38e8c45fSAndroid Build Coastguard Worker 
6343*38e8c45fSAndroid Build Coastguard Worker     // These codes are used for the IBinder protocol to either interrogate the recipient
6344*38e8c45fSAndroid Build Coastguard Worker     // side of the transaction for its canonical interface descriptor or to dump its state.
6345*38e8c45fSAndroid Build Coastguard Worker     // We let them pass by default.
6346*38e8c45fSAndroid Build Coastguard Worker     if (code == IBinder::INTERFACE_TRANSACTION || code == IBinder::DUMP_TRANSACTION ||
6347*38e8c45fSAndroid Build Coastguard Worker         code == IBinder::PING_TRANSACTION || code == IBinder::SHELL_COMMAND_TRANSACTION ||
6348*38e8c45fSAndroid Build Coastguard Worker         code == IBinder::SYSPROPS_TRANSACTION) {
6349*38e8c45fSAndroid Build Coastguard Worker         return OK;
6350*38e8c45fSAndroid Build Coastguard Worker     }
6351*38e8c45fSAndroid Build Coastguard Worker     // Numbers from 1000 to 1045 are currently used for backdoors. The code
6352*38e8c45fSAndroid Build Coastguard Worker     // in onTransact verifies that the user is root, and has access to use SF.
6353*38e8c45fSAndroid Build Coastguard Worker     if (code >= 1000 && code <= 1046) {
6354*38e8c45fSAndroid Build Coastguard Worker         ALOGV("Accessing SurfaceFlinger through backdoor code: %u", code);
6355*38e8c45fSAndroid Build Coastguard Worker         return OK;
6356*38e8c45fSAndroid Build Coastguard Worker     }
6357*38e8c45fSAndroid Build Coastguard Worker     ALOGE("Permission Denial: SurfaceFlinger did not recognize request code: %u", code);
6358*38e8c45fSAndroid Build Coastguard Worker     return PERMISSION_DENIED;
6359*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic pop
6360*38e8c45fSAndroid Build Coastguard Worker }
6361*38e8c45fSAndroid Build Coastguard Worker 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)6362*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
6363*38e8c45fSAndroid Build Coastguard Worker                                     uint32_t flags) {
6364*38e8c45fSAndroid Build Coastguard Worker     if (const status_t error = CheckTransactCodeCredentials(code); error != OK) {
6365*38e8c45fSAndroid Build Coastguard Worker         return error;
6366*38e8c45fSAndroid Build Coastguard Worker     }
6367*38e8c45fSAndroid Build Coastguard Worker 
6368*38e8c45fSAndroid Build Coastguard Worker     status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
6369*38e8c45fSAndroid Build Coastguard Worker     if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
6370*38e8c45fSAndroid Build Coastguard Worker         CHECK_INTERFACE(ISurfaceComposer, data, reply);
6371*38e8c45fSAndroid Build Coastguard Worker         IPCThreadState* ipc = IPCThreadState::self();
6372*38e8c45fSAndroid Build Coastguard Worker         const int uid = ipc->getCallingUid();
6373*38e8c45fSAndroid Build Coastguard Worker         if (CC_UNLIKELY(uid != AID_SYSTEM
6374*38e8c45fSAndroid Build Coastguard Worker                 && !PermissionCache::checkCallingPermission(sHardwareTest))) {
6375*38e8c45fSAndroid Build Coastguard Worker             const int pid = ipc->getCallingPid();
6376*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Permission Denial: "
6377*38e8c45fSAndroid Build Coastguard Worker                     "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
6378*38e8c45fSAndroid Build Coastguard Worker             return PERMISSION_DENIED;
6379*38e8c45fSAndroid Build Coastguard Worker         }
6380*38e8c45fSAndroid Build Coastguard Worker         int n;
6381*38e8c45fSAndroid Build Coastguard Worker         switch (code) {
6382*38e8c45fSAndroid Build Coastguard Worker             case 1000: // Unused.
6383*38e8c45fSAndroid Build Coastguard Worker             case 1001:
6384*38e8c45fSAndroid Build Coastguard Worker                 return NAME_NOT_FOUND;
6385*38e8c45fSAndroid Build Coastguard Worker             case 1002: // Toggle flashing on surface damage.
6386*38e8c45fSAndroid Build Coastguard Worker                 sfdo_setDebugFlash(data.readInt32());
6387*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6388*38e8c45fSAndroid Build Coastguard Worker             case 1004: // Force composite ahead of next VSYNC.
6389*38e8c45fSAndroid Build Coastguard Worker             case 1006:
6390*38e8c45fSAndroid Build Coastguard Worker                 sfdo_scheduleComposite();
6391*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6392*38e8c45fSAndroid Build Coastguard Worker             case 1005: { // Force commit ahead of next VSYNC.
6393*38e8c45fSAndroid Build Coastguard Worker                 sfdo_scheduleCommit();
6394*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6395*38e8c45fSAndroid Build Coastguard Worker             }
6396*38e8c45fSAndroid Build Coastguard Worker             case 1007: // Unused.
6397*38e8c45fSAndroid Build Coastguard Worker                 return NAME_NOT_FOUND;
6398*38e8c45fSAndroid Build Coastguard Worker             case 1008: // Toggle forced GPU composition.
6399*38e8c45fSAndroid Build Coastguard Worker                 sfdo_forceClientComposition(data.readInt32() != 0);
6400*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6401*38e8c45fSAndroid Build Coastguard Worker             case 1009: // Toggle use of transform hint.
6402*38e8c45fSAndroid Build Coastguard Worker                 mDebugDisableTransformHint = data.readInt32() != 0;
6403*38e8c45fSAndroid Build Coastguard Worker                 scheduleRepaint();
6404*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6405*38e8c45fSAndroid Build Coastguard Worker             case 1010: // Interrogate.
6406*38e8c45fSAndroid Build Coastguard Worker                 reply->writeInt32(0);
6407*38e8c45fSAndroid Build Coastguard Worker                 reply->writeInt32(0);
6408*38e8c45fSAndroid Build Coastguard Worker                 reply->writeInt32(mDebugFlashDelay);
6409*38e8c45fSAndroid Build Coastguard Worker                 reply->writeInt32(0);
6410*38e8c45fSAndroid Build Coastguard Worker                 reply->writeInt32(mDebugDisableHWC);
6411*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6412*38e8c45fSAndroid Build Coastguard Worker             case 1013: // Unused.
6413*38e8c45fSAndroid Build Coastguard Worker                 return NAME_NOT_FOUND;
6414*38e8c45fSAndroid Build Coastguard Worker             case 1014: {
6415*38e8c45fSAndroid Build Coastguard Worker                 Mutex::Autolock _l(mStateLock);
6416*38e8c45fSAndroid Build Coastguard Worker                 // daltonize
6417*38e8c45fSAndroid Build Coastguard Worker                 n = data.readInt32();
6418*38e8c45fSAndroid Build Coastguard Worker                 mDaltonizer.setLevel(data.readInt32());
6419*38e8c45fSAndroid Build Coastguard Worker                 switch (n % 10) {
6420*38e8c45fSAndroid Build Coastguard Worker                     case 1:
6421*38e8c45fSAndroid Build Coastguard Worker                         mDaltonizer.setType(ColorBlindnessType::Protanomaly);
6422*38e8c45fSAndroid Build Coastguard Worker                         break;
6423*38e8c45fSAndroid Build Coastguard Worker                     case 2:
6424*38e8c45fSAndroid Build Coastguard Worker                         mDaltonizer.setType(ColorBlindnessType::Deuteranomaly);
6425*38e8c45fSAndroid Build Coastguard Worker                         break;
6426*38e8c45fSAndroid Build Coastguard Worker                     case 3:
6427*38e8c45fSAndroid Build Coastguard Worker                         mDaltonizer.setType(ColorBlindnessType::Tritanomaly);
6428*38e8c45fSAndroid Build Coastguard Worker                         break;
6429*38e8c45fSAndroid Build Coastguard Worker                     default:
6430*38e8c45fSAndroid Build Coastguard Worker                         mDaltonizer.setType(ColorBlindnessType::None);
6431*38e8c45fSAndroid Build Coastguard Worker                         break;
6432*38e8c45fSAndroid Build Coastguard Worker                 }
6433*38e8c45fSAndroid Build Coastguard Worker                 if (n >= 10) {
6434*38e8c45fSAndroid Build Coastguard Worker                     mDaltonizer.setMode(ColorBlindnessMode::Correction);
6435*38e8c45fSAndroid Build Coastguard Worker                 } else {
6436*38e8c45fSAndroid Build Coastguard Worker                     mDaltonizer.setMode(ColorBlindnessMode::Simulation);
6437*38e8c45fSAndroid Build Coastguard Worker                 }
6438*38e8c45fSAndroid Build Coastguard Worker 
6439*38e8c45fSAndroid Build Coastguard Worker                 updateColorMatrixLocked();
6440*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6441*38e8c45fSAndroid Build Coastguard Worker             }
6442*38e8c45fSAndroid Build Coastguard Worker             case 1015: {
6443*38e8c45fSAndroid Build Coastguard Worker                 Mutex::Autolock _l(mStateLock);
6444*38e8c45fSAndroid Build Coastguard Worker                 // apply a color matrix
6445*38e8c45fSAndroid Build Coastguard Worker                 n = data.readInt32();
6446*38e8c45fSAndroid Build Coastguard Worker                 if (n) {
6447*38e8c45fSAndroid Build Coastguard Worker                     // color matrix is sent as a column-major mat4 matrix
6448*38e8c45fSAndroid Build Coastguard Worker                     for (size_t i = 0 ; i < 4; i++) {
6449*38e8c45fSAndroid Build Coastguard Worker                         for (size_t j = 0; j < 4; j++) {
6450*38e8c45fSAndroid Build Coastguard Worker                             mClientColorMatrix[i][j] = data.readFloat();
6451*38e8c45fSAndroid Build Coastguard Worker                         }
6452*38e8c45fSAndroid Build Coastguard Worker                     }
6453*38e8c45fSAndroid Build Coastguard Worker                 } else {
6454*38e8c45fSAndroid Build Coastguard Worker                     mClientColorMatrix = mat4();
6455*38e8c45fSAndroid Build Coastguard Worker                 }
6456*38e8c45fSAndroid Build Coastguard Worker 
6457*38e8c45fSAndroid Build Coastguard Worker                 // Check that supplied matrix's last row is {0,0,0,1} so we can avoid
6458*38e8c45fSAndroid Build Coastguard Worker                 // the division by w in the fragment shader
6459*38e8c45fSAndroid Build Coastguard Worker                 float4 lastRow(transpose(mClientColorMatrix)[3]);
6460*38e8c45fSAndroid Build Coastguard Worker                 if (any(greaterThan(abs(lastRow - float4{0, 0, 0, 1}), float4{1e-4f}))) {
6461*38e8c45fSAndroid Build Coastguard Worker                     ALOGE("The color transform's last row must be (0, 0, 0, 1)");
6462*38e8c45fSAndroid Build Coastguard Worker                 }
6463*38e8c45fSAndroid Build Coastguard Worker 
6464*38e8c45fSAndroid Build Coastguard Worker                 updateColorMatrixLocked();
6465*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6466*38e8c45fSAndroid Build Coastguard Worker             }
6467*38e8c45fSAndroid Build Coastguard Worker             case 1016: { // Unused.
6468*38e8c45fSAndroid Build Coastguard Worker                 return NAME_NOT_FOUND;
6469*38e8c45fSAndroid Build Coastguard Worker             }
6470*38e8c45fSAndroid Build Coastguard Worker             case 1017: {
6471*38e8c45fSAndroid Build Coastguard Worker                 n = data.readInt32();
6472*38e8c45fSAndroid Build Coastguard Worker                 mForceFullDamage = n != 0;
6473*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6474*38e8c45fSAndroid Build Coastguard Worker             }
6475*38e8c45fSAndroid Build Coastguard Worker             case 1018: { // Set the render deadline as a duration until VSYNC.
6476*38e8c45fSAndroid Build Coastguard Worker                 n = data.readInt32();
6477*38e8c45fSAndroid Build Coastguard Worker                 mScheduler->setDuration(scheduler::Cycle::Render, std::chrono::nanoseconds(n), 0ns);
6478*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6479*38e8c45fSAndroid Build Coastguard Worker             }
6480*38e8c45fSAndroid Build Coastguard Worker             case 1019: { // Set the deadline of the last composite as a duration until VSYNC.
6481*38e8c45fSAndroid Build Coastguard Worker                 n = data.readInt32();
6482*38e8c45fSAndroid Build Coastguard Worker                 mScheduler->setDuration(scheduler::Cycle::LastComposite,
6483*38e8c45fSAndroid Build Coastguard Worker                                         std::chrono::nanoseconds(n), 0ns);
6484*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6485*38e8c45fSAndroid Build Coastguard Worker             }
6486*38e8c45fSAndroid Build Coastguard Worker             case 1020: { // Unused
6487*38e8c45fSAndroid Build Coastguard Worker                 return NAME_NOT_FOUND;
6488*38e8c45fSAndroid Build Coastguard Worker             }
6489*38e8c45fSAndroid Build Coastguard Worker             case 1021: { // Disable HWC virtual displays
6490*38e8c45fSAndroid Build Coastguard Worker                 const bool enable = data.readInt32() != 0;
6491*38e8c45fSAndroid Build Coastguard Worker                 static_cast<void>(
6492*38e8c45fSAndroid Build Coastguard Worker                         mScheduler->schedule([this, enable] { enableHalVirtualDisplays(enable); }));
6493*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6494*38e8c45fSAndroid Build Coastguard Worker             }
6495*38e8c45fSAndroid Build Coastguard Worker             case 1022: { // Set saturation boost
6496*38e8c45fSAndroid Build Coastguard Worker                 Mutex::Autolock _l(mStateLock);
6497*38e8c45fSAndroid Build Coastguard Worker                 mGlobalSaturationFactor = std::max(0.0f, std::min(data.readFloat(), 2.0f));
6498*38e8c45fSAndroid Build Coastguard Worker 
6499*38e8c45fSAndroid Build Coastguard Worker                 updateColorMatrixLocked();
6500*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6501*38e8c45fSAndroid Build Coastguard Worker             }
6502*38e8c45fSAndroid Build Coastguard Worker             case 1023: { // Set color mode.
6503*38e8c45fSAndroid Build Coastguard Worker                 mDisplayColorSetting = static_cast<DisplayColorSetting>(data.readInt32());
6504*38e8c45fSAndroid Build Coastguard Worker 
6505*38e8c45fSAndroid Build Coastguard Worker                 if (int32_t colorMode; data.readInt32(&colorMode) == NO_ERROR) {
6506*38e8c45fSAndroid Build Coastguard Worker                     mForceColorMode = static_cast<ui::ColorMode>(colorMode);
6507*38e8c45fSAndroid Build Coastguard Worker                 }
6508*38e8c45fSAndroid Build Coastguard Worker                 scheduleRepaint();
6509*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6510*38e8c45fSAndroid Build Coastguard Worker             }
6511*38e8c45fSAndroid Build Coastguard Worker             // Deprecate, use 1030 to check whether the device is color managed.
6512*38e8c45fSAndroid Build Coastguard Worker             case 1024: {
6513*38e8c45fSAndroid Build Coastguard Worker                 return NAME_NOT_FOUND;
6514*38e8c45fSAndroid Build Coastguard Worker             }
6515*38e8c45fSAndroid Build Coastguard Worker             // Deprecated, use perfetto to start/stop the layer tracing
6516*38e8c45fSAndroid Build Coastguard Worker             case 1025: {
6517*38e8c45fSAndroid Build Coastguard Worker                 return NAME_NOT_FOUND;
6518*38e8c45fSAndroid Build Coastguard Worker             }
6519*38e8c45fSAndroid Build Coastguard Worker             // Deprecated, execute "adb shell perfetto --query" to see the ongoing tracing sessions
6520*38e8c45fSAndroid Build Coastguard Worker             case 1026: {
6521*38e8c45fSAndroid Build Coastguard Worker                 return NAME_NOT_FOUND;
6522*38e8c45fSAndroid Build Coastguard Worker             }
6523*38e8c45fSAndroid Build Coastguard Worker             // Is a DisplayColorSetting supported?
6524*38e8c45fSAndroid Build Coastguard Worker             case 1027: {
6525*38e8c45fSAndroid Build Coastguard Worker                 const auto display = getDefaultDisplayDevice();
6526*38e8c45fSAndroid Build Coastguard Worker                 if (!display) {
6527*38e8c45fSAndroid Build Coastguard Worker                     return NAME_NOT_FOUND;
6528*38e8c45fSAndroid Build Coastguard Worker                 }
6529*38e8c45fSAndroid Build Coastguard Worker 
6530*38e8c45fSAndroid Build Coastguard Worker                 DisplayColorSetting setting = static_cast<DisplayColorSetting>(data.readInt32());
6531*38e8c45fSAndroid Build Coastguard Worker                 switch (setting) {
6532*38e8c45fSAndroid Build Coastguard Worker                     case DisplayColorSetting::kManaged:
6533*38e8c45fSAndroid Build Coastguard Worker                     case DisplayColorSetting::kUnmanaged:
6534*38e8c45fSAndroid Build Coastguard Worker                         reply->writeBool(true);
6535*38e8c45fSAndroid Build Coastguard Worker                         break;
6536*38e8c45fSAndroid Build Coastguard Worker                     case DisplayColorSetting::kEnhanced:
6537*38e8c45fSAndroid Build Coastguard Worker                         reply->writeBool(display->hasRenderIntent(RenderIntent::ENHANCE));
6538*38e8c45fSAndroid Build Coastguard Worker                         break;
6539*38e8c45fSAndroid Build Coastguard Worker                     default: // vendor display color setting
6540*38e8c45fSAndroid Build Coastguard Worker                         reply->writeBool(
6541*38e8c45fSAndroid Build Coastguard Worker                                 display->hasRenderIntent(static_cast<RenderIntent>(setting)));
6542*38e8c45fSAndroid Build Coastguard Worker                         break;
6543*38e8c45fSAndroid Build Coastguard Worker                 }
6544*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6545*38e8c45fSAndroid Build Coastguard Worker             }
6546*38e8c45fSAndroid Build Coastguard Worker             case 1028: { // Unused.
6547*38e8c45fSAndroid Build Coastguard Worker                 return NAME_NOT_FOUND;
6548*38e8c45fSAndroid Build Coastguard Worker             }
6549*38e8c45fSAndroid Build Coastguard Worker             // Deprecated, use perfetto to set the active layer tracing buffer size
6550*38e8c45fSAndroid Build Coastguard Worker             case 1029: {
6551*38e8c45fSAndroid Build Coastguard Worker                 return NAME_NOT_FOUND;
6552*38e8c45fSAndroid Build Coastguard Worker             }
6553*38e8c45fSAndroid Build Coastguard Worker             // Is device color managed?
6554*38e8c45fSAndroid Build Coastguard Worker             case 1030: {
6555*38e8c45fSAndroid Build Coastguard Worker                 // ColorDisplayManager stil calls this
6556*38e8c45fSAndroid Build Coastguard Worker                 reply->writeBool(true);
6557*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6558*38e8c45fSAndroid Build Coastguard Worker             }
6559*38e8c45fSAndroid Build Coastguard Worker             // Override default composition data space
6560*38e8c45fSAndroid Build Coastguard Worker             // adb shell service call SurfaceFlinger 1031 i32 1 DATASPACE_NUMBER DATASPACE_NUMBER \
6561*38e8c45fSAndroid Build Coastguard Worker             // && adb shell stop zygote && adb shell start zygote
6562*38e8c45fSAndroid Build Coastguard Worker             // to restore: adb shell service call SurfaceFlinger 1031 i32 0 && \
6563*38e8c45fSAndroid Build Coastguard Worker             // adb shell stop zygote && adb shell start zygote
6564*38e8c45fSAndroid Build Coastguard Worker             case 1031: {
6565*38e8c45fSAndroid Build Coastguard Worker                 Mutex::Autolock _l(mStateLock);
6566*38e8c45fSAndroid Build Coastguard Worker                 n = data.readInt32();
6567*38e8c45fSAndroid Build Coastguard Worker                 if (n) {
6568*38e8c45fSAndroid Build Coastguard Worker                     n = data.readInt32();
6569*38e8c45fSAndroid Build Coastguard Worker                     if (n) {
6570*38e8c45fSAndroid Build Coastguard Worker                         Dataspace dataspace = static_cast<Dataspace>(n);
6571*38e8c45fSAndroid Build Coastguard Worker                         if (!validateCompositionDataspace(dataspace)) {
6572*38e8c45fSAndroid Build Coastguard Worker                             return BAD_VALUE;
6573*38e8c45fSAndroid Build Coastguard Worker                         }
6574*38e8c45fSAndroid Build Coastguard Worker                         mDefaultCompositionDataspace = dataspace;
6575*38e8c45fSAndroid Build Coastguard Worker                     }
6576*38e8c45fSAndroid Build Coastguard Worker                     n = data.readInt32();
6577*38e8c45fSAndroid Build Coastguard Worker                     if (n) {
6578*38e8c45fSAndroid Build Coastguard Worker                         Dataspace dataspace = static_cast<Dataspace>(n);
6579*38e8c45fSAndroid Build Coastguard Worker                         if (!validateCompositionDataspace(dataspace)) {
6580*38e8c45fSAndroid Build Coastguard Worker                             return BAD_VALUE;
6581*38e8c45fSAndroid Build Coastguard Worker                         }
6582*38e8c45fSAndroid Build Coastguard Worker                         mWideColorGamutCompositionDataspace = dataspace;
6583*38e8c45fSAndroid Build Coastguard Worker                     }
6584*38e8c45fSAndroid Build Coastguard Worker                 } else {
6585*38e8c45fSAndroid Build Coastguard Worker                     // restore composition data space.
6586*38e8c45fSAndroid Build Coastguard Worker                     mDefaultCompositionDataspace = defaultCompositionDataspace;
6587*38e8c45fSAndroid Build Coastguard Worker                     mWideColorGamutCompositionDataspace = wideColorGamutCompositionDataspace;
6588*38e8c45fSAndroid Build Coastguard Worker                 }
6589*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6590*38e8c45fSAndroid Build Coastguard Worker             }
6591*38e8c45fSAndroid Build Coastguard Worker             // Deprecated, use perfetto to set layer trace flags
6592*38e8c45fSAndroid Build Coastguard Worker             case 1033: {
6593*38e8c45fSAndroid Build Coastguard Worker                 return NAME_NOT_FOUND;
6594*38e8c45fSAndroid Build Coastguard Worker             }
6595*38e8c45fSAndroid Build Coastguard Worker             case 1034: {
6596*38e8c45fSAndroid Build Coastguard Worker                 n = data.readInt32();
6597*38e8c45fSAndroid Build Coastguard Worker                 if (n == 0 || n == 1) {
6598*38e8c45fSAndroid Build Coastguard Worker                     sfdo_enableRefreshRateOverlay(static_cast<bool>(n));
6599*38e8c45fSAndroid Build Coastguard Worker                 } else {
6600*38e8c45fSAndroid Build Coastguard Worker                     Mutex::Autolock lock(mStateLock);
6601*38e8c45fSAndroid Build Coastguard Worker                     reply->writeBool(isRefreshRateOverlayEnabled());
6602*38e8c45fSAndroid Build Coastguard Worker                 }
6603*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6604*38e8c45fSAndroid Build Coastguard Worker             }
6605*38e8c45fSAndroid Build Coastguard Worker             case 1035: {
6606*38e8c45fSAndroid Build Coastguard Worker                 // Parameters:
6607*38e8c45fSAndroid Build Coastguard Worker                 // - (required) i32 mode id.
6608*38e8c45fSAndroid Build Coastguard Worker                 // - (optional) i64 display id. Using default display if not provided.
6609*38e8c45fSAndroid Build Coastguard Worker                 // - (optional) f min render rate. Using mode's fps is not provided.
6610*38e8c45fSAndroid Build Coastguard Worker                 // - (optional) f max render rate. Using mode's fps is not provided.
6611*38e8c45fSAndroid Build Coastguard Worker 
6612*38e8c45fSAndroid Build Coastguard Worker                 const int modeId = data.readInt32();
6613*38e8c45fSAndroid Build Coastguard Worker 
6614*38e8c45fSAndroid Build Coastguard Worker                 const auto display = [&]() -> sp<IBinder> {
6615*38e8c45fSAndroid Build Coastguard Worker                     uint64_t value;
6616*38e8c45fSAndroid Build Coastguard Worker                     if (data.readUint64(&value) != NO_ERROR) {
6617*38e8c45fSAndroid Build Coastguard Worker                         return getDefaultDisplayDevice()->getDisplayToken().promote();
6618*38e8c45fSAndroid Build Coastguard Worker                     }
6619*38e8c45fSAndroid Build Coastguard Worker 
6620*38e8c45fSAndroid Build Coastguard Worker                     if (const auto id = DisplayId::fromValue<PhysicalDisplayId>(value)) {
6621*38e8c45fSAndroid Build Coastguard Worker                         return getPhysicalDisplayToken(*id);
6622*38e8c45fSAndroid Build Coastguard Worker                     }
6623*38e8c45fSAndroid Build Coastguard Worker 
6624*38e8c45fSAndroid Build Coastguard Worker                     ALOGE("Invalid physical display ID");
6625*38e8c45fSAndroid Build Coastguard Worker                     return nullptr;
6626*38e8c45fSAndroid Build Coastguard Worker                 }();
6627*38e8c45fSAndroid Build Coastguard Worker 
6628*38e8c45fSAndroid Build Coastguard Worker                 const auto getFps = [&] {
6629*38e8c45fSAndroid Build Coastguard Worker                     float value;
6630*38e8c45fSAndroid Build Coastguard Worker                     if (data.readFloat(&value) == NO_ERROR) {
6631*38e8c45fSAndroid Build Coastguard Worker                         return Fps::fromValue(value);
6632*38e8c45fSAndroid Build Coastguard Worker                     }
6633*38e8c45fSAndroid Build Coastguard Worker 
6634*38e8c45fSAndroid Build Coastguard Worker                     return Fps();
6635*38e8c45fSAndroid Build Coastguard Worker                 };
6636*38e8c45fSAndroid Build Coastguard Worker 
6637*38e8c45fSAndroid Build Coastguard Worker                 const auto minFps = getFps();
6638*38e8c45fSAndroid Build Coastguard Worker                 const auto maxFps = getFps();
6639*38e8c45fSAndroid Build Coastguard Worker 
6640*38e8c45fSAndroid Build Coastguard Worker                 mDebugDisplayModeSetByBackdoor = false;
6641*38e8c45fSAndroid Build Coastguard Worker                 const status_t result =
6642*38e8c45fSAndroid Build Coastguard Worker                         setActiveModeFromBackdoor(display, DisplayModeId{modeId}, minFps, maxFps);
6643*38e8c45fSAndroid Build Coastguard Worker                 mDebugDisplayModeSetByBackdoor = result == NO_ERROR;
6644*38e8c45fSAndroid Build Coastguard Worker                 return result;
6645*38e8c45fSAndroid Build Coastguard Worker             }
6646*38e8c45fSAndroid Build Coastguard Worker             // Turn on/off frame rate flexibility mode. When turned on it overrides the display
6647*38e8c45fSAndroid Build Coastguard Worker             // manager frame rate policy a new policy which allows switching between all refresh
6648*38e8c45fSAndroid Build Coastguard Worker             // rates.
6649*38e8c45fSAndroid Build Coastguard Worker             case 1036: {
6650*38e8c45fSAndroid Build Coastguard Worker                 if (data.readInt32() > 0) { // turn on
6651*38e8c45fSAndroid Build Coastguard Worker                     return mScheduler
6652*38e8c45fSAndroid Build Coastguard Worker                             ->schedule([this]() FTL_FAKE_GUARD(kMainThreadContext) {
6653*38e8c45fSAndroid Build Coastguard Worker                                 const auto display =
6654*38e8c45fSAndroid Build Coastguard Worker                                         FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
6655*38e8c45fSAndroid Build Coastguard Worker 
6656*38e8c45fSAndroid Build Coastguard Worker                                 // This is a little racy, but not in a way that hurts anything. As
6657*38e8c45fSAndroid Build Coastguard Worker                                 // we grab the defaultMode from the display manager policy, we could
6658*38e8c45fSAndroid Build Coastguard Worker                                 // be setting a new display manager policy, leaving us using a stale
6659*38e8c45fSAndroid Build Coastguard Worker                                 // defaultMode. The defaultMode doesn't matter for the override
6660*38e8c45fSAndroid Build Coastguard Worker                                 // policy though, since we set allowGroupSwitching to true, so it's
6661*38e8c45fSAndroid Build Coastguard Worker                                 // not a problem.
6662*38e8c45fSAndroid Build Coastguard Worker                                 scheduler::RefreshRateSelector::OverridePolicy overridePolicy;
6663*38e8c45fSAndroid Build Coastguard Worker                                 overridePolicy.defaultMode = display->refreshRateSelector()
6664*38e8c45fSAndroid Build Coastguard Worker                                                                      .getDisplayManagerPolicy()
6665*38e8c45fSAndroid Build Coastguard Worker                                                                      .defaultMode;
6666*38e8c45fSAndroid Build Coastguard Worker                                 overridePolicy.allowGroupSwitching = true;
6667*38e8c45fSAndroid Build Coastguard Worker                                 return setDesiredDisplayModeSpecsInternal(display, overridePolicy);
6668*38e8c45fSAndroid Build Coastguard Worker                             })
6669*38e8c45fSAndroid Build Coastguard Worker                             .get();
6670*38e8c45fSAndroid Build Coastguard Worker                 } else { // turn off
6671*38e8c45fSAndroid Build Coastguard Worker                     return mScheduler
6672*38e8c45fSAndroid Build Coastguard Worker                             ->schedule([this]() FTL_FAKE_GUARD(kMainThreadContext) {
6673*38e8c45fSAndroid Build Coastguard Worker                                 const auto display =
6674*38e8c45fSAndroid Build Coastguard Worker                                         FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
6675*38e8c45fSAndroid Build Coastguard Worker                                 return setDesiredDisplayModeSpecsInternal(
6676*38e8c45fSAndroid Build Coastguard Worker                                         display,
6677*38e8c45fSAndroid Build Coastguard Worker                                         scheduler::RefreshRateSelector::NoOverridePolicy{});
6678*38e8c45fSAndroid Build Coastguard Worker                             })
6679*38e8c45fSAndroid Build Coastguard Worker                             .get();
6680*38e8c45fSAndroid Build Coastguard Worker                 }
6681*38e8c45fSAndroid Build Coastguard Worker             }
6682*38e8c45fSAndroid Build Coastguard Worker             // Inject a hotplug connected event for the primary display. This will deallocate and
6683*38e8c45fSAndroid Build Coastguard Worker             // reallocate the display state including framebuffers.
6684*38e8c45fSAndroid Build Coastguard Worker             case 1037: {
6685*38e8c45fSAndroid Build Coastguard Worker                 const hal::HWDisplayId hwcId =
6686*38e8c45fSAndroid Build Coastguard Worker                         (Mutex::Autolock(mStateLock), getHwComposer().getPrimaryHwcDisplayId());
6687*38e8c45fSAndroid Build Coastguard Worker 
6688*38e8c45fSAndroid Build Coastguard Worker                 onComposerHalHotplugEvent(hwcId, DisplayHotplugEvent::CONNECTED);
6689*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6690*38e8c45fSAndroid Build Coastguard Worker             }
6691*38e8c45fSAndroid Build Coastguard Worker             // Modify the max number of display frames stored within FrameTimeline
6692*38e8c45fSAndroid Build Coastguard Worker             case 1038: {
6693*38e8c45fSAndroid Build Coastguard Worker                 n = data.readInt32();
6694*38e8c45fSAndroid Build Coastguard Worker                 if (n < 0 || n > MAX_ALLOWED_DISPLAY_FRAMES) {
6695*38e8c45fSAndroid Build Coastguard Worker                     ALOGW("Invalid max size. Maximum allowed is %d", MAX_ALLOWED_DISPLAY_FRAMES);
6696*38e8c45fSAndroid Build Coastguard Worker                     return BAD_VALUE;
6697*38e8c45fSAndroid Build Coastguard Worker                 }
6698*38e8c45fSAndroid Build Coastguard Worker                 if (n == 0) {
6699*38e8c45fSAndroid Build Coastguard Worker                     // restore to default
6700*38e8c45fSAndroid Build Coastguard Worker                     mFrameTimeline->reset();
6701*38e8c45fSAndroid Build Coastguard Worker                     return NO_ERROR;
6702*38e8c45fSAndroid Build Coastguard Worker                 }
6703*38e8c45fSAndroid Build Coastguard Worker                 mFrameTimeline->setMaxDisplayFrames(n);
6704*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6705*38e8c45fSAndroid Build Coastguard Worker             }
6706*38e8c45fSAndroid Build Coastguard Worker             case 1039: {
6707*38e8c45fSAndroid Build Coastguard Worker                 const auto uid = static_cast<uid_t>(data.readInt32());
6708*38e8c45fSAndroid Build Coastguard Worker                 const auto refreshRate = data.readFloat();
6709*38e8c45fSAndroid Build Coastguard Worker                 mScheduler->setPreferredRefreshRateForUid(FrameRateOverride{uid, refreshRate});
6710*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6711*38e8c45fSAndroid Build Coastguard Worker             }
6712*38e8c45fSAndroid Build Coastguard Worker             // Toggle caching feature
6713*38e8c45fSAndroid Build Coastguard Worker             // First argument is an int32 - nonzero enables caching and zero disables caching
6714*38e8c45fSAndroid Build Coastguard Worker             // Second argument is an optional uint64 - if present, then limits enabling/disabling
6715*38e8c45fSAndroid Build Coastguard Worker             // caching to a particular physical display
6716*38e8c45fSAndroid Build Coastguard Worker             case 1040: {
6717*38e8c45fSAndroid Build Coastguard Worker                 auto future = mScheduler->schedule([&] {
6718*38e8c45fSAndroid Build Coastguard Worker                     n = data.readInt32();
6719*38e8c45fSAndroid Build Coastguard Worker                     std::optional<PhysicalDisplayId> inputId = std::nullopt;
6720*38e8c45fSAndroid Build Coastguard Worker                     if (uint64_t inputDisplayId; data.readUint64(&inputDisplayId) == NO_ERROR) {
6721*38e8c45fSAndroid Build Coastguard Worker                         inputId = DisplayId::fromValue<PhysicalDisplayId>(inputDisplayId);
6722*38e8c45fSAndroid Build Coastguard Worker                         if (!inputId || getPhysicalDisplayToken(*inputId)) {
6723*38e8c45fSAndroid Build Coastguard Worker                             ALOGE("No display with id: %" PRIu64, inputDisplayId);
6724*38e8c45fSAndroid Build Coastguard Worker                             return NAME_NOT_FOUND;
6725*38e8c45fSAndroid Build Coastguard Worker                         }
6726*38e8c45fSAndroid Build Coastguard Worker                     }
6727*38e8c45fSAndroid Build Coastguard Worker                     {
6728*38e8c45fSAndroid Build Coastguard Worker                         Mutex::Autolock lock(mStateLock);
6729*38e8c45fSAndroid Build Coastguard Worker                         mLayerCachingEnabled = n != 0;
6730*38e8c45fSAndroid Build Coastguard Worker                         for (const auto& [_, display] : mDisplays) {
6731*38e8c45fSAndroid Build Coastguard Worker                             if (!inputId || *inputId == display->getPhysicalId()) {
6732*38e8c45fSAndroid Build Coastguard Worker                                 display->enableLayerCaching(mLayerCachingEnabled);
6733*38e8c45fSAndroid Build Coastguard Worker                             }
6734*38e8c45fSAndroid Build Coastguard Worker                         }
6735*38e8c45fSAndroid Build Coastguard Worker                     }
6736*38e8c45fSAndroid Build Coastguard Worker                     return OK;
6737*38e8c45fSAndroid Build Coastguard Worker                 });
6738*38e8c45fSAndroid Build Coastguard Worker 
6739*38e8c45fSAndroid Build Coastguard Worker                 if (const status_t error = future.get(); error != OK) {
6740*38e8c45fSAndroid Build Coastguard Worker                     return error;
6741*38e8c45fSAndroid Build Coastguard Worker                 }
6742*38e8c45fSAndroid Build Coastguard Worker                 scheduleRepaint();
6743*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6744*38e8c45fSAndroid Build Coastguard Worker             }
6745*38e8c45fSAndroid Build Coastguard Worker             case 1041: { // Transaction tracing
6746*38e8c45fSAndroid Build Coastguard Worker                 if (mTransactionTracing) {
6747*38e8c45fSAndroid Build Coastguard Worker                     int arg = data.readInt32();
6748*38e8c45fSAndroid Build Coastguard Worker                     if (arg == -1) {
6749*38e8c45fSAndroid Build Coastguard Worker                         mScheduler->schedule([&]() { mTransactionTracing.reset(); }).get();
6750*38e8c45fSAndroid Build Coastguard Worker                     } else if (arg > 0) {
6751*38e8c45fSAndroid Build Coastguard Worker                         // Transaction tracing is always running but allow the user to temporarily
6752*38e8c45fSAndroid Build Coastguard Worker                         // increase the buffer when actively debugging.
6753*38e8c45fSAndroid Build Coastguard Worker                         mTransactionTracing->setBufferSize(
6754*38e8c45fSAndroid Build Coastguard Worker                                 TransactionTracing::LEGACY_ACTIVE_TRACING_BUFFER_SIZE);
6755*38e8c45fSAndroid Build Coastguard Worker                     } else {
6756*38e8c45fSAndroid Build Coastguard Worker                         TransactionTraceWriter::getInstance().invoke("", /* overwrite= */ true);
6757*38e8c45fSAndroid Build Coastguard Worker                         mTransactionTracing->setBufferSize(
6758*38e8c45fSAndroid Build Coastguard Worker                                 TransactionTracing::CONTINUOUS_TRACING_BUFFER_SIZE);
6759*38e8c45fSAndroid Build Coastguard Worker                     }
6760*38e8c45fSAndroid Build Coastguard Worker                 }
6761*38e8c45fSAndroid Build Coastguard Worker                 reply->writeInt32(NO_ERROR);
6762*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6763*38e8c45fSAndroid Build Coastguard Worker             }
6764*38e8c45fSAndroid Build Coastguard Worker             case 1042: { // Write transaction trace to file
6765*38e8c45fSAndroid Build Coastguard Worker                 if (mTransactionTracing) {
6766*38e8c45fSAndroid Build Coastguard Worker                     mTransactionTracing->writeToFile();
6767*38e8c45fSAndroid Build Coastguard Worker                 }
6768*38e8c45fSAndroid Build Coastguard Worker                 reply->writeInt32(NO_ERROR);
6769*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6770*38e8c45fSAndroid Build Coastguard Worker             }
6771*38e8c45fSAndroid Build Coastguard Worker             // hdr sdr ratio overlay
6772*38e8c45fSAndroid Build Coastguard Worker             case 1043: {
6773*38e8c45fSAndroid Build Coastguard Worker                 auto future = mScheduler->schedule(
6774*38e8c45fSAndroid Build Coastguard Worker                         [&]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(kMainThreadContext) {
6775*38e8c45fSAndroid Build Coastguard Worker                             n = data.readInt32();
6776*38e8c45fSAndroid Build Coastguard Worker                             if (n == 0 || n == 1) {
6777*38e8c45fSAndroid Build Coastguard Worker                                 mHdrSdrRatioOverlay = n != 0;
6778*38e8c45fSAndroid Build Coastguard Worker                                 enableHdrSdrRatioOverlay(mHdrSdrRatioOverlay);
6779*38e8c45fSAndroid Build Coastguard Worker                             } else {
6780*38e8c45fSAndroid Build Coastguard Worker                                 reply->writeBool(isHdrSdrRatioOverlayEnabled());
6781*38e8c45fSAndroid Build Coastguard Worker                             }
6782*38e8c45fSAndroid Build Coastguard Worker                         });
6783*38e8c45fSAndroid Build Coastguard Worker                 future.wait();
6784*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6785*38e8c45fSAndroid Build Coastguard Worker             }
6786*38e8c45fSAndroid Build Coastguard Worker 
6787*38e8c45fSAndroid Build Coastguard Worker             case 1044: { // Enable/Disable mirroring from one display to another
6788*38e8c45fSAndroid Build Coastguard Worker                 /*
6789*38e8c45fSAndroid Build Coastguard Worker                  * Mirror one display onto another.
6790*38e8c45fSAndroid Build Coastguard Worker                  * Ensure the source and destination displays are on.
6791*38e8c45fSAndroid Build Coastguard Worker                  * Commands:
6792*38e8c45fSAndroid Build Coastguard Worker                  * 0: Mirror one display to another
6793*38e8c45fSAndroid Build Coastguard Worker                  * 1: Disable mirroring to a previously mirrored display
6794*38e8c45fSAndroid Build Coastguard Worker                  * 2: Disable mirroring on previously mirrored displays
6795*38e8c45fSAndroid Build Coastguard Worker                  *
6796*38e8c45fSAndroid Build Coastguard Worker                  * Ex:
6797*38e8c45fSAndroid Build Coastguard Worker                  * Get the display ids:
6798*38e8c45fSAndroid Build Coastguard Worker                  * adb shell dumpsys SurfaceFlinger --display-id
6799*38e8c45fSAndroid Build Coastguard Worker                  * Mirror first display to the second:
6800*38e8c45fSAndroid Build Coastguard Worker                  * adb shell service call SurfaceFlinger 1044 i64 0 i64 4619827677550801152 i64
6801*38e8c45fSAndroid Build Coastguard Worker                  * 4619827677550801153
6802*38e8c45fSAndroid Build Coastguard Worker                  * Stop mirroring:
6803*38e8c45fSAndroid Build Coastguard Worker                  * adb shell service call SurfaceFlinger 1044 i64 1
6804*38e8c45fSAndroid Build Coastguard Worker                  */
6805*38e8c45fSAndroid Build Coastguard Worker 
6806*38e8c45fSAndroid Build Coastguard Worker                 int64_t arg0 = data.readInt64();
6807*38e8c45fSAndroid Build Coastguard Worker 
6808*38e8c45fSAndroid Build Coastguard Worker                 switch (arg0) {
6809*38e8c45fSAndroid Build Coastguard Worker                     case 0: {
6810*38e8c45fSAndroid Build Coastguard Worker                         // Mirror arg1 to arg2
6811*38e8c45fSAndroid Build Coastguard Worker                         int64_t arg1 = data.readInt64();
6812*38e8c45fSAndroid Build Coastguard Worker                         int64_t arg2 = data.readInt64();
6813*38e8c45fSAndroid Build Coastguard Worker                         // Enable mirroring for one display
6814*38e8c45fSAndroid Build Coastguard Worker                         const auto display1id = DisplayId::fromValue(arg1);
6815*38e8c45fSAndroid Build Coastguard Worker                         auto mirrorRoot = SurfaceComposerClient::getDefault()->mirrorDisplay(
6816*38e8c45fSAndroid Build Coastguard Worker                                 display1id.value());
6817*38e8c45fSAndroid Build Coastguard Worker                         auto id2 = DisplayId::fromValue<PhysicalDisplayId>(arg2);
6818*38e8c45fSAndroid Build Coastguard Worker                         const auto token2 = getPhysicalDisplayToken(*id2);
6819*38e8c45fSAndroid Build Coastguard Worker                         ui::LayerStack layerStack;
6820*38e8c45fSAndroid Build Coastguard Worker                         {
6821*38e8c45fSAndroid Build Coastguard Worker                             Mutex::Autolock lock(mStateLock);
6822*38e8c45fSAndroid Build Coastguard Worker                             sp<DisplayDevice> display = getDisplayDeviceLocked(token2);
6823*38e8c45fSAndroid Build Coastguard Worker                             layerStack = display->getLayerStack();
6824*38e8c45fSAndroid Build Coastguard Worker                         }
6825*38e8c45fSAndroid Build Coastguard Worker                         SurfaceComposerClient::Transaction t;
6826*38e8c45fSAndroid Build Coastguard Worker                         t.setDisplayLayerStack(token2, layerStack);
6827*38e8c45fSAndroid Build Coastguard Worker                         t.setLayer(mirrorRoot, INT_MAX); // Top-most layer
6828*38e8c45fSAndroid Build Coastguard Worker                         t.setLayerStack(mirrorRoot, layerStack);
6829*38e8c45fSAndroid Build Coastguard Worker                         t.apply();
6830*38e8c45fSAndroid Build Coastguard Worker 
6831*38e8c45fSAndroid Build Coastguard Worker                         mMirrorMapForDebug.emplace_or_replace(arg2, mirrorRoot);
6832*38e8c45fSAndroid Build Coastguard Worker                         break;
6833*38e8c45fSAndroid Build Coastguard Worker                     }
6834*38e8c45fSAndroid Build Coastguard Worker 
6835*38e8c45fSAndroid Build Coastguard Worker                     case 1: {
6836*38e8c45fSAndroid Build Coastguard Worker                         // Disable mirroring for arg1
6837*38e8c45fSAndroid Build Coastguard Worker                         int64_t arg1 = data.readInt64();
6838*38e8c45fSAndroid Build Coastguard Worker                         mMirrorMapForDebug.erase(arg1);
6839*38e8c45fSAndroid Build Coastguard Worker                         break;
6840*38e8c45fSAndroid Build Coastguard Worker                     }
6841*38e8c45fSAndroid Build Coastguard Worker 
6842*38e8c45fSAndroid Build Coastguard Worker                     case 2: {
6843*38e8c45fSAndroid Build Coastguard Worker                         // Disable mirroring for all displays
6844*38e8c45fSAndroid Build Coastguard Worker                         mMirrorMapForDebug.clear();
6845*38e8c45fSAndroid Build Coastguard Worker                         break;
6846*38e8c45fSAndroid Build Coastguard Worker                     }
6847*38e8c45fSAndroid Build Coastguard Worker 
6848*38e8c45fSAndroid Build Coastguard Worker                     default:
6849*38e8c45fSAndroid Build Coastguard Worker                         return BAD_VALUE;
6850*38e8c45fSAndroid Build Coastguard Worker                 }
6851*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6852*38e8c45fSAndroid Build Coastguard Worker             }
6853*38e8c45fSAndroid Build Coastguard Worker             // Inject jank
6854*38e8c45fSAndroid Build Coastguard Worker             // First argument is a float that describes the fraction of frame duration to jank by.
6855*38e8c45fSAndroid Build Coastguard Worker             // Second argument is a delay in ms for triggering the jank. This is useful for working
6856*38e8c45fSAndroid Build Coastguard Worker             // with tools that steal the adb connection. This argument is optional.
6857*38e8c45fSAndroid Build Coastguard Worker             case 1045: {
6858*38e8c45fSAndroid Build Coastguard Worker                 if (FlagManager::getInstance().vrr_config()) {
6859*38e8c45fSAndroid Build Coastguard Worker                     float jankAmount = data.readFloat();
6860*38e8c45fSAndroid Build Coastguard Worker                     int32_t jankDelayMs = 0;
6861*38e8c45fSAndroid Build Coastguard Worker                     if (data.readInt32(&jankDelayMs) != NO_ERROR) {
6862*38e8c45fSAndroid Build Coastguard Worker                         jankDelayMs = 0;
6863*38e8c45fSAndroid Build Coastguard Worker                     }
6864*38e8c45fSAndroid Build Coastguard Worker 
6865*38e8c45fSAndroid Build Coastguard Worker                     const auto jankDelayDuration = Duration(std::chrono::milliseconds(jankDelayMs));
6866*38e8c45fSAndroid Build Coastguard Worker 
6867*38e8c45fSAndroid Build Coastguard Worker                     const bool jankAmountValid = jankAmount > 0.0 && jankAmount < 100.0;
6868*38e8c45fSAndroid Build Coastguard Worker 
6869*38e8c45fSAndroid Build Coastguard Worker                     if (!jankAmountValid) {
6870*38e8c45fSAndroid Build Coastguard Worker                         ALOGD("Ignoring invalid jank amount: %f", jankAmount);
6871*38e8c45fSAndroid Build Coastguard Worker                         reply->writeInt32(BAD_VALUE);
6872*38e8c45fSAndroid Build Coastguard Worker                         return BAD_VALUE;
6873*38e8c45fSAndroid Build Coastguard Worker                     }
6874*38e8c45fSAndroid Build Coastguard Worker 
6875*38e8c45fSAndroid Build Coastguard Worker                     (void)mScheduler->scheduleDelayed(
6876*38e8c45fSAndroid Build Coastguard Worker                             [&, jankAmount]() FTL_FAKE_GUARD(kMainThreadContext) {
6877*38e8c45fSAndroid Build Coastguard Worker                                 mScheduler->injectPacesetterDelay(jankAmount);
6878*38e8c45fSAndroid Build Coastguard Worker                                 scheduleComposite(FrameHint::kActive);
6879*38e8c45fSAndroid Build Coastguard Worker                             },
6880*38e8c45fSAndroid Build Coastguard Worker                             jankDelayDuration.ns());
6881*38e8c45fSAndroid Build Coastguard Worker                     reply->writeInt32(NO_ERROR);
6882*38e8c45fSAndroid Build Coastguard Worker                     return NO_ERROR;
6883*38e8c45fSAndroid Build Coastguard Worker                 }
6884*38e8c45fSAndroid Build Coastguard Worker                 return err;
6885*38e8c45fSAndroid Build Coastguard Worker             }
6886*38e8c45fSAndroid Build Coastguard Worker             // Introduce jank to HWC
6887*38e8c45fSAndroid Build Coastguard Worker             case 1046: {
6888*38e8c45fSAndroid Build Coastguard Worker                 int32_t jankDelayMs = 0;
6889*38e8c45fSAndroid Build Coastguard Worker                 if (data.readInt32(&jankDelayMs) != NO_ERROR) {
6890*38e8c45fSAndroid Build Coastguard Worker                     return BAD_VALUE;
6891*38e8c45fSAndroid Build Coastguard Worker                 }
6892*38e8c45fSAndroid Build Coastguard Worker                 mScheduler->setDebugPresentDelay(TimePoint::fromNs(ms2ns(jankDelayMs)));
6893*38e8c45fSAndroid Build Coastguard Worker                 return NO_ERROR;
6894*38e8c45fSAndroid Build Coastguard Worker             }
6895*38e8c45fSAndroid Build Coastguard Worker         }
6896*38e8c45fSAndroid Build Coastguard Worker     }
6897*38e8c45fSAndroid Build Coastguard Worker     return err;
6898*38e8c45fSAndroid Build Coastguard Worker }
6899*38e8c45fSAndroid Build Coastguard Worker 
kernelTimerChanged(bool expired)6900*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::kernelTimerChanged(bool expired) {
6901*38e8c45fSAndroid Build Coastguard Worker     static bool updateOverlay =
6902*38e8c45fSAndroid Build Coastguard Worker             property_get_bool("debug.sf.kernel_idle_timer_update_overlay", true);
6903*38e8c45fSAndroid Build Coastguard Worker     if (!updateOverlay) return;
6904*38e8c45fSAndroid Build Coastguard Worker 
6905*38e8c45fSAndroid Build Coastguard Worker     // Update the overlay on the main thread to avoid race conditions with
6906*38e8c45fSAndroid Build Coastguard Worker     // RefreshRateSelector::getActiveMode
6907*38e8c45fSAndroid Build Coastguard Worker     static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) {
6908*38e8c45fSAndroid Build Coastguard Worker         const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
6909*38e8c45fSAndroid Build Coastguard Worker         if (!display) {
6910*38e8c45fSAndroid Build Coastguard Worker             ALOGW("%s: default display is null", __func__);
6911*38e8c45fSAndroid Build Coastguard Worker             return;
6912*38e8c45fSAndroid Build Coastguard Worker         }
6913*38e8c45fSAndroid Build Coastguard Worker         if (!display->isRefreshRateOverlayEnabled()) return;
6914*38e8c45fSAndroid Build Coastguard Worker 
6915*38e8c45fSAndroid Build Coastguard Worker         const auto state = mDisplayModeController.getKernelIdleTimerState(display->getPhysicalId());
6916*38e8c45fSAndroid Build Coastguard Worker 
6917*38e8c45fSAndroid Build Coastguard Worker         if (display->onKernelTimerChanged(state.desiredModeIdOpt, state.isEnabled && expired)) {
6918*38e8c45fSAndroid Build Coastguard Worker             mScheduler->scheduleFrame();
6919*38e8c45fSAndroid Build Coastguard Worker         }
6920*38e8c45fSAndroid Build Coastguard Worker     }));
6921*38e8c45fSAndroid Build Coastguard Worker }
6922*38e8c45fSAndroid Build Coastguard Worker 
vrrDisplayIdle(bool idle)6923*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::vrrDisplayIdle(bool idle) {
6924*38e8c45fSAndroid Build Coastguard Worker     // Update the overlay on the main thread to avoid race conditions with
6925*38e8c45fSAndroid Build Coastguard Worker     // RefreshRateSelector::getActiveMode
6926*38e8c45fSAndroid Build Coastguard Worker     static_cast<void>(mScheduler->schedule([=, this] {
6927*38e8c45fSAndroid Build Coastguard Worker         const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
6928*38e8c45fSAndroid Build Coastguard Worker         if (!display) {
6929*38e8c45fSAndroid Build Coastguard Worker             ALOGW("%s: default display is null", __func__);
6930*38e8c45fSAndroid Build Coastguard Worker             return;
6931*38e8c45fSAndroid Build Coastguard Worker         }
6932*38e8c45fSAndroid Build Coastguard Worker         if (!display->isRefreshRateOverlayEnabled()) return;
6933*38e8c45fSAndroid Build Coastguard Worker 
6934*38e8c45fSAndroid Build Coastguard Worker         display->onVrrIdle(idle);
6935*38e8c45fSAndroid Build Coastguard Worker         mScheduler->scheduleFrame();
6936*38e8c45fSAndroid Build Coastguard Worker     }));
6937*38e8c45fSAndroid Build Coastguard Worker }
6938*38e8c45fSAndroid Build Coastguard Worker 
getKernelIdleTimerProperties(PhysicalDisplayId displayId)6939*38e8c45fSAndroid Build Coastguard Worker auto SurfaceFlinger::getKernelIdleTimerProperties(PhysicalDisplayId displayId)
6940*38e8c45fSAndroid Build Coastguard Worker         -> std::pair<std::optional<KernelIdleTimerController>, std::chrono::milliseconds> {
6941*38e8c45fSAndroid Build Coastguard Worker     const bool isKernelIdleTimerHwcSupported = getHwComposer().getComposer()->isSupported(
6942*38e8c45fSAndroid Build Coastguard Worker             android::Hwc2::Composer::OptionalFeature::KernelIdleTimer);
6943*38e8c45fSAndroid Build Coastguard Worker     const auto timeout = getIdleTimerTimeout(displayId);
6944*38e8c45fSAndroid Build Coastguard Worker     if (isKernelIdleTimerHwcSupported) {
6945*38e8c45fSAndroid Build Coastguard Worker         if (getHwComposer().hasDisplayIdleTimerCapability(displayId)) {
6946*38e8c45fSAndroid Build Coastguard Worker             // In order to decide if we can use the HWC api for idle timer
6947*38e8c45fSAndroid Build Coastguard Worker             // we query DisplayCapability::DISPLAY_IDLE_TIMER directly on the composer
6948*38e8c45fSAndroid Build Coastguard Worker             // without relying on hasDisplayCapability.
6949*38e8c45fSAndroid Build Coastguard Worker             // hasDisplayCapability relies on DisplayCapabilities
6950*38e8c45fSAndroid Build Coastguard Worker             // which are updated after we set the PowerMode::ON.
6951*38e8c45fSAndroid Build Coastguard Worker             // DISPLAY_IDLE_TIMER is a display driver property
6952*38e8c45fSAndroid Build Coastguard Worker             // and is available before the PowerMode::ON
6953*38e8c45fSAndroid Build Coastguard Worker             return {KernelIdleTimerController::HwcApi, timeout};
6954*38e8c45fSAndroid Build Coastguard Worker         }
6955*38e8c45fSAndroid Build Coastguard Worker         return {std::nullopt, timeout};
6956*38e8c45fSAndroid Build Coastguard Worker     }
6957*38e8c45fSAndroid Build Coastguard Worker     if (getKernelIdleTimerSyspropConfig(displayId)) {
6958*38e8c45fSAndroid Build Coastguard Worker         return {KernelIdleTimerController::Sysprop, timeout};
6959*38e8c45fSAndroid Build Coastguard Worker     }
6960*38e8c45fSAndroid Build Coastguard Worker 
6961*38e8c45fSAndroid Build Coastguard Worker     return {std::nullopt, timeout};
6962*38e8c45fSAndroid Build Coastguard Worker }
6963*38e8c45fSAndroid Build Coastguard Worker 
6964*38e8c45fSAndroid Build Coastguard Worker // A simple RAII class to disconnect from an ANativeWindow* when it goes out of scope
6965*38e8c45fSAndroid Build Coastguard Worker class WindowDisconnector {
6966*38e8c45fSAndroid Build Coastguard Worker public:
WindowDisconnector(ANativeWindow * window,int api)6967*38e8c45fSAndroid Build Coastguard Worker     WindowDisconnector(ANativeWindow* window, int api) : mWindow(window), mApi(api) {}
~WindowDisconnector()6968*38e8c45fSAndroid Build Coastguard Worker     ~WindowDisconnector() {
6969*38e8c45fSAndroid Build Coastguard Worker         native_window_api_disconnect(mWindow, mApi);
6970*38e8c45fSAndroid Build Coastguard Worker     }
6971*38e8c45fSAndroid Build Coastguard Worker 
6972*38e8c45fSAndroid Build Coastguard Worker private:
6973*38e8c45fSAndroid Build Coastguard Worker     ANativeWindow* mWindow;
6974*38e8c45fSAndroid Build Coastguard Worker     const int mApi;
6975*38e8c45fSAndroid Build Coastguard Worker };
6976*38e8c45fSAndroid Build Coastguard Worker 
hasCaptureBlackoutContentPermission()6977*38e8c45fSAndroid Build Coastguard Worker static bool hasCaptureBlackoutContentPermission() {
6978*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
6979*38e8c45fSAndroid Build Coastguard Worker     const int pid = ipc->getCallingPid();
6980*38e8c45fSAndroid Build Coastguard Worker     const int uid = ipc->getCallingUid();
6981*38e8c45fSAndroid Build Coastguard Worker     return uid == AID_GRAPHICS || uid == AID_SYSTEM ||
6982*38e8c45fSAndroid Build Coastguard Worker             PermissionCache::checkPermission(sCaptureBlackoutContent, pid, uid);
6983*38e8c45fSAndroid Build Coastguard Worker }
6984*38e8c45fSAndroid Build Coastguard Worker 
validateScreenshotPermissions(const CaptureArgs & captureArgs)6985*38e8c45fSAndroid Build Coastguard Worker static status_t validateScreenshotPermissions(const CaptureArgs& captureArgs) {
6986*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
6987*38e8c45fSAndroid Build Coastguard Worker     const int pid = ipc->getCallingPid();
6988*38e8c45fSAndroid Build Coastguard Worker     const int uid = ipc->getCallingUid();
6989*38e8c45fSAndroid Build Coastguard Worker     if (uid == AID_GRAPHICS || uid == AID_SYSTEM ||
6990*38e8c45fSAndroid Build Coastguard Worker         PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
6991*38e8c45fSAndroid Build Coastguard Worker         return OK;
6992*38e8c45fSAndroid Build Coastguard Worker     }
6993*38e8c45fSAndroid Build Coastguard Worker 
6994*38e8c45fSAndroid Build Coastguard Worker     // If the caller doesn't have the correct permissions but is only attempting to screenshot
6995*38e8c45fSAndroid Build Coastguard Worker     // itself, we allow it to continue.
6996*38e8c45fSAndroid Build Coastguard Worker     if (captureArgs.uid == uid) {
6997*38e8c45fSAndroid Build Coastguard Worker         return OK;
6998*38e8c45fSAndroid Build Coastguard Worker     }
6999*38e8c45fSAndroid Build Coastguard Worker 
7000*38e8c45fSAndroid Build Coastguard Worker     ALOGE("Permission Denial: can't take screenshot pid=%d, uid=%d", pid, uid);
7001*38e8c45fSAndroid Build Coastguard Worker     return PERMISSION_DENIED;
7002*38e8c45fSAndroid Build Coastguard Worker }
7003*38e8c45fSAndroid Build Coastguard Worker 
setSchedFifo(bool enabled)7004*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setSchedFifo(bool enabled) {
7005*38e8c45fSAndroid Build Coastguard Worker     static constexpr int kFifoPriority = 2;
7006*38e8c45fSAndroid Build Coastguard Worker     static constexpr int kOtherPriority = 0;
7007*38e8c45fSAndroid Build Coastguard Worker 
7008*38e8c45fSAndroid Build Coastguard Worker     struct sched_param param = {0};
7009*38e8c45fSAndroid Build Coastguard Worker     int sched_policy;
7010*38e8c45fSAndroid Build Coastguard Worker     if (enabled) {
7011*38e8c45fSAndroid Build Coastguard Worker         sched_policy = SCHED_FIFO;
7012*38e8c45fSAndroid Build Coastguard Worker         param.sched_priority = kFifoPriority;
7013*38e8c45fSAndroid Build Coastguard Worker     } else {
7014*38e8c45fSAndroid Build Coastguard Worker         sched_policy = SCHED_OTHER;
7015*38e8c45fSAndroid Build Coastguard Worker         param.sched_priority = kOtherPriority;
7016*38e8c45fSAndroid Build Coastguard Worker     }
7017*38e8c45fSAndroid Build Coastguard Worker 
7018*38e8c45fSAndroid Build Coastguard Worker     if (sched_setscheduler(0, sched_policy, &param) != 0) {
7019*38e8c45fSAndroid Build Coastguard Worker         return -errno;
7020*38e8c45fSAndroid Build Coastguard Worker     }
7021*38e8c45fSAndroid Build Coastguard Worker 
7022*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
7023*38e8c45fSAndroid Build Coastguard Worker }
7024*38e8c45fSAndroid Build Coastguard Worker 
setSchedAttr(bool enabled)7025*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setSchedAttr(bool enabled) {
7026*38e8c45fSAndroid Build Coastguard Worker     static const unsigned int kUclampMin =
7027*38e8c45fSAndroid Build Coastguard Worker             base::GetUintProperty<unsigned int>("ro.surface_flinger.uclamp.min"s, 0U);
7028*38e8c45fSAndroid Build Coastguard Worker 
7029*38e8c45fSAndroid Build Coastguard Worker     if (!kUclampMin) {
7030*38e8c45fSAndroid Build Coastguard Worker         // uclamp.min set to 0 (default), skip setting
7031*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
7032*38e8c45fSAndroid Build Coastguard Worker     }
7033*38e8c45fSAndroid Build Coastguard Worker 
7034*38e8c45fSAndroid Build Coastguard Worker     sched_attr attr = {};
7035*38e8c45fSAndroid Build Coastguard Worker     attr.size = sizeof(attr);
7036*38e8c45fSAndroid Build Coastguard Worker 
7037*38e8c45fSAndroid Build Coastguard Worker     attr.sched_flags = (SCHED_FLAG_KEEP_ALL | SCHED_FLAG_UTIL_CLAMP);
7038*38e8c45fSAndroid Build Coastguard Worker     attr.sched_util_min = enabled ? kUclampMin : 0;
7039*38e8c45fSAndroid Build Coastguard Worker     attr.sched_util_max = 1024;
7040*38e8c45fSAndroid Build Coastguard Worker 
7041*38e8c45fSAndroid Build Coastguard Worker     if (syscall(__NR_sched_setattr, 0, &attr, 0)) {
7042*38e8c45fSAndroid Build Coastguard Worker         return -errno;
7043*38e8c45fSAndroid Build Coastguard Worker     }
7044*38e8c45fSAndroid Build Coastguard Worker 
7045*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
7046*38e8c45fSAndroid Build Coastguard Worker }
7047*38e8c45fSAndroid Build Coastguard Worker 
7048*38e8c45fSAndroid Build Coastguard Worker namespace {
7049*38e8c45fSAndroid Build Coastguard Worker 
pickBestDataspace(ui::Dataspace requestedDataspace,const compositionengine::impl::OutputCompositionState & state,bool capturingHdrLayers,bool hintForSeamlessTransition)7050*38e8c45fSAndroid Build Coastguard Worker ui::Dataspace pickBestDataspace(ui::Dataspace requestedDataspace,
7051*38e8c45fSAndroid Build Coastguard Worker                                 const compositionengine::impl::OutputCompositionState& state,
7052*38e8c45fSAndroid Build Coastguard Worker                                 bool capturingHdrLayers, bool hintForSeamlessTransition) {
7053*38e8c45fSAndroid Build Coastguard Worker     if (requestedDataspace != ui::Dataspace::UNKNOWN) {
7054*38e8c45fSAndroid Build Coastguard Worker         return requestedDataspace;
7055*38e8c45fSAndroid Build Coastguard Worker     }
7056*38e8c45fSAndroid Build Coastguard Worker 
7057*38e8c45fSAndroid Build Coastguard Worker     const auto dataspaceForColorMode = ui::pickDataspaceFor(state.colorMode);
7058*38e8c45fSAndroid Build Coastguard Worker 
7059*38e8c45fSAndroid Build Coastguard Worker     // TODO: Enable once HDR screenshots are ready.
7060*38e8c45fSAndroid Build Coastguard Worker     if constexpr (/* DISABLES CODE */ (false)) {
7061*38e8c45fSAndroid Build Coastguard Worker         // For now since we only support 8-bit screenshots, just use HLG and
7062*38e8c45fSAndroid Build Coastguard Worker         // assume that 1.0 >= display max luminance. This isn't quite as future
7063*38e8c45fSAndroid Build Coastguard Worker         // proof as PQ is, but is good enough.
7064*38e8c45fSAndroid Build Coastguard Worker         // Consider using PQ once we support 16-bit screenshots and we're able
7065*38e8c45fSAndroid Build Coastguard Worker         // to consistently supply metadata to image encoders.
7066*38e8c45fSAndroid Build Coastguard Worker         return ui::Dataspace::BT2020_HLG;
7067*38e8c45fSAndroid Build Coastguard Worker     }
7068*38e8c45fSAndroid Build Coastguard Worker 
7069*38e8c45fSAndroid Build Coastguard Worker     return dataspaceForColorMode;
7070*38e8c45fSAndroid Build Coastguard Worker }
7071*38e8c45fSAndroid Build Coastguard Worker 
7072*38e8c45fSAndroid Build Coastguard Worker } // namespace
7073*38e8c45fSAndroid Build Coastguard Worker 
invokeScreenCaptureError(const status_t status,const sp<IScreenCaptureListener> & captureListener)7074*38e8c45fSAndroid Build Coastguard Worker static void invokeScreenCaptureError(const status_t status,
7075*38e8c45fSAndroid Build Coastguard Worker                                      const sp<IScreenCaptureListener>& captureListener) {
7076*38e8c45fSAndroid Build Coastguard Worker     ScreenCaptureResults captureResults;
7077*38e8c45fSAndroid Build Coastguard Worker     captureResults.fenceResult = base::unexpected(status);
7078*38e8c45fSAndroid Build Coastguard Worker     captureListener->onScreenCaptureCompleted(captureResults);
7079*38e8c45fSAndroid Build Coastguard Worker }
7080*38e8c45fSAndroid Build Coastguard Worker 
captureDisplay(const DisplayCaptureArgs & args,const sp<IScreenCaptureListener> & captureListener)7081*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args,
7082*38e8c45fSAndroid Build Coastguard Worker                                     const sp<IScreenCaptureListener>& captureListener) {
7083*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
7084*38e8c45fSAndroid Build Coastguard Worker 
7085*38e8c45fSAndroid Build Coastguard Worker     const auto& captureArgs = args.captureArgs;
7086*38e8c45fSAndroid Build Coastguard Worker     status_t validate = validateScreenshotPermissions(captureArgs);
7087*38e8c45fSAndroid Build Coastguard Worker     if (validate != OK) {
7088*38e8c45fSAndroid Build Coastguard Worker         ALOGD("Permission denied to captureDisplay");
7089*38e8c45fSAndroid Build Coastguard Worker         invokeScreenCaptureError(validate, captureListener);
7090*38e8c45fSAndroid Build Coastguard Worker         return;
7091*38e8c45fSAndroid Build Coastguard Worker     }
7092*38e8c45fSAndroid Build Coastguard Worker 
7093*38e8c45fSAndroid Build Coastguard Worker     if (!args.displayToken) {
7094*38e8c45fSAndroid Build Coastguard Worker         ALOGD("Invalid display token to captureDisplay");
7095*38e8c45fSAndroid Build Coastguard Worker         invokeScreenCaptureError(BAD_VALUE, captureListener);
7096*38e8c45fSAndroid Build Coastguard Worker         return;
7097*38e8c45fSAndroid Build Coastguard Worker     }
7098*38e8c45fSAndroid Build Coastguard Worker 
7099*38e8c45fSAndroid Build Coastguard Worker     if (captureArgs.captureSecureLayers && !hasCaptureBlackoutContentPermission()) {
7100*38e8c45fSAndroid Build Coastguard Worker         ALOGD("Attempting to capture secure layers without CAPTURE_BLACKOUT_CONTENT");
7101*38e8c45fSAndroid Build Coastguard Worker         invokeScreenCaptureError(PERMISSION_DENIED, captureListener);
7102*38e8c45fSAndroid Build Coastguard Worker         return;
7103*38e8c45fSAndroid Build Coastguard Worker     }
7104*38e8c45fSAndroid Build Coastguard Worker 
7105*38e8c45fSAndroid Build Coastguard Worker     wp<const DisplayDevice> displayWeak;
7106*38e8c45fSAndroid Build Coastguard Worker     ui::LayerStack layerStack;
7107*38e8c45fSAndroid Build Coastguard Worker     ui::Size reqSize(args.width, args.height);
7108*38e8c45fSAndroid Build Coastguard Worker     std::unordered_set<uint32_t> excludeLayerIds;
7109*38e8c45fSAndroid Build Coastguard Worker     {
7110*38e8c45fSAndroid Build Coastguard Worker         Mutex::Autolock lock(mStateLock);
7111*38e8c45fSAndroid Build Coastguard Worker         sp<DisplayDevice> display = getDisplayDeviceLocked(args.displayToken);
7112*38e8c45fSAndroid Build Coastguard Worker         if (!display) {
7113*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Unable to find display device for captureDisplay");
7114*38e8c45fSAndroid Build Coastguard Worker             invokeScreenCaptureError(NAME_NOT_FOUND, captureListener);
7115*38e8c45fSAndroid Build Coastguard Worker             return;
7116*38e8c45fSAndroid Build Coastguard Worker         }
7117*38e8c45fSAndroid Build Coastguard Worker         displayWeak = display;
7118*38e8c45fSAndroid Build Coastguard Worker         layerStack = display->getLayerStack();
7119*38e8c45fSAndroid Build Coastguard Worker 
7120*38e8c45fSAndroid Build Coastguard Worker         // set the requested width/height to the logical display layer stack rect size by default
7121*38e8c45fSAndroid Build Coastguard Worker         if (args.width == 0 || args.height == 0) {
7122*38e8c45fSAndroid Build Coastguard Worker             reqSize = display->getLayerStackSpaceRect().getSize();
7123*38e8c45fSAndroid Build Coastguard Worker         }
7124*38e8c45fSAndroid Build Coastguard Worker 
7125*38e8c45fSAndroid Build Coastguard Worker         for (const auto& handle : captureArgs.excludeHandles) {
7126*38e8c45fSAndroid Build Coastguard Worker             uint32_t excludeLayer = LayerHandle::getLayerId(handle);
7127*38e8c45fSAndroid Build Coastguard Worker             if (excludeLayer != UNASSIGNED_LAYER_ID) {
7128*38e8c45fSAndroid Build Coastguard Worker                 excludeLayerIds.emplace(excludeLayer);
7129*38e8c45fSAndroid Build Coastguard Worker             } else {
7130*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("Invalid layer handle passed as excludeLayer to captureDisplay");
7131*38e8c45fSAndroid Build Coastguard Worker                 invokeScreenCaptureError(NAME_NOT_FOUND, captureListener);
7132*38e8c45fSAndroid Build Coastguard Worker                 return;
7133*38e8c45fSAndroid Build Coastguard Worker             }
7134*38e8c45fSAndroid Build Coastguard Worker         }
7135*38e8c45fSAndroid Build Coastguard Worker     }
7136*38e8c45fSAndroid Build Coastguard Worker 
7137*38e8c45fSAndroid Build Coastguard Worker     GetLayerSnapshotsFunction getLayerSnapshotsFn =
7138*38e8c45fSAndroid Build Coastguard Worker             getLayerSnapshotsForScreenshots(layerStack, captureArgs.uid,
7139*38e8c45fSAndroid Build Coastguard Worker                                             std::move(excludeLayerIds));
7140*38e8c45fSAndroid Build Coastguard Worker 
7141*38e8c45fSAndroid Build Coastguard Worker     ftl::Flags<RenderArea::Options> options;
7142*38e8c45fSAndroid Build Coastguard Worker     if (captureArgs.captureSecureLayers) options |= RenderArea::Options::CAPTURE_SECURE_LAYERS;
7143*38e8c45fSAndroid Build Coastguard Worker     if (captureArgs.hintForSeamlessTransition)
7144*38e8c45fSAndroid Build Coastguard Worker         options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION;
7145*38e8c45fSAndroid Build Coastguard Worker     captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<DisplayRenderAreaBuilder>,
7146*38e8c45fSAndroid Build Coastguard Worker                                                  gui::aidl_utils::fromARect(captureArgs.sourceCrop),
7147*38e8c45fSAndroid Build Coastguard Worker                                                  reqSize,
7148*38e8c45fSAndroid Build Coastguard Worker                                                  static_cast<ui::Dataspace>(captureArgs.dataspace),
7149*38e8c45fSAndroid Build Coastguard Worker                                                  displayWeak, options),
7150*38e8c45fSAndroid Build Coastguard Worker                         getLayerSnapshotsFn, reqSize,
7151*38e8c45fSAndroid Build Coastguard Worker                         static_cast<ui::PixelFormat>(captureArgs.pixelFormat),
7152*38e8c45fSAndroid Build Coastguard Worker                         captureArgs.allowProtected, captureArgs.grayscale,
7153*38e8c45fSAndroid Build Coastguard Worker                         captureArgs.attachGainmap, captureListener);
7154*38e8c45fSAndroid Build Coastguard Worker }
7155*38e8c45fSAndroid Build Coastguard Worker 
captureDisplay(DisplayId displayId,const CaptureArgs & args,const sp<IScreenCaptureListener> & captureListener)7156*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args,
7157*38e8c45fSAndroid Build Coastguard Worker                                     const sp<IScreenCaptureListener>& captureListener) {
7158*38e8c45fSAndroid Build Coastguard Worker     ui::LayerStack layerStack;
7159*38e8c45fSAndroid Build Coastguard Worker     wp<const DisplayDevice> displayWeak;
7160*38e8c45fSAndroid Build Coastguard Worker     ui::Size size;
7161*38e8c45fSAndroid Build Coastguard Worker     {
7162*38e8c45fSAndroid Build Coastguard Worker         Mutex::Autolock lock(mStateLock);
7163*38e8c45fSAndroid Build Coastguard Worker 
7164*38e8c45fSAndroid Build Coastguard Worker         const auto display = getDisplayDeviceLocked(displayId);
7165*38e8c45fSAndroid Build Coastguard Worker         if (!display) {
7166*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Unable to find display device for captureDisplay");
7167*38e8c45fSAndroid Build Coastguard Worker             invokeScreenCaptureError(NAME_NOT_FOUND, captureListener);
7168*38e8c45fSAndroid Build Coastguard Worker             return;
7169*38e8c45fSAndroid Build Coastguard Worker         }
7170*38e8c45fSAndroid Build Coastguard Worker 
7171*38e8c45fSAndroid Build Coastguard Worker         displayWeak = display;
7172*38e8c45fSAndroid Build Coastguard Worker         layerStack = display->getLayerStack();
7173*38e8c45fSAndroid Build Coastguard Worker         size = display->getLayerStackSpaceRect().getSize();
7174*38e8c45fSAndroid Build Coastguard Worker     }
7175*38e8c45fSAndroid Build Coastguard Worker 
7176*38e8c45fSAndroid Build Coastguard Worker     size.width *= args.frameScaleX;
7177*38e8c45fSAndroid Build Coastguard Worker     size.height *= args.frameScaleY;
7178*38e8c45fSAndroid Build Coastguard Worker 
7179*38e8c45fSAndroid Build Coastguard Worker     // We could query a real value for this but it'll be a long, long time until we support
7180*38e8c45fSAndroid Build Coastguard Worker     // displays that need upwards of 1GB per buffer so...
7181*38e8c45fSAndroid Build Coastguard Worker     constexpr auto kMaxTextureSize = 16384;
7182*38e8c45fSAndroid Build Coastguard Worker     if (size.width <= 0 || size.height <= 0 || size.width >= kMaxTextureSize ||
7183*38e8c45fSAndroid Build Coastguard Worker         size.height >= kMaxTextureSize) {
7184*38e8c45fSAndroid Build Coastguard Worker         ALOGD("captureDisplay resolved to invalid size %d x %d", size.width, size.height);
7185*38e8c45fSAndroid Build Coastguard Worker         invokeScreenCaptureError(BAD_VALUE, captureListener);
7186*38e8c45fSAndroid Build Coastguard Worker         return;
7187*38e8c45fSAndroid Build Coastguard Worker     }
7188*38e8c45fSAndroid Build Coastguard Worker 
7189*38e8c45fSAndroid Build Coastguard Worker     GetLayerSnapshotsFunction getLayerSnapshotsFn =
7190*38e8c45fSAndroid Build Coastguard Worker             getLayerSnapshotsForScreenshots(layerStack, CaptureArgs::UNSET_UID,
7191*38e8c45fSAndroid Build Coastguard Worker                                             /*snapshotFilterFn=*/nullptr);
7192*38e8c45fSAndroid Build Coastguard Worker 
7193*38e8c45fSAndroid Build Coastguard Worker     if (captureListener == nullptr) {
7194*38e8c45fSAndroid Build Coastguard Worker         ALOGE("capture screen must provide a capture listener callback");
7195*38e8c45fSAndroid Build Coastguard Worker         invokeScreenCaptureError(BAD_VALUE, captureListener);
7196*38e8c45fSAndroid Build Coastguard Worker         return;
7197*38e8c45fSAndroid Build Coastguard Worker     }
7198*38e8c45fSAndroid Build Coastguard Worker 
7199*38e8c45fSAndroid Build Coastguard Worker     constexpr bool kAllowProtected = false;
7200*38e8c45fSAndroid Build Coastguard Worker     constexpr bool kGrayscale = false;
7201*38e8c45fSAndroid Build Coastguard Worker 
7202*38e8c45fSAndroid Build Coastguard Worker     ftl::Flags<RenderArea::Options> options;
7203*38e8c45fSAndroid Build Coastguard Worker     if (args.hintForSeamlessTransition)
7204*38e8c45fSAndroid Build Coastguard Worker         options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION;
7205*38e8c45fSAndroid Build Coastguard Worker     captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<DisplayRenderAreaBuilder>,
7206*38e8c45fSAndroid Build Coastguard Worker                                                  Rect(), size,
7207*38e8c45fSAndroid Build Coastguard Worker                                                  static_cast<ui::Dataspace>(args.dataspace),
7208*38e8c45fSAndroid Build Coastguard Worker                                                  displayWeak, options),
7209*38e8c45fSAndroid Build Coastguard Worker                         getLayerSnapshotsFn, size, static_cast<ui::PixelFormat>(args.pixelFormat),
7210*38e8c45fSAndroid Build Coastguard Worker                         kAllowProtected, kGrayscale, args.attachGainmap, captureListener);
7211*38e8c45fSAndroid Build Coastguard Worker }
7212*38e8c45fSAndroid Build Coastguard Worker 
captureLayersSync(const LayerCaptureArgs & args)7213*38e8c45fSAndroid Build Coastguard Worker ScreenCaptureResults SurfaceFlinger::captureLayersSync(const LayerCaptureArgs& args) {
7214*38e8c45fSAndroid Build Coastguard Worker     sp<SyncScreenCaptureListener> captureListener = sp<SyncScreenCaptureListener>::make();
7215*38e8c45fSAndroid Build Coastguard Worker     captureLayers(args, captureListener);
7216*38e8c45fSAndroid Build Coastguard Worker     return captureListener->waitForResults();
7217*38e8c45fSAndroid Build Coastguard Worker }
7218*38e8c45fSAndroid Build Coastguard Worker 
captureLayers(const LayerCaptureArgs & args,const sp<IScreenCaptureListener> & captureListener)7219*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args,
7220*38e8c45fSAndroid Build Coastguard Worker                                    const sp<IScreenCaptureListener>& captureListener) {
7221*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
7222*38e8c45fSAndroid Build Coastguard Worker 
7223*38e8c45fSAndroid Build Coastguard Worker     const auto& captureArgs = args.captureArgs;
7224*38e8c45fSAndroid Build Coastguard Worker 
7225*38e8c45fSAndroid Build Coastguard Worker     status_t validate = validateScreenshotPermissions(captureArgs);
7226*38e8c45fSAndroid Build Coastguard Worker     if (validate != OK) {
7227*38e8c45fSAndroid Build Coastguard Worker         ALOGD("Permission denied to captureLayers");
7228*38e8c45fSAndroid Build Coastguard Worker         invokeScreenCaptureError(validate, captureListener);
7229*38e8c45fSAndroid Build Coastguard Worker         return;
7230*38e8c45fSAndroid Build Coastguard Worker     }
7231*38e8c45fSAndroid Build Coastguard Worker 
7232*38e8c45fSAndroid Build Coastguard Worker     auto crop = gui::aidl_utils::fromARect(captureArgs.sourceCrop);
7233*38e8c45fSAndroid Build Coastguard Worker 
7234*38e8c45fSAndroid Build Coastguard Worker     ui::Size reqSize;
7235*38e8c45fSAndroid Build Coastguard Worker     sp<Layer> parent;
7236*38e8c45fSAndroid Build Coastguard Worker     std::unordered_set<uint32_t> excludeLayerIds;
7237*38e8c45fSAndroid Build Coastguard Worker     ui::Dataspace dataspace = static_cast<ui::Dataspace>(captureArgs.dataspace);
7238*38e8c45fSAndroid Build Coastguard Worker 
7239*38e8c45fSAndroid Build Coastguard Worker     if (captureArgs.captureSecureLayers && !hasCaptureBlackoutContentPermission()) {
7240*38e8c45fSAndroid Build Coastguard Worker         ALOGD("Attempting to capture secure layers without CAPTURE_BLACKOUT_CONTENT");
7241*38e8c45fSAndroid Build Coastguard Worker         invokeScreenCaptureError(PERMISSION_DENIED, captureListener);
7242*38e8c45fSAndroid Build Coastguard Worker         return;
7243*38e8c45fSAndroid Build Coastguard Worker     }
7244*38e8c45fSAndroid Build Coastguard Worker 
7245*38e8c45fSAndroid Build Coastguard Worker     {
7246*38e8c45fSAndroid Build Coastguard Worker         Mutex::Autolock lock(mStateLock);
7247*38e8c45fSAndroid Build Coastguard Worker 
7248*38e8c45fSAndroid Build Coastguard Worker         parent = LayerHandle::getLayer(args.layerHandle);
7249*38e8c45fSAndroid Build Coastguard Worker         if (parent == nullptr) {
7250*38e8c45fSAndroid Build Coastguard Worker             ALOGD("captureLayers called with an invalid or removed parent");
7251*38e8c45fSAndroid Build Coastguard Worker             invokeScreenCaptureError(NAME_NOT_FOUND, captureListener);
7252*38e8c45fSAndroid Build Coastguard Worker             return;
7253*38e8c45fSAndroid Build Coastguard Worker         }
7254*38e8c45fSAndroid Build Coastguard Worker 
7255*38e8c45fSAndroid Build Coastguard Worker         Rect parentSourceBounds = parent->getCroppedBufferSize(parent->getDrawingState());
7256*38e8c45fSAndroid Build Coastguard Worker         if (crop.width() <= 0) {
7257*38e8c45fSAndroid Build Coastguard Worker             crop.left = 0;
7258*38e8c45fSAndroid Build Coastguard Worker             crop.right = parentSourceBounds.getWidth();
7259*38e8c45fSAndroid Build Coastguard Worker         }
7260*38e8c45fSAndroid Build Coastguard Worker 
7261*38e8c45fSAndroid Build Coastguard Worker         if (crop.height() <= 0) {
7262*38e8c45fSAndroid Build Coastguard Worker             crop.top = 0;
7263*38e8c45fSAndroid Build Coastguard Worker             crop.bottom = parentSourceBounds.getHeight();
7264*38e8c45fSAndroid Build Coastguard Worker         }
7265*38e8c45fSAndroid Build Coastguard Worker 
7266*38e8c45fSAndroid Build Coastguard Worker         if (crop.isEmpty() || captureArgs.frameScaleX <= 0.0f || captureArgs.frameScaleY <= 0.0f) {
7267*38e8c45fSAndroid Build Coastguard Worker             // Error out if the layer has no source bounds (i.e. they are boundless) and a source
7268*38e8c45fSAndroid Build Coastguard Worker             // crop was not specified, or an invalid frame scale was provided.
7269*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Boundless layer, unspecified crop, or invalid frame scale to captureLayers");
7270*38e8c45fSAndroid Build Coastguard Worker             invokeScreenCaptureError(BAD_VALUE, captureListener);
7271*38e8c45fSAndroid Build Coastguard Worker             return;
7272*38e8c45fSAndroid Build Coastguard Worker         }
7273*38e8c45fSAndroid Build Coastguard Worker         reqSize = ui::Size(crop.width() * captureArgs.frameScaleX,
7274*38e8c45fSAndroid Build Coastguard Worker                            crop.height() * captureArgs.frameScaleY);
7275*38e8c45fSAndroid Build Coastguard Worker 
7276*38e8c45fSAndroid Build Coastguard Worker         for (const auto& handle : captureArgs.excludeHandles) {
7277*38e8c45fSAndroid Build Coastguard Worker             uint32_t excludeLayer = LayerHandle::getLayerId(handle);
7278*38e8c45fSAndroid Build Coastguard Worker             if (excludeLayer != UNASSIGNED_LAYER_ID) {
7279*38e8c45fSAndroid Build Coastguard Worker                 excludeLayerIds.emplace(excludeLayer);
7280*38e8c45fSAndroid Build Coastguard Worker             } else {
7281*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("Invalid layer handle passed as excludeLayer to captureLayers");
7282*38e8c45fSAndroid Build Coastguard Worker                 invokeScreenCaptureError(NAME_NOT_FOUND, captureListener);
7283*38e8c45fSAndroid Build Coastguard Worker                 return;
7284*38e8c45fSAndroid Build Coastguard Worker             }
7285*38e8c45fSAndroid Build Coastguard Worker         }
7286*38e8c45fSAndroid Build Coastguard Worker     } // mStateLock
7287*38e8c45fSAndroid Build Coastguard Worker 
7288*38e8c45fSAndroid Build Coastguard Worker     // really small crop or frameScale
7289*38e8c45fSAndroid Build Coastguard Worker     if (reqSize.width <= 0 || reqSize.height <= 0) {
7290*38e8c45fSAndroid Build Coastguard Worker         ALOGD("Failed to captureLayers: crop or scale too small");
7291*38e8c45fSAndroid Build Coastguard Worker         invokeScreenCaptureError(BAD_VALUE, captureListener);
7292*38e8c45fSAndroid Build Coastguard Worker         return;
7293*38e8c45fSAndroid Build Coastguard Worker     }
7294*38e8c45fSAndroid Build Coastguard Worker 
7295*38e8c45fSAndroid Build Coastguard Worker     std::optional<FloatRect> parentCrop = std::nullopt;
7296*38e8c45fSAndroid Build Coastguard Worker     if (args.childrenOnly) {
7297*38e8c45fSAndroid Build Coastguard Worker         parentCrop = crop.isEmpty() ? FloatRect(0, 0, reqSize.width, reqSize.height)
7298*38e8c45fSAndroid Build Coastguard Worker                                     : crop.toFloatRect();
7299*38e8c45fSAndroid Build Coastguard Worker     }
7300*38e8c45fSAndroid Build Coastguard Worker 
7301*38e8c45fSAndroid Build Coastguard Worker     GetLayerSnapshotsFunction getLayerSnapshotsFn =
7302*38e8c45fSAndroid Build Coastguard Worker             getLayerSnapshotsForScreenshots(parent->sequence, captureArgs.uid,
7303*38e8c45fSAndroid Build Coastguard Worker                                             std::move(excludeLayerIds), args.childrenOnly,
7304*38e8c45fSAndroid Build Coastguard Worker                                             parentCrop);
7305*38e8c45fSAndroid Build Coastguard Worker 
7306*38e8c45fSAndroid Build Coastguard Worker     if (captureListener == nullptr) {
7307*38e8c45fSAndroid Build Coastguard Worker         ALOGD("capture screen must provide a capture listener callback");
7308*38e8c45fSAndroid Build Coastguard Worker         invokeScreenCaptureError(BAD_VALUE, captureListener);
7309*38e8c45fSAndroid Build Coastguard Worker         return;
7310*38e8c45fSAndroid Build Coastguard Worker     }
7311*38e8c45fSAndroid Build Coastguard Worker 
7312*38e8c45fSAndroid Build Coastguard Worker     ftl::Flags<RenderArea::Options> options;
7313*38e8c45fSAndroid Build Coastguard Worker     if (captureArgs.captureSecureLayers) options |= RenderArea::Options::CAPTURE_SECURE_LAYERS;
7314*38e8c45fSAndroid Build Coastguard Worker     if (captureArgs.hintForSeamlessTransition)
7315*38e8c45fSAndroid Build Coastguard Worker         options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION;
7316*38e8c45fSAndroid Build Coastguard Worker     captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<LayerRenderAreaBuilder>, crop,
7317*38e8c45fSAndroid Build Coastguard Worker                                                  reqSize, dataspace, parent, args.childrenOnly,
7318*38e8c45fSAndroid Build Coastguard Worker                                                  options),
7319*38e8c45fSAndroid Build Coastguard Worker                         getLayerSnapshotsFn, reqSize,
7320*38e8c45fSAndroid Build Coastguard Worker                         static_cast<ui::PixelFormat>(captureArgs.pixelFormat),
7321*38e8c45fSAndroid Build Coastguard Worker                         captureArgs.allowProtected, captureArgs.grayscale,
7322*38e8c45fSAndroid Build Coastguard Worker                         captureArgs.attachGainmap, captureListener);
7323*38e8c45fSAndroid Build Coastguard Worker }
7324*38e8c45fSAndroid Build Coastguard Worker 
7325*38e8c45fSAndroid Build Coastguard Worker // Creates a Future release fence for a layer and keeps track of it in a list to
7326*38e8c45fSAndroid Build Coastguard Worker // release the buffer when the Future is complete. Calls from composittion
7327*38e8c45fSAndroid Build Coastguard Worker // involve needing to refresh the composition start time for stats.
attachReleaseFenceFutureToLayer(Layer * layer,LayerFE * layerFE,ui::LayerStack layerStack)7328*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::attachReleaseFenceFutureToLayer(Layer* layer, LayerFE* layerFE,
7329*38e8c45fSAndroid Build Coastguard Worker                                                      ui::LayerStack layerStack) {
7330*38e8c45fSAndroid Build Coastguard Worker     ftl::Future<FenceResult> futureFence = layerFE->createReleaseFenceFuture();
7331*38e8c45fSAndroid Build Coastguard Worker     layer->prepareReleaseCallbacks(std::move(futureFence), layerStack);
7332*38e8c45fSAndroid Build Coastguard Worker }
7333*38e8c45fSAndroid Build Coastguard Worker 
7334*38e8c45fSAndroid Build Coastguard Worker // Loop over all visible layers to see whether there's any protected layer. A protected layer is
7335*38e8c45fSAndroid Build Coastguard Worker // typically a layer with DRM contents, or have the GRALLOC_USAGE_PROTECTED set on the buffer.
7336*38e8c45fSAndroid Build Coastguard Worker // A protected layer has no implication on whether it's secure, which is explicitly set by
7337*38e8c45fSAndroid Build Coastguard Worker // application to avoid being screenshot or drawn via unsecure display.
layersHasProtectedLayer(const std::vector<std::pair<Layer *,sp<LayerFE>>> & layers) const7338*38e8c45fSAndroid Build Coastguard Worker bool SurfaceFlinger::layersHasProtectedLayer(
7339*38e8c45fSAndroid Build Coastguard Worker         const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) const {
7340*38e8c45fSAndroid Build Coastguard Worker     bool protectedLayerFound = false;
7341*38e8c45fSAndroid Build Coastguard Worker     for (auto& [_, layerFE] : layers) {
7342*38e8c45fSAndroid Build Coastguard Worker         protectedLayerFound |=
7343*38e8c45fSAndroid Build Coastguard Worker                 (layerFE->mSnapshot->isVisible && layerFE->mSnapshot->hasProtectedContent);
7344*38e8c45fSAndroid Build Coastguard Worker         if (protectedLayerFound) {
7345*38e8c45fSAndroid Build Coastguard Worker             break;
7346*38e8c45fSAndroid Build Coastguard Worker         }
7347*38e8c45fSAndroid Build Coastguard Worker     }
7348*38e8c45fSAndroid Build Coastguard Worker     return protectedLayerFound;
7349*38e8c45fSAndroid Build Coastguard Worker }
7350*38e8c45fSAndroid Build Coastguard Worker 
7351*38e8c45fSAndroid Build Coastguard Worker // Getting layer snapshots and display should take place on main thread.
7352*38e8c45fSAndroid Build Coastguard Worker // Accessing display requires mStateLock, and contention for this lock
7353*38e8c45fSAndroid Build Coastguard Worker // is reduced when grabbed from the main thread, thus also reducing
7354*38e8c45fSAndroid Build Coastguard Worker // risk of deadlocks.
getSnapshotsFromMainThread(RenderAreaBuilderVariant & renderAreaBuilder,GetLayerSnapshotsFunction getLayerSnapshotsFn,std::vector<std::pair<Layer *,sp<LayerFE>>> & layers)7355*38e8c45fSAndroid Build Coastguard Worker std::optional<SurfaceFlinger::OutputCompositionState> SurfaceFlinger::getSnapshotsFromMainThread(
7356*38e8c45fSAndroid Build Coastguard Worker         RenderAreaBuilderVariant& renderAreaBuilder, GetLayerSnapshotsFunction getLayerSnapshotsFn,
7357*38e8c45fSAndroid Build Coastguard Worker         std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) {
7358*38e8c45fSAndroid Build Coastguard Worker     return mScheduler
7359*38e8c45fSAndroid Build Coastguard Worker             ->schedule([=, this, &renderAreaBuilder, &layers]() REQUIRES(kMainThreadContext) {
7360*38e8c45fSAndroid Build Coastguard Worker                 SFTRACE_NAME("getSnapshotsFromMainThread");
7361*38e8c45fSAndroid Build Coastguard Worker                 layers = getLayerSnapshotsFn();
7362*38e8c45fSAndroid Build Coastguard Worker                 // Non-threaded RenderEngine eventually returns to the main thread a 2nd time
7363*38e8c45fSAndroid Build Coastguard Worker                 // to complete the screenshot. Release fences should only be added during the 2nd
7364*38e8c45fSAndroid Build Coastguard Worker                 // hop to main thread in order to avoid potential deadlocks from waiting for the
7365*38e8c45fSAndroid Build Coastguard Worker                 // the future fence to fire.
7366*38e8c45fSAndroid Build Coastguard Worker                 if (mRenderEngine->isThreaded()) {
7367*38e8c45fSAndroid Build Coastguard Worker                     for (auto& [layer, layerFE] : layers) {
7368*38e8c45fSAndroid Build Coastguard Worker                         attachReleaseFenceFutureToLayer(layer, layerFE.get(),
7369*38e8c45fSAndroid Build Coastguard Worker                                                         ui::INVALID_LAYER_STACK);
7370*38e8c45fSAndroid Build Coastguard Worker                     }
7371*38e8c45fSAndroid Build Coastguard Worker                 }
7372*38e8c45fSAndroid Build Coastguard Worker                 return getDisplayStateFromRenderAreaBuilder(renderAreaBuilder);
7373*38e8c45fSAndroid Build Coastguard Worker             })
7374*38e8c45fSAndroid Build Coastguard Worker             .get();
7375*38e8c45fSAndroid Build Coastguard Worker }
7376*38e8c45fSAndroid Build Coastguard Worker 
captureScreenCommon(RenderAreaBuilderVariant renderAreaBuilder,GetLayerSnapshotsFunction getLayerSnapshotsFn,ui::Size bufferSize,ui::PixelFormat reqPixelFormat,bool allowProtected,bool grayscale,bool attachGainmap,const sp<IScreenCaptureListener> & captureListener)7377*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuilder,
7378*38e8c45fSAndroid Build Coastguard Worker                                          GetLayerSnapshotsFunction getLayerSnapshotsFn,
7379*38e8c45fSAndroid Build Coastguard Worker                                          ui::Size bufferSize, ui::PixelFormat reqPixelFormat,
7380*38e8c45fSAndroid Build Coastguard Worker                                          bool allowProtected, bool grayscale, bool attachGainmap,
7381*38e8c45fSAndroid Build Coastguard Worker                                          const sp<IScreenCaptureListener>& captureListener) {
7382*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
7383*38e8c45fSAndroid Build Coastguard Worker 
7384*38e8c45fSAndroid Build Coastguard Worker     if (exceedsMaxRenderTargetSize(bufferSize.getWidth(), bufferSize.getHeight())) {
7385*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Attempted to capture screen with size (%" PRId32 ", %" PRId32
7386*38e8c45fSAndroid Build Coastguard Worker               ") that exceeds render target size limit.",
7387*38e8c45fSAndroid Build Coastguard Worker               bufferSize.getWidth(), bufferSize.getHeight());
7388*38e8c45fSAndroid Build Coastguard Worker         invokeScreenCaptureError(BAD_VALUE, captureListener);
7389*38e8c45fSAndroid Build Coastguard Worker         return;
7390*38e8c45fSAndroid Build Coastguard Worker     }
7391*38e8c45fSAndroid Build Coastguard Worker 
7392*38e8c45fSAndroid Build Coastguard Worker     std::vector<std::pair<Layer*, sp<LayerFE>>> layers;
7393*38e8c45fSAndroid Build Coastguard Worker     auto displayState = getSnapshotsFromMainThread(renderAreaBuilder, getLayerSnapshotsFn, layers);
7394*38e8c45fSAndroid Build Coastguard Worker 
7395*38e8c45fSAndroid Build Coastguard Worker     const bool supportsProtected = getRenderEngine().supportsProtectedContent();
7396*38e8c45fSAndroid Build Coastguard Worker     bool hasProtectedLayer = false;
7397*38e8c45fSAndroid Build Coastguard Worker     if (allowProtected && supportsProtected) {
7398*38e8c45fSAndroid Build Coastguard Worker         hasProtectedLayer = layersHasProtectedLayer(layers);
7399*38e8c45fSAndroid Build Coastguard Worker     }
7400*38e8c45fSAndroid Build Coastguard Worker     const bool isProtected = hasProtectedLayer && allowProtected && supportsProtected;
7401*38e8c45fSAndroid Build Coastguard Worker     const uint32_t usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER |
7402*38e8c45fSAndroid Build Coastguard Worker             GRALLOC_USAGE_HW_TEXTURE |
7403*38e8c45fSAndroid Build Coastguard Worker             (isProtected ? GRALLOC_USAGE_PROTECTED
7404*38e8c45fSAndroid Build Coastguard Worker                          : GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
7405*38e8c45fSAndroid Build Coastguard Worker     sp<GraphicBuffer> buffer =
7406*38e8c45fSAndroid Build Coastguard Worker             getFactory().createGraphicBuffer(bufferSize.getWidth(), bufferSize.getHeight(),
7407*38e8c45fSAndroid Build Coastguard Worker                                              static_cast<android_pixel_format>(reqPixelFormat),
7408*38e8c45fSAndroid Build Coastguard Worker                                              1 /* layerCount */, usage, "screenshot");
7409*38e8c45fSAndroid Build Coastguard Worker 
7410*38e8c45fSAndroid Build Coastguard Worker     const status_t bufferStatus = buffer->initCheck();
7411*38e8c45fSAndroid Build Coastguard Worker     if (bufferStatus != OK) {
7412*38e8c45fSAndroid Build Coastguard Worker         // Animations may end up being really janky, but don't crash here.
7413*38e8c45fSAndroid Build Coastguard Worker         // Otherwise an irreponsible process may cause an SF crash by allocating
7414*38e8c45fSAndroid Build Coastguard Worker         // too much.
7415*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: Buffer failed to allocate: %d", __func__, bufferStatus);
7416*38e8c45fSAndroid Build Coastguard Worker         invokeScreenCaptureError(bufferStatus, captureListener);
7417*38e8c45fSAndroid Build Coastguard Worker         return;
7418*38e8c45fSAndroid Build Coastguard Worker     }
7419*38e8c45fSAndroid Build Coastguard Worker     const std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared<
7420*38e8c45fSAndroid Build Coastguard Worker             renderengine::impl::ExternalTexture>(buffer, getRenderEngine(),
7421*38e8c45fSAndroid Build Coastguard Worker                                                  renderengine::impl::ExternalTexture::Usage::
7422*38e8c45fSAndroid Build Coastguard Worker                                                          WRITEABLE);
7423*38e8c45fSAndroid Build Coastguard Worker     auto futureFence =
7424*38e8c45fSAndroid Build Coastguard Worker             captureScreenshot(renderAreaBuilder, texture, false /* regionSampling */, grayscale,
7425*38e8c45fSAndroid Build Coastguard Worker                               isProtected, attachGainmap, captureListener, displayState, layers);
7426*38e8c45fSAndroid Build Coastguard Worker     futureFence.get();
7427*38e8c45fSAndroid Build Coastguard Worker }
7428*38e8c45fSAndroid Build Coastguard Worker 
7429*38e8c45fSAndroid Build Coastguard Worker std::optional<SurfaceFlinger::OutputCompositionState>
getDisplayStateFromRenderAreaBuilder(RenderAreaBuilderVariant & renderAreaBuilder)7430*38e8c45fSAndroid Build Coastguard Worker SurfaceFlinger::getDisplayStateFromRenderAreaBuilder(RenderAreaBuilderVariant& renderAreaBuilder) {
7431*38e8c45fSAndroid Build Coastguard Worker     sp<const DisplayDevice> display = nullptr;
7432*38e8c45fSAndroid Build Coastguard Worker     {
7433*38e8c45fSAndroid Build Coastguard Worker         Mutex::Autolock lock(mStateLock);
7434*38e8c45fSAndroid Build Coastguard Worker         if (auto* layerRenderAreaBuilder =
7435*38e8c45fSAndroid Build Coastguard Worker                     std::get_if<LayerRenderAreaBuilder>(&renderAreaBuilder)) {
7436*38e8c45fSAndroid Build Coastguard Worker             // LayerSnapshotBuilder should only be accessed from the main thread.
7437*38e8c45fSAndroid Build Coastguard Worker             const frontend::LayerSnapshot* snapshot =
7438*38e8c45fSAndroid Build Coastguard Worker                     mLayerSnapshotBuilder.getSnapshot(layerRenderAreaBuilder->layer->getSequence());
7439*38e8c45fSAndroid Build Coastguard Worker             if (!snapshot) {
7440*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("Couldn't find layer snapshot for %d",
7441*38e8c45fSAndroid Build Coastguard Worker                       layerRenderAreaBuilder->layer->getSequence());
7442*38e8c45fSAndroid Build Coastguard Worker             } else {
7443*38e8c45fSAndroid Build Coastguard Worker                 layerRenderAreaBuilder->setLayerSnapshot(*snapshot);
7444*38e8c45fSAndroid Build Coastguard Worker                 display = findDisplay(
7445*38e8c45fSAndroid Build Coastguard Worker                         [layerStack = snapshot->outputFilter.layerStack](const auto& display) {
7446*38e8c45fSAndroid Build Coastguard Worker                             return display.getLayerStack() == layerStack;
7447*38e8c45fSAndroid Build Coastguard Worker                         });
7448*38e8c45fSAndroid Build Coastguard Worker             }
7449*38e8c45fSAndroid Build Coastguard Worker         } else if (auto* displayRenderAreaBuilder =
7450*38e8c45fSAndroid Build Coastguard Worker                            std::get_if<DisplayRenderAreaBuilder>(&renderAreaBuilder)) {
7451*38e8c45fSAndroid Build Coastguard Worker             display = displayRenderAreaBuilder->displayWeak.promote();
7452*38e8c45fSAndroid Build Coastguard Worker         }
7453*38e8c45fSAndroid Build Coastguard Worker 
7454*38e8c45fSAndroid Build Coastguard Worker         if (display == nullptr) {
7455*38e8c45fSAndroid Build Coastguard Worker             display = getDefaultDisplayDeviceLocked();
7456*38e8c45fSAndroid Build Coastguard Worker         }
7457*38e8c45fSAndroid Build Coastguard Worker 
7458*38e8c45fSAndroid Build Coastguard Worker         if (display != nullptr) {
7459*38e8c45fSAndroid Build Coastguard Worker             return std::optional{display->getCompositionDisplay()->getState()};
7460*38e8c45fSAndroid Build Coastguard Worker         }
7461*38e8c45fSAndroid Build Coastguard Worker     }
7462*38e8c45fSAndroid Build Coastguard Worker     return std::nullopt;
7463*38e8c45fSAndroid Build Coastguard Worker }
7464*38e8c45fSAndroid Build Coastguard Worker 
captureScreenshot(const RenderAreaBuilderVariant & renderAreaBuilder,const std::shared_ptr<renderengine::ExternalTexture> & buffer,bool regionSampling,bool grayscale,bool isProtected,bool attachGainmap,const sp<IScreenCaptureListener> & captureListener,std::optional<OutputCompositionState> & displayState,std::vector<std::pair<Layer *,sp<LayerFE>>> & layers)7465*38e8c45fSAndroid Build Coastguard Worker ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot(
7466*38e8c45fSAndroid Build Coastguard Worker         const RenderAreaBuilderVariant& renderAreaBuilder,
7467*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling,
7468*38e8c45fSAndroid Build Coastguard Worker         bool grayscale, bool isProtected, bool attachGainmap,
7469*38e8c45fSAndroid Build Coastguard Worker         const sp<IScreenCaptureListener>& captureListener,
7470*38e8c45fSAndroid Build Coastguard Worker         std::optional<OutputCompositionState>& displayState,
7471*38e8c45fSAndroid Build Coastguard Worker         std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) {
7472*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
7473*38e8c45fSAndroid Build Coastguard Worker 
7474*38e8c45fSAndroid Build Coastguard Worker     ScreenCaptureResults captureResults;
7475*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<const RenderArea> renderArea =
7476*38e8c45fSAndroid Build Coastguard Worker             std::visit([](auto&& arg) -> std::unique_ptr<RenderArea> { return arg.build(); },
7477*38e8c45fSAndroid Build Coastguard Worker                        renderAreaBuilder);
7478*38e8c45fSAndroid Build Coastguard Worker 
7479*38e8c45fSAndroid Build Coastguard Worker     if (!renderArea) {
7480*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Skipping screen capture because of invalid render area.");
7481*38e8c45fSAndroid Build Coastguard Worker         if (captureListener) {
7482*38e8c45fSAndroid Build Coastguard Worker             captureResults.fenceResult = base::unexpected(NO_MEMORY);
7483*38e8c45fSAndroid Build Coastguard Worker             captureListener->onScreenCaptureCompleted(captureResults);
7484*38e8c45fSAndroid Build Coastguard Worker         }
7485*38e8c45fSAndroid Build Coastguard Worker         return ftl::yield<FenceResult>(base::unexpected(NO_ERROR)).share();
7486*38e8c45fSAndroid Build Coastguard Worker     }
7487*38e8c45fSAndroid Build Coastguard Worker     float displayBrightnessNits = displayState.value().displayBrightnessNits;
7488*38e8c45fSAndroid Build Coastguard Worker     float sdrWhitePointNits = displayState.value().sdrWhitePointNits;
7489*38e8c45fSAndroid Build Coastguard Worker 
7490*38e8c45fSAndroid Build Coastguard Worker     ftl::SharedFuture<FenceResult> renderFuture =
7491*38e8c45fSAndroid Build Coastguard Worker             renderScreenImpl(renderArea.get(), buffer, regionSampling, grayscale, isProtected,
7492*38e8c45fSAndroid Build Coastguard Worker                              captureResults, displayState, layers);
7493*38e8c45fSAndroid Build Coastguard Worker 
7494*38e8c45fSAndroid Build Coastguard Worker     if (captureResults.capturedHdrLayers && attachGainmap &&
7495*38e8c45fSAndroid Build Coastguard Worker         FlagManager::getInstance().true_hdr_screenshots()) {
7496*38e8c45fSAndroid Build Coastguard Worker         sp<GraphicBuffer> hdrBuffer =
7497*38e8c45fSAndroid Build Coastguard Worker                 getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(),
7498*38e8c45fSAndroid Build Coastguard Worker                                                  HAL_PIXEL_FORMAT_RGBA_FP16, 1 /* layerCount */,
7499*38e8c45fSAndroid Build Coastguard Worker                                                  buffer->getUsage(), "screenshot-hdr");
7500*38e8c45fSAndroid Build Coastguard Worker         sp<GraphicBuffer> gainmapBuffer =
7501*38e8c45fSAndroid Build Coastguard Worker                 getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(),
7502*38e8c45fSAndroid Build Coastguard Worker                                                  buffer->getPixelFormat(), 1 /* layerCount */,
7503*38e8c45fSAndroid Build Coastguard Worker                                                  buffer->getUsage(), "screenshot-gainmap");
7504*38e8c45fSAndroid Build Coastguard Worker 
7505*38e8c45fSAndroid Build Coastguard Worker         const status_t bufferStatus = hdrBuffer->initCheck();
7506*38e8c45fSAndroid Build Coastguard Worker         const status_t gainmapBufferStatus = gainmapBuffer->initCheck();
7507*38e8c45fSAndroid Build Coastguard Worker 
7508*38e8c45fSAndroid Build Coastguard Worker         if (bufferStatus != OK) {
7509*38e8c45fSAndroid Build Coastguard Worker             ALOGW("%s: Buffer failed to allocate for hdr: %d. Screenshoting SDR instead.", __func__,
7510*38e8c45fSAndroid Build Coastguard Worker                   bufferStatus);
7511*38e8c45fSAndroid Build Coastguard Worker         } else if (gainmapBufferStatus != OK) {
7512*38e8c45fSAndroid Build Coastguard Worker             ALOGW("%s: Buffer failed to allocate for gainmap: %d. Screenshoting SDR instead.",
7513*38e8c45fSAndroid Build Coastguard Worker                   __func__, gainmapBufferStatus);
7514*38e8c45fSAndroid Build Coastguard Worker         } else {
7515*38e8c45fSAndroid Build Coastguard Worker             captureResults.optionalGainMap = gainmapBuffer;
7516*38e8c45fSAndroid Build Coastguard Worker             const auto hdrTexture = std::make_shared<
7517*38e8c45fSAndroid Build Coastguard Worker                     renderengine::impl::ExternalTexture>(hdrBuffer, getRenderEngine(),
7518*38e8c45fSAndroid Build Coastguard Worker                                                          renderengine::impl::ExternalTexture::
7519*38e8c45fSAndroid Build Coastguard Worker                                                                  Usage::WRITEABLE);
7520*38e8c45fSAndroid Build Coastguard Worker             const auto gainmapTexture = std::make_shared<
7521*38e8c45fSAndroid Build Coastguard Worker                     renderengine::impl::ExternalTexture>(gainmapBuffer, getRenderEngine(),
7522*38e8c45fSAndroid Build Coastguard Worker                                                          renderengine::impl::ExternalTexture::
7523*38e8c45fSAndroid Build Coastguard Worker                                                                  Usage::WRITEABLE);
7524*38e8c45fSAndroid Build Coastguard Worker             ScreenCaptureResults unusedResults;
7525*38e8c45fSAndroid Build Coastguard Worker             ftl::SharedFuture<FenceResult> hdrRenderFuture =
7526*38e8c45fSAndroid Build Coastguard Worker                     renderScreenImpl(renderArea.get(), hdrTexture, regionSampling, grayscale,
7527*38e8c45fSAndroid Build Coastguard Worker                                      isProtected, unusedResults, displayState, layers);
7528*38e8c45fSAndroid Build Coastguard Worker 
7529*38e8c45fSAndroid Build Coastguard Worker             renderFuture =
7530*38e8c45fSAndroid Build Coastguard Worker                     ftl::Future(std::move(renderFuture))
7531*38e8c45fSAndroid Build Coastguard Worker                             .then([&, hdrRenderFuture = std::move(hdrRenderFuture),
7532*38e8c45fSAndroid Build Coastguard Worker                                    displayBrightnessNits, sdrWhitePointNits,
7533*38e8c45fSAndroid Build Coastguard Worker                                    dataspace = captureResults.capturedDataspace, buffer, hdrTexture,
7534*38e8c45fSAndroid Build Coastguard Worker                                    gainmapTexture](FenceResult fenceResult) -> FenceResult {
7535*38e8c45fSAndroid Build Coastguard Worker                                 if (!fenceResult.ok()) {
7536*38e8c45fSAndroid Build Coastguard Worker                                     return fenceResult;
7537*38e8c45fSAndroid Build Coastguard Worker                                 }
7538*38e8c45fSAndroid Build Coastguard Worker 
7539*38e8c45fSAndroid Build Coastguard Worker                                 auto hdrFenceResult = hdrRenderFuture.get();
7540*38e8c45fSAndroid Build Coastguard Worker 
7541*38e8c45fSAndroid Build Coastguard Worker                                 if (!hdrFenceResult.ok()) {
7542*38e8c45fSAndroid Build Coastguard Worker                                     return hdrFenceResult;
7543*38e8c45fSAndroid Build Coastguard Worker                                 }
7544*38e8c45fSAndroid Build Coastguard Worker 
7545*38e8c45fSAndroid Build Coastguard Worker                                 return getRenderEngine()
7546*38e8c45fSAndroid Build Coastguard Worker                                         .drawGainmap(buffer, fenceResult.value()->get(), hdrTexture,
7547*38e8c45fSAndroid Build Coastguard Worker                                                      hdrFenceResult.value()->get(),
7548*38e8c45fSAndroid Build Coastguard Worker                                                      displayBrightnessNits / sdrWhitePointNits,
7549*38e8c45fSAndroid Build Coastguard Worker                                                      static_cast<ui::Dataspace>(dataspace),
7550*38e8c45fSAndroid Build Coastguard Worker                                                      gainmapTexture)
7551*38e8c45fSAndroid Build Coastguard Worker                                         .get();
7552*38e8c45fSAndroid Build Coastguard Worker                             })
7553*38e8c45fSAndroid Build Coastguard Worker                             .share();
7554*38e8c45fSAndroid Build Coastguard Worker         };
7555*38e8c45fSAndroid Build Coastguard Worker     }
7556*38e8c45fSAndroid Build Coastguard Worker 
7557*38e8c45fSAndroid Build Coastguard Worker     if (captureListener) {
7558*38e8c45fSAndroid Build Coastguard Worker         // Defer blocking on renderFuture back to the Binder thread.
7559*38e8c45fSAndroid Build Coastguard Worker         return ftl::Future(std::move(renderFuture))
7560*38e8c45fSAndroid Build Coastguard Worker                 .then([captureListener, captureResults = std::move(captureResults),
7561*38e8c45fSAndroid Build Coastguard Worker                        displayBrightnessNits,
7562*38e8c45fSAndroid Build Coastguard Worker                        sdrWhitePointNits](FenceResult fenceResult) mutable -> FenceResult {
7563*38e8c45fSAndroid Build Coastguard Worker                     captureResults.fenceResult = std::move(fenceResult);
7564*38e8c45fSAndroid Build Coastguard Worker                     captureResults.hdrSdrRatio = displayBrightnessNits / sdrWhitePointNits;
7565*38e8c45fSAndroid Build Coastguard Worker                     captureListener->onScreenCaptureCompleted(captureResults);
7566*38e8c45fSAndroid Build Coastguard Worker                     return base::unexpected(NO_ERROR);
7567*38e8c45fSAndroid Build Coastguard Worker                 })
7568*38e8c45fSAndroid Build Coastguard Worker                 .share();
7569*38e8c45fSAndroid Build Coastguard Worker     }
7570*38e8c45fSAndroid Build Coastguard Worker     return renderFuture;
7571*38e8c45fSAndroid Build Coastguard Worker }
7572*38e8c45fSAndroid Build Coastguard Worker 
renderScreenImpl(const RenderArea * renderArea,const std::shared_ptr<renderengine::ExternalTexture> & buffer,bool regionSampling,bool grayscale,bool isProtected,ScreenCaptureResults & captureResults,std::optional<OutputCompositionState> & displayState,std::vector<std::pair<Layer *,sp<LayerFE>>> & layers)7573*38e8c45fSAndroid Build Coastguard Worker ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl(
7574*38e8c45fSAndroid Build Coastguard Worker         const RenderArea* renderArea, const std::shared_ptr<renderengine::ExternalTexture>& buffer,
7575*38e8c45fSAndroid Build Coastguard Worker         bool regionSampling, bool grayscale, bool isProtected, ScreenCaptureResults& captureResults,
7576*38e8c45fSAndroid Build Coastguard Worker         std::optional<OutputCompositionState>& displayState,
7577*38e8c45fSAndroid Build Coastguard Worker         std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) {
7578*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
7579*38e8c45fSAndroid Build Coastguard Worker 
7580*38e8c45fSAndroid Build Coastguard Worker     for (auto& [_, layerFE] : layers) {
7581*38e8c45fSAndroid Build Coastguard Worker         frontend::LayerSnapshot* snapshot = layerFE->mSnapshot.get();
7582*38e8c45fSAndroid Build Coastguard Worker         captureResults.capturedSecureLayers |= (snapshot->isVisible && snapshot->isSecure);
7583*38e8c45fSAndroid Build Coastguard Worker         captureResults.capturedHdrLayers |= isHdrLayer(*snapshot);
7584*38e8c45fSAndroid Build Coastguard Worker         layerFE->mSnapshot->geomLayerTransform =
7585*38e8c45fSAndroid Build Coastguard Worker                 renderArea->getTransform() * layerFE->mSnapshot->geomLayerTransform;
7586*38e8c45fSAndroid Build Coastguard Worker         layerFE->mSnapshot->geomInverseLayerTransform =
7587*38e8c45fSAndroid Build Coastguard Worker                 layerFE->mSnapshot->geomLayerTransform.inverse();
7588*38e8c45fSAndroid Build Coastguard Worker     }
7589*38e8c45fSAndroid Build Coastguard Worker 
7590*38e8c45fSAndroid Build Coastguard Worker     auto capturedBuffer = buffer;
7591*38e8c45fSAndroid Build Coastguard Worker 
7592*38e8c45fSAndroid Build Coastguard Worker     auto requestedDataspace = renderArea->getReqDataSpace();
7593*38e8c45fSAndroid Build Coastguard Worker     auto parent = renderArea->getParentLayer();
7594*38e8c45fSAndroid Build Coastguard Worker     auto renderIntent = RenderIntent::TONE_MAP_COLORIMETRIC;
7595*38e8c45fSAndroid Build Coastguard Worker     auto sdrWhitePointNits = DisplayDevice::sDefaultMaxLumiance;
7596*38e8c45fSAndroid Build Coastguard Worker     auto displayBrightnessNits = DisplayDevice::sDefaultMaxLumiance;
7597*38e8c45fSAndroid Build Coastguard Worker 
7598*38e8c45fSAndroid Build Coastguard Worker     captureResults.capturedDataspace = requestedDataspace;
7599*38e8c45fSAndroid Build Coastguard Worker 
7600*38e8c45fSAndroid Build Coastguard Worker     const bool enableLocalTonemapping = FlagManager::getInstance().local_tonemap_screenshots() &&
7601*38e8c45fSAndroid Build Coastguard Worker             !renderArea->getHintForSeamlessTransition();
7602*38e8c45fSAndroid Build Coastguard Worker 
7603*38e8c45fSAndroid Build Coastguard Worker     if (displayState) {
7604*38e8c45fSAndroid Build Coastguard Worker         const auto& state = displayState.value();
7605*38e8c45fSAndroid Build Coastguard Worker         captureResults.capturedDataspace =
7606*38e8c45fSAndroid Build Coastguard Worker                 pickBestDataspace(requestedDataspace, state, captureResults.capturedHdrLayers,
7607*38e8c45fSAndroid Build Coastguard Worker                                   renderArea->getHintForSeamlessTransition());
7608*38e8c45fSAndroid Build Coastguard Worker         sdrWhitePointNits = state.sdrWhitePointNits;
7609*38e8c45fSAndroid Build Coastguard Worker 
7610*38e8c45fSAndroid Build Coastguard Worker         if (!captureResults.capturedHdrLayers) {
7611*38e8c45fSAndroid Build Coastguard Worker             displayBrightnessNits = sdrWhitePointNits;
7612*38e8c45fSAndroid Build Coastguard Worker         } else {
7613*38e8c45fSAndroid Build Coastguard Worker             displayBrightnessNits = state.displayBrightnessNits;
7614*38e8c45fSAndroid Build Coastguard Worker             if (!enableLocalTonemapping) {
7615*38e8c45fSAndroid Build Coastguard Worker                 // Only clamp the display brightness if this is not a seamless transition.
7616*38e8c45fSAndroid Build Coastguard Worker                 // Otherwise for seamless transitions it's important to match the current
7617*38e8c45fSAndroid Build Coastguard Worker                 // display state as the buffer will be shown under these same conditions, and we
7618*38e8c45fSAndroid Build Coastguard Worker                 // want to avoid any flickers
7619*38e8c45fSAndroid Build Coastguard Worker                 if (sdrWhitePointNits > 1.0f && !renderArea->getHintForSeamlessTransition()) {
7620*38e8c45fSAndroid Build Coastguard Worker                     // Restrict the amount of HDR "headroom" in the screenshot to avoid
7621*38e8c45fSAndroid Build Coastguard Worker                     // over-dimming the SDR portion. 2.0 chosen by experimentation
7622*38e8c45fSAndroid Build Coastguard Worker                     constexpr float kMaxScreenshotHeadroom = 2.0f;
7623*38e8c45fSAndroid Build Coastguard Worker                     displayBrightnessNits = std::min(sdrWhitePointNits * kMaxScreenshotHeadroom,
7624*38e8c45fSAndroid Build Coastguard Worker                                                      displayBrightnessNits);
7625*38e8c45fSAndroid Build Coastguard Worker                 }
7626*38e8c45fSAndroid Build Coastguard Worker             }
7627*38e8c45fSAndroid Build Coastguard Worker         }
7628*38e8c45fSAndroid Build Coastguard Worker 
7629*38e8c45fSAndroid Build Coastguard Worker         // Screenshots leaving the device should be colorimetric
7630*38e8c45fSAndroid Build Coastguard Worker         if (requestedDataspace == ui::Dataspace::UNKNOWN &&
7631*38e8c45fSAndroid Build Coastguard Worker             renderArea->getHintForSeamlessTransition()) {
7632*38e8c45fSAndroid Build Coastguard Worker             renderIntent = state.renderIntent;
7633*38e8c45fSAndroid Build Coastguard Worker         }
7634*38e8c45fSAndroid Build Coastguard Worker     }
7635*38e8c45fSAndroid Build Coastguard Worker 
7636*38e8c45fSAndroid Build Coastguard Worker     captureResults.buffer = capturedBuffer->getBuffer();
7637*38e8c45fSAndroid Build Coastguard Worker 
7638*38e8c45fSAndroid Build Coastguard Worker     ui::LayerStack layerStack{ui::DEFAULT_LAYER_STACK};
7639*38e8c45fSAndroid Build Coastguard Worker     if (!layers.empty()) {
7640*38e8c45fSAndroid Build Coastguard Worker         const sp<LayerFE>& layerFE = layers.back().second;
7641*38e8c45fSAndroid Build Coastguard Worker         layerStack = layerFE->getCompositionState()->outputFilter.layerStack;
7642*38e8c45fSAndroid Build Coastguard Worker     }
7643*38e8c45fSAndroid Build Coastguard Worker 
7644*38e8c45fSAndroid Build Coastguard Worker     auto present = [this, buffer = capturedBuffer, dataspace = captureResults.capturedDataspace,
7645*38e8c45fSAndroid Build Coastguard Worker                     sdrWhitePointNits, displayBrightnessNits, grayscale, isProtected,
7646*38e8c45fSAndroid Build Coastguard Worker                     layers = std::move(layers), layerStack, regionSampling,
7647*38e8c45fSAndroid Build Coastguard Worker                     renderArea = std::move(renderArea), renderIntent,
7648*38e8c45fSAndroid Build Coastguard Worker                     enableLocalTonemapping]() -> FenceResult {
7649*38e8c45fSAndroid Build Coastguard Worker         std::unique_ptr<compositionengine::CompositionEngine> compositionEngine =
7650*38e8c45fSAndroid Build Coastguard Worker                 mFactory.createCompositionEngine();
7651*38e8c45fSAndroid Build Coastguard Worker         compositionEngine->setRenderEngine(mRenderEngine.get());
7652*38e8c45fSAndroid Build Coastguard Worker 
7653*38e8c45fSAndroid Build Coastguard Worker         std::vector<sp<compositionengine::LayerFE>> layerFEs;
7654*38e8c45fSAndroid Build Coastguard Worker         layerFEs.reserve(layers.size());
7655*38e8c45fSAndroid Build Coastguard Worker         for (auto& [layer, layerFE] : layers) {
7656*38e8c45fSAndroid Build Coastguard Worker             // Release fences were not yet added for non-threaded render engine. To avoid
7657*38e8c45fSAndroid Build Coastguard Worker             // deadlocks between main thread and binder threads waiting for the future fence
7658*38e8c45fSAndroid Build Coastguard Worker             // result, fences should be added to layers in the same hop onto the main thread.
7659*38e8c45fSAndroid Build Coastguard Worker             if (!mRenderEngine->isThreaded()) {
7660*38e8c45fSAndroid Build Coastguard Worker                 attachReleaseFenceFutureToLayer(layer, layerFE.get(), ui::INVALID_LAYER_STACK);
7661*38e8c45fSAndroid Build Coastguard Worker             }
7662*38e8c45fSAndroid Build Coastguard Worker             layerFEs.push_back(layerFE);
7663*38e8c45fSAndroid Build Coastguard Worker         }
7664*38e8c45fSAndroid Build Coastguard Worker 
7665*38e8c45fSAndroid Build Coastguard Worker         compositionengine::Output::ColorProfile colorProfile{.dataspace = dataspace,
7666*38e8c45fSAndroid Build Coastguard Worker                                                              .renderIntent = renderIntent};
7667*38e8c45fSAndroid Build Coastguard Worker 
7668*38e8c45fSAndroid Build Coastguard Worker         float targetBrightness = 1.0f;
7669*38e8c45fSAndroid Build Coastguard Worker         if (enableLocalTonemapping) {
7670*38e8c45fSAndroid Build Coastguard Worker             // Boost the whole scene so that SDR white is at 1.0 while still communicating the hdr
7671*38e8c45fSAndroid Build Coastguard Worker             // sdr ratio via display brightness / sdrWhite nits.
7672*38e8c45fSAndroid Build Coastguard Worker             targetBrightness = sdrWhitePointNits / displayBrightnessNits;
7673*38e8c45fSAndroid Build Coastguard Worker         } else if (dataspace == ui::Dataspace::BT2020_HLG) {
7674*38e8c45fSAndroid Build Coastguard Worker             const float maxBrightnessNits = displayBrightnessNits / sdrWhitePointNits * 203;
7675*38e8c45fSAndroid Build Coastguard Worker             // With a low dimming ratio, don't fit the entire curve. Otherwise mixed content
7676*38e8c45fSAndroid Build Coastguard Worker             // will appear way too bright.
7677*38e8c45fSAndroid Build Coastguard Worker             if (maxBrightnessNits < 1000.f) {
7678*38e8c45fSAndroid Build Coastguard Worker                 targetBrightness = 1000.f / maxBrightnessNits;
7679*38e8c45fSAndroid Build Coastguard Worker             }
7680*38e8c45fSAndroid Build Coastguard Worker         }
7681*38e8c45fSAndroid Build Coastguard Worker 
7682*38e8c45fSAndroid Build Coastguard Worker         // Screenshots leaving the device must not dim in gamma space.
7683*38e8c45fSAndroid Build Coastguard Worker         const bool dimInGammaSpaceForEnhancedScreenshots = mDimInGammaSpaceForEnhancedScreenshots &&
7684*38e8c45fSAndroid Build Coastguard Worker                 renderArea->getHintForSeamlessTransition();
7685*38e8c45fSAndroid Build Coastguard Worker 
7686*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<ScreenCaptureOutput> output = createScreenCaptureOutput(
7687*38e8c45fSAndroid Build Coastguard Worker                 ScreenCaptureOutputArgs{.compositionEngine = *compositionEngine,
7688*38e8c45fSAndroid Build Coastguard Worker                                         .colorProfile = colorProfile,
7689*38e8c45fSAndroid Build Coastguard Worker                                         .renderArea = *renderArea,
7690*38e8c45fSAndroid Build Coastguard Worker                                         .layerStack = layerStack,
7691*38e8c45fSAndroid Build Coastguard Worker                                         .buffer = std::move(buffer),
7692*38e8c45fSAndroid Build Coastguard Worker                                         .sdrWhitePointNits = sdrWhitePointNits,
7693*38e8c45fSAndroid Build Coastguard Worker                                         .displayBrightnessNits = displayBrightnessNits,
7694*38e8c45fSAndroid Build Coastguard Worker                                         .targetBrightness = targetBrightness,
7695*38e8c45fSAndroid Build Coastguard Worker                                         .regionSampling = regionSampling,
7696*38e8c45fSAndroid Build Coastguard Worker                                         .treat170mAsSrgb = mTreat170mAsSrgb,
7697*38e8c45fSAndroid Build Coastguard Worker                                         .dimInGammaSpaceForEnhancedScreenshots =
7698*38e8c45fSAndroid Build Coastguard Worker                                                 dimInGammaSpaceForEnhancedScreenshots,
7699*38e8c45fSAndroid Build Coastguard Worker                                         .isProtected = isProtected,
7700*38e8c45fSAndroid Build Coastguard Worker                                         .enableLocalTonemapping = enableLocalTonemapping});
7701*38e8c45fSAndroid Build Coastguard Worker 
7702*38e8c45fSAndroid Build Coastguard Worker         const float colorSaturation = grayscale ? 0 : 1;
7703*38e8c45fSAndroid Build Coastguard Worker         compositionengine::CompositionRefreshArgs refreshArgs{
7704*38e8c45fSAndroid Build Coastguard Worker                 .outputs = {output},
7705*38e8c45fSAndroid Build Coastguard Worker                 .layers = std::move(layerFEs),
7706*38e8c45fSAndroid Build Coastguard Worker                 .updatingOutputGeometryThisFrame = true,
7707*38e8c45fSAndroid Build Coastguard Worker                 .updatingGeometryThisFrame = true,
7708*38e8c45fSAndroid Build Coastguard Worker                 .colorTransformMatrix = calculateColorMatrix(colorSaturation),
7709*38e8c45fSAndroid Build Coastguard Worker         };
7710*38e8c45fSAndroid Build Coastguard Worker         compositionEngine->present(refreshArgs);
7711*38e8c45fSAndroid Build Coastguard Worker 
7712*38e8c45fSAndroid Build Coastguard Worker         return output->getRenderSurface()->getClientTargetAcquireFence();
7713*38e8c45fSAndroid Build Coastguard Worker     };
7714*38e8c45fSAndroid Build Coastguard Worker 
7715*38e8c45fSAndroid Build Coastguard Worker     // If RenderEngine is threaded, we can safely call CompositionEngine::present off the main
7716*38e8c45fSAndroid Build Coastguard Worker     // thread as the RenderEngine::drawLayers call will run on RenderEngine's thread. Otherwise,
7717*38e8c45fSAndroid Build Coastguard Worker     // we need RenderEngine to run on the main thread so we call CompositionEngine::present
7718*38e8c45fSAndroid Build Coastguard Worker     // immediately.
7719*38e8c45fSAndroid Build Coastguard Worker     //
7720*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/196334700) Once we use RenderEngineThreaded everywhere we can always defer the call
7721*38e8c45fSAndroid Build Coastguard Worker     // to CompositionEngine::present.
7722*38e8c45fSAndroid Build Coastguard Worker     ftl::SharedFuture<FenceResult> presentFuture = mRenderEngine->isThreaded()
7723*38e8c45fSAndroid Build Coastguard Worker             ? ftl::yield(present()).share()
7724*38e8c45fSAndroid Build Coastguard Worker             : mScheduler->schedule(std::move(present)).share();
7725*38e8c45fSAndroid Build Coastguard Worker 
7726*38e8c45fSAndroid Build Coastguard Worker     return presentFuture;
7727*38e8c45fSAndroid Build Coastguard Worker }
7728*38e8c45fSAndroid Build Coastguard Worker 
traverseLegacyLayers(const LayerVector::Visitor & visitor) const7729*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::traverseLegacyLayers(const LayerVector::Visitor& visitor) const {
7730*38e8c45fSAndroid Build Coastguard Worker     for (auto& layer : mLegacyLayers) {
7731*38e8c45fSAndroid Build Coastguard Worker         visitor(layer.second.get());
7732*38e8c45fSAndroid Build Coastguard Worker     }
7733*38e8c45fSAndroid Build Coastguard Worker }
7734*38e8c45fSAndroid Build Coastguard Worker 
7735*38e8c45fSAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
7736*38e8c45fSAndroid Build Coastguard Worker 
getPreferredDisplayMode(PhysicalDisplayId displayId,DisplayModeId defaultModeId) const7737*38e8c45fSAndroid Build Coastguard Worker ftl::Optional<scheduler::FrameRateMode> SurfaceFlinger::getPreferredDisplayMode(
7738*38e8c45fSAndroid Build Coastguard Worker         PhysicalDisplayId displayId, DisplayModeId defaultModeId) const {
7739*38e8c45fSAndroid Build Coastguard Worker     if (const auto schedulerMode = mScheduler->getPreferredDisplayMode();
7740*38e8c45fSAndroid Build Coastguard Worker         schedulerMode.modePtr->getPhysicalDisplayId() == displayId) {
7741*38e8c45fSAndroid Build Coastguard Worker         return schedulerMode;
7742*38e8c45fSAndroid Build Coastguard Worker     }
7743*38e8c45fSAndroid Build Coastguard Worker 
7744*38e8c45fSAndroid Build Coastguard Worker     return mPhysicalDisplays.get(displayId)
7745*38e8c45fSAndroid Build Coastguard Worker             .transform(&PhysicalDisplay::snapshotRef)
7746*38e8c45fSAndroid Build Coastguard Worker             .and_then([&](const display::DisplaySnapshot& snapshot) {
7747*38e8c45fSAndroid Build Coastguard Worker                 return snapshot.displayModes().get(defaultModeId);
7748*38e8c45fSAndroid Build Coastguard Worker             })
7749*38e8c45fSAndroid Build Coastguard Worker             .transform([](const DisplayModePtr& modePtr) {
7750*38e8c45fSAndroid Build Coastguard Worker                 return scheduler::FrameRateMode{modePtr->getPeakFps(), ftl::as_non_null(modePtr)};
7751*38e8c45fSAndroid Build Coastguard Worker             });
7752*38e8c45fSAndroid Build Coastguard Worker }
7753*38e8c45fSAndroid Build Coastguard Worker 
setDesiredDisplayModeSpecsInternal(const sp<DisplayDevice> & display,const scheduler::RefreshRateSelector::PolicyVariant & policy)7754*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setDesiredDisplayModeSpecsInternal(
7755*38e8c45fSAndroid Build Coastguard Worker         const sp<DisplayDevice>& display,
7756*38e8c45fSAndroid Build Coastguard Worker         const scheduler::RefreshRateSelector::PolicyVariant& policy) {
7757*38e8c45fSAndroid Build Coastguard Worker     const auto displayId = display->getPhysicalId();
7758*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str());
7759*38e8c45fSAndroid Build Coastguard Worker 
7760*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
7761*38e8c45fSAndroid Build Coastguard Worker 
7762*38e8c45fSAndroid Build Coastguard Worker     if (mDebugDisplayModeSetByBackdoor) {
7763*38e8c45fSAndroid Build Coastguard Worker         // ignore this request as mode is overridden by backdoor
7764*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
7765*38e8c45fSAndroid Build Coastguard Worker     }
7766*38e8c45fSAndroid Build Coastguard Worker 
7767*38e8c45fSAndroid Build Coastguard Worker     auto& selector = display->refreshRateSelector();
7768*38e8c45fSAndroid Build Coastguard Worker     using SetPolicyResult = scheduler::RefreshRateSelector::SetPolicyResult;
7769*38e8c45fSAndroid Build Coastguard Worker 
7770*38e8c45fSAndroid Build Coastguard Worker     switch (selector.setPolicy(policy)) {
7771*38e8c45fSAndroid Build Coastguard Worker         case SetPolicyResult::Invalid:
7772*38e8c45fSAndroid Build Coastguard Worker             return BAD_VALUE;
7773*38e8c45fSAndroid Build Coastguard Worker         case SetPolicyResult::Unchanged:
7774*38e8c45fSAndroid Build Coastguard Worker             return NO_ERROR;
7775*38e8c45fSAndroid Build Coastguard Worker         case SetPolicyResult::Changed:
7776*38e8c45fSAndroid Build Coastguard Worker             break;
7777*38e8c45fSAndroid Build Coastguard Worker     }
7778*38e8c45fSAndroid Build Coastguard Worker 
7779*38e8c45fSAndroid Build Coastguard Worker     return applyRefreshRateSelectorPolicy(displayId, selector);
7780*38e8c45fSAndroid Build Coastguard Worker }
7781*38e8c45fSAndroid Build Coastguard Worker 
applyRefreshRateSelectorPolicy(PhysicalDisplayId displayId,const scheduler::RefreshRateSelector & selector)7782*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::applyRefreshRateSelectorPolicy(
7783*38e8c45fSAndroid Build Coastguard Worker         PhysicalDisplayId displayId, const scheduler::RefreshRateSelector& selector) {
7784*38e8c45fSAndroid Build Coastguard Worker     const scheduler::RefreshRateSelector::Policy currentPolicy = selector.getCurrentPolicy();
7785*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Setting desired display mode specs: %s", currentPolicy.toString().c_str());
7786*38e8c45fSAndroid Build Coastguard Worker 
7787*38e8c45fSAndroid Build Coastguard Worker     if (const bool isPacesetter =
7788*38e8c45fSAndroid Build Coastguard Worker                 mScheduler->onDisplayModeChanged(displayId, selector.getActiveMode(),
7789*38e8c45fSAndroid Build Coastguard Worker                                                  /*clearContentRequirements*/ true)) {
7790*38e8c45fSAndroid Build Coastguard Worker         mDisplayModeController.updateKernelIdleTimer(displayId);
7791*38e8c45fSAndroid Build Coastguard Worker     }
7792*38e8c45fSAndroid Build Coastguard Worker 
7793*38e8c45fSAndroid Build Coastguard Worker     auto preferredModeOpt = getPreferredDisplayMode(displayId, currentPolicy.defaultMode);
7794*38e8c45fSAndroid Build Coastguard Worker     if (!preferredModeOpt) {
7795*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: Preferred mode is unknown", __func__);
7796*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
7797*38e8c45fSAndroid Build Coastguard Worker     }
7798*38e8c45fSAndroid Build Coastguard Worker 
7799*38e8c45fSAndroid Build Coastguard Worker     auto preferredMode = std::move(*preferredModeOpt);
7800*38e8c45fSAndroid Build Coastguard Worker     const auto preferredModeId = preferredMode.modePtr->getId();
7801*38e8c45fSAndroid Build Coastguard Worker 
7802*38e8c45fSAndroid Build Coastguard Worker     const Fps preferredFps = preferredMode.fps;
7803*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Switching to Scheduler preferred mode %d (%s)", ftl::to_underlying(preferredModeId),
7804*38e8c45fSAndroid Build Coastguard Worker           to_string(preferredFps).c_str());
7805*38e8c45fSAndroid Build Coastguard Worker 
7806*38e8c45fSAndroid Build Coastguard Worker     if (!selector.isModeAllowed(preferredMode)) {
7807*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: Preferred mode %d is disallowed", __func__, ftl::to_underlying(preferredModeId));
7808*38e8c45fSAndroid Build Coastguard Worker         return INVALID_OPERATION;
7809*38e8c45fSAndroid Build Coastguard Worker     }
7810*38e8c45fSAndroid Build Coastguard Worker 
7811*38e8c45fSAndroid Build Coastguard Worker     setDesiredMode({std::move(preferredMode), .emitEvent = true});
7812*38e8c45fSAndroid Build Coastguard Worker 
7813*38e8c45fSAndroid Build Coastguard Worker     // Update the frameRateOverride list as the display render rate might have changed
7814*38e8c45fSAndroid Build Coastguard Worker     mScheduler->updateFrameRateOverrides(scheduler::GlobalSignals{}, preferredFps);
7815*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
7816*38e8c45fSAndroid Build Coastguard Worker }
7817*38e8c45fSAndroid Build Coastguard Worker 
7818*38e8c45fSAndroid Build Coastguard Worker namespace {
translate(const gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange & aidlRange)7819*38e8c45fSAndroid Build Coastguard Worker FpsRange translate(const gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange& aidlRange) {
7820*38e8c45fSAndroid Build Coastguard Worker     return FpsRange{Fps::fromValue(aidlRange.min), Fps::fromValue(aidlRange.max)};
7821*38e8c45fSAndroid Build Coastguard Worker }
7822*38e8c45fSAndroid Build Coastguard Worker 
translate(const gui::DisplayModeSpecs::RefreshRateRanges & aidlRanges)7823*38e8c45fSAndroid Build Coastguard Worker FpsRanges translate(const gui::DisplayModeSpecs::RefreshRateRanges& aidlRanges) {
7824*38e8c45fSAndroid Build Coastguard Worker     return FpsRanges{translate(aidlRanges.physical), translate(aidlRanges.render)};
7825*38e8c45fSAndroid Build Coastguard Worker }
7826*38e8c45fSAndroid Build Coastguard Worker 
translate(const FpsRange & range)7827*38e8c45fSAndroid Build Coastguard Worker gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange translate(const FpsRange& range) {
7828*38e8c45fSAndroid Build Coastguard Worker     gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange aidlRange;
7829*38e8c45fSAndroid Build Coastguard Worker     aidlRange.min = range.min.getValue();
7830*38e8c45fSAndroid Build Coastguard Worker     aidlRange.max = range.max.getValue();
7831*38e8c45fSAndroid Build Coastguard Worker     return aidlRange;
7832*38e8c45fSAndroid Build Coastguard Worker }
7833*38e8c45fSAndroid Build Coastguard Worker 
translate(const FpsRanges & ranges)7834*38e8c45fSAndroid Build Coastguard Worker gui::DisplayModeSpecs::RefreshRateRanges translate(const FpsRanges& ranges) {
7835*38e8c45fSAndroid Build Coastguard Worker     gui::DisplayModeSpecs::RefreshRateRanges aidlRanges;
7836*38e8c45fSAndroid Build Coastguard Worker     aidlRanges.physical = translate(ranges.physical);
7837*38e8c45fSAndroid Build Coastguard Worker     aidlRanges.render = translate(ranges.render);
7838*38e8c45fSAndroid Build Coastguard Worker     return aidlRanges;
7839*38e8c45fSAndroid Build Coastguard Worker }
7840*38e8c45fSAndroid Build Coastguard Worker 
7841*38e8c45fSAndroid Build Coastguard Worker } // namespace
7842*38e8c45fSAndroid Build Coastguard Worker 
setDesiredDisplayModeSpecs(const sp<IBinder> & displayToken,const gui::DisplayModeSpecs & specs)7843*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
7844*38e8c45fSAndroid Build Coastguard Worker                                                     const gui::DisplayModeSpecs& specs) {
7845*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
7846*38e8c45fSAndroid Build Coastguard Worker 
7847*38e8c45fSAndroid Build Coastguard Worker     if (!displayToken) {
7848*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
7849*38e8c45fSAndroid Build Coastguard Worker     }
7850*38e8c45fSAndroid Build Coastguard Worker 
7851*38e8c45fSAndroid Build Coastguard Worker     auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) -> status_t {
7852*38e8c45fSAndroid Build Coastguard Worker         const auto display = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(displayToken));
7853*38e8c45fSAndroid Build Coastguard Worker         if (!display) {
7854*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Attempt to set desired display modes for invalid display token %p",
7855*38e8c45fSAndroid Build Coastguard Worker                   displayToken.get());
7856*38e8c45fSAndroid Build Coastguard Worker             return NAME_NOT_FOUND;
7857*38e8c45fSAndroid Build Coastguard Worker         } else if (display->isVirtual()) {
7858*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Attempt to set desired display modes for virtual display");
7859*38e8c45fSAndroid Build Coastguard Worker             return INVALID_OPERATION;
7860*38e8c45fSAndroid Build Coastguard Worker         } else {
7861*38e8c45fSAndroid Build Coastguard Worker             using Policy = scheduler::RefreshRateSelector::DisplayManagerPolicy;
7862*38e8c45fSAndroid Build Coastguard Worker             const auto idleScreenConfigOpt =
7863*38e8c45fSAndroid Build Coastguard Worker                     FlagManager::getInstance().idle_screen_refresh_rate_timeout()
7864*38e8c45fSAndroid Build Coastguard Worker                     ? specs.idleScreenRefreshRateConfig
7865*38e8c45fSAndroid Build Coastguard Worker                     : std::nullopt;
7866*38e8c45fSAndroid Build Coastguard Worker             const Policy policy{DisplayModeId(specs.defaultMode), translate(specs.primaryRanges),
7867*38e8c45fSAndroid Build Coastguard Worker                                 translate(specs.appRequestRanges), specs.allowGroupSwitching,
7868*38e8c45fSAndroid Build Coastguard Worker                                 idleScreenConfigOpt};
7869*38e8c45fSAndroid Build Coastguard Worker 
7870*38e8c45fSAndroid Build Coastguard Worker             return setDesiredDisplayModeSpecsInternal(display, policy);
7871*38e8c45fSAndroid Build Coastguard Worker         }
7872*38e8c45fSAndroid Build Coastguard Worker     });
7873*38e8c45fSAndroid Build Coastguard Worker 
7874*38e8c45fSAndroid Build Coastguard Worker     return future.get();
7875*38e8c45fSAndroid Build Coastguard Worker }
7876*38e8c45fSAndroid Build Coastguard Worker 
getDesiredDisplayModeSpecs(const sp<IBinder> & displayToken,gui::DisplayModeSpecs * outSpecs)7877*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
7878*38e8c45fSAndroid Build Coastguard Worker                                                     gui::DisplayModeSpecs* outSpecs) {
7879*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
7880*38e8c45fSAndroid Build Coastguard Worker 
7881*38e8c45fSAndroid Build Coastguard Worker     if (!displayToken || !outSpecs) {
7882*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
7883*38e8c45fSAndroid Build Coastguard Worker     }
7884*38e8c45fSAndroid Build Coastguard Worker 
7885*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
7886*38e8c45fSAndroid Build Coastguard Worker     const auto display = getDisplayDeviceLocked(displayToken);
7887*38e8c45fSAndroid Build Coastguard Worker     if (!display) {
7888*38e8c45fSAndroid Build Coastguard Worker         return NAME_NOT_FOUND;
7889*38e8c45fSAndroid Build Coastguard Worker     }
7890*38e8c45fSAndroid Build Coastguard Worker 
7891*38e8c45fSAndroid Build Coastguard Worker     if (display->isVirtual()) {
7892*38e8c45fSAndroid Build Coastguard Worker         return INVALID_OPERATION;
7893*38e8c45fSAndroid Build Coastguard Worker     }
7894*38e8c45fSAndroid Build Coastguard Worker 
7895*38e8c45fSAndroid Build Coastguard Worker     scheduler::RefreshRateSelector::Policy policy =
7896*38e8c45fSAndroid Build Coastguard Worker             display->refreshRateSelector().getDisplayManagerPolicy();
7897*38e8c45fSAndroid Build Coastguard Worker     outSpecs->defaultMode = ftl::to_underlying(policy.defaultMode);
7898*38e8c45fSAndroid Build Coastguard Worker     outSpecs->allowGroupSwitching = policy.allowGroupSwitching;
7899*38e8c45fSAndroid Build Coastguard Worker     outSpecs->primaryRanges = translate(policy.primaryRanges);
7900*38e8c45fSAndroid Build Coastguard Worker     outSpecs->appRequestRanges = translate(policy.appRequestRanges);
7901*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
7902*38e8c45fSAndroid Build Coastguard Worker }
7903*38e8c45fSAndroid Build Coastguard Worker 
onLayerFirstRef(Layer * layer)7904*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onLayerFirstRef(Layer* layer) {
7905*38e8c45fSAndroid Build Coastguard Worker     mNumLayers++;
7906*38e8c45fSAndroid Build Coastguard Worker     mScheduler->registerLayer(layer, scheduler::FrameRateCompatibility::Default);
7907*38e8c45fSAndroid Build Coastguard Worker }
7908*38e8c45fSAndroid Build Coastguard Worker 
onLayerDestroyed(Layer * layer)7909*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onLayerDestroyed(Layer* layer) {
7910*38e8c45fSAndroid Build Coastguard Worker     mNumLayers--;
7911*38e8c45fSAndroid Build Coastguard Worker     mScheduler->deregisterLayer(layer);
7912*38e8c45fSAndroid Build Coastguard Worker     if (mTransactionTracing) {
7913*38e8c45fSAndroid Build Coastguard Worker         mTransactionTracing->onLayerRemoved(layer->getSequence());
7914*38e8c45fSAndroid Build Coastguard Worker     }
7915*38e8c45fSAndroid Build Coastguard Worker     mScheduler->onLayerDestroyed(layer);
7916*38e8c45fSAndroid Build Coastguard Worker }
7917*38e8c45fSAndroid Build Coastguard Worker 
onLayerUpdate()7918*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onLayerUpdate() {
7919*38e8c45fSAndroid Build Coastguard Worker     scheduleCommit(FrameHint::kActive);
7920*38e8c45fSAndroid Build Coastguard Worker }
7921*38e8c45fSAndroid Build Coastguard Worker 
setGlobalShadowSettings(const half4 & ambientColor,const half4 & spotColor,float lightPosY,float lightPosZ,float lightRadius)7922*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
7923*38e8c45fSAndroid Build Coastguard Worker                                                  float lightPosY, float lightPosZ,
7924*38e8c45fSAndroid Build Coastguard Worker                                                  float lightRadius) {
7925*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock _l(mStateLock);
7926*38e8c45fSAndroid Build Coastguard Worker     mCurrentState.globalShadowSettings.ambientColor = vec4(ambientColor);
7927*38e8c45fSAndroid Build Coastguard Worker     mCurrentState.globalShadowSettings.spotColor = vec4(spotColor);
7928*38e8c45fSAndroid Build Coastguard Worker     mCurrentState.globalShadowSettings.lightPos.y = lightPosY;
7929*38e8c45fSAndroid Build Coastguard Worker     mCurrentState.globalShadowSettings.lightPos.z = lightPosZ;
7930*38e8c45fSAndroid Build Coastguard Worker     mCurrentState.globalShadowSettings.lightRadius = lightRadius;
7931*38e8c45fSAndroid Build Coastguard Worker 
7932*38e8c45fSAndroid Build Coastguard Worker     // these values are overridden when calculating the shadow settings for a layer.
7933*38e8c45fSAndroid Build Coastguard Worker     mCurrentState.globalShadowSettings.lightPos.x = 0.f;
7934*38e8c45fSAndroid Build Coastguard Worker     mCurrentState.globalShadowSettings.length = 0.f;
7935*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
7936*38e8c45fSAndroid Build Coastguard Worker }
7937*38e8c45fSAndroid Build Coastguard Worker 
getGenericLayerMetadataKeyMap() const7938*38e8c45fSAndroid Build Coastguard Worker const std::unordered_map<std::string, uint32_t>& SurfaceFlinger::getGenericLayerMetadataKeyMap()
7939*38e8c45fSAndroid Build Coastguard Worker         const {
7940*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/149500060): Remove this fixed/static mapping. Please prefer taking
7941*38e8c45fSAndroid Build Coastguard Worker     // on the work to remove the table in that bug rather than adding more to
7942*38e8c45fSAndroid Build Coastguard Worker     // it.
7943*38e8c45fSAndroid Build Coastguard Worker     static const std::unordered_map<std::string, uint32_t> genericLayerMetadataKeyMap{
7944*38e8c45fSAndroid Build Coastguard Worker             {"org.chromium.arc.V1_0.TaskId", gui::METADATA_TASK_ID},
7945*38e8c45fSAndroid Build Coastguard Worker             {"org.chromium.arc.V1_0.CursorInfo", gui::METADATA_MOUSE_CURSOR},
7946*38e8c45fSAndroid Build Coastguard Worker     };
7947*38e8c45fSAndroid Build Coastguard Worker     return genericLayerMetadataKeyMap;
7948*38e8c45fSAndroid Build Coastguard Worker }
7949*38e8c45fSAndroid Build Coastguard Worker 
setGameModeFrameRateOverride(uid_t uid,float frameRate)7950*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setGameModeFrameRateOverride(uid_t uid, float frameRate) {
7951*38e8c45fSAndroid Build Coastguard Worker     mScheduler->setGameModeFrameRateForUid(FrameRateOverride{uid, frameRate});
7952*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
7953*38e8c45fSAndroid Build Coastguard Worker }
7954*38e8c45fSAndroid Build Coastguard Worker 
setGameDefaultFrameRateOverride(uid_t uid,float frameRate)7955*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setGameDefaultFrameRateOverride(uid_t uid, float frameRate) {
7956*38e8c45fSAndroid Build Coastguard Worker     if (FlagManager::getInstance().game_default_frame_rate()) {
7957*38e8c45fSAndroid Build Coastguard Worker         mScheduler->setGameDefaultFrameRateForUid(
7958*38e8c45fSAndroid Build Coastguard Worker                 FrameRateOverride{static_cast<uid_t>(uid), frameRate});
7959*38e8c45fSAndroid Build Coastguard Worker     }
7960*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
7961*38e8c45fSAndroid Build Coastguard Worker }
7962*38e8c45fSAndroid Build Coastguard Worker 
updateSmallAreaDetection(std::vector<std::pair<int32_t,float>> & appIdThresholdMappings)7963*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::updateSmallAreaDetection(
7964*38e8c45fSAndroid Build Coastguard Worker         std::vector<std::pair<int32_t, float>>& appIdThresholdMappings) {
7965*38e8c45fSAndroid Build Coastguard Worker     mScheduler->updateSmallAreaDetection(appIdThresholdMappings);
7966*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
7967*38e8c45fSAndroid Build Coastguard Worker }
7968*38e8c45fSAndroid Build Coastguard Worker 
setSmallAreaDetectionThreshold(int32_t appId,float threshold)7969*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::setSmallAreaDetectionThreshold(int32_t appId, float threshold) {
7970*38e8c45fSAndroid Build Coastguard Worker     mScheduler->setSmallAreaDetectionThreshold(appId, threshold);
7971*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
7972*38e8c45fSAndroid Build Coastguard Worker }
7973*38e8c45fSAndroid Build Coastguard Worker 
enableRefreshRateOverlay(bool enable)7974*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::enableRefreshRateOverlay(bool enable) {
7975*38e8c45fSAndroid Build Coastguard Worker     bool setByHwc = getHwComposer().hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG);
7976*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [displayId, physical] : mPhysicalDisplays) {
7977*38e8c45fSAndroid Build Coastguard Worker         if (physical.snapshot().connectionType() == ui::DisplayConnectionType::Internal ||
7978*38e8c45fSAndroid Build Coastguard Worker             FlagManager::getInstance().refresh_rate_overlay_on_external_display()) {
7979*38e8c45fSAndroid Build Coastguard Worker             if (const auto display = getDisplayDeviceLocked(displayId)) {
7980*38e8c45fSAndroid Build Coastguard Worker                 const auto enableOverlay = [&](bool setByHwc) FTL_FAKE_GUARD(kMainThreadContext) {
7981*38e8c45fSAndroid Build Coastguard Worker                     const auto activeMode = mDisplayModeController.getActiveMode(displayId);
7982*38e8c45fSAndroid Build Coastguard Worker                     const Fps refreshRate = activeMode.modePtr->getVsyncRate();
7983*38e8c45fSAndroid Build Coastguard Worker                     const Fps renderFps = activeMode.fps;
7984*38e8c45fSAndroid Build Coastguard Worker 
7985*38e8c45fSAndroid Build Coastguard Worker                     display->enableRefreshRateOverlay(enable, setByHwc, refreshRate, renderFps,
7986*38e8c45fSAndroid Build Coastguard Worker                                                       mRefreshRateOverlaySpinner,
7987*38e8c45fSAndroid Build Coastguard Worker                                                       mRefreshRateOverlayRenderRate,
7988*38e8c45fSAndroid Build Coastguard Worker                                                       mRefreshRateOverlayShowInMiddle);
7989*38e8c45fSAndroid Build Coastguard Worker                 };
7990*38e8c45fSAndroid Build Coastguard Worker 
7991*38e8c45fSAndroid Build Coastguard Worker                 enableOverlay(setByHwc);
7992*38e8c45fSAndroid Build Coastguard Worker                 if (setByHwc) {
7993*38e8c45fSAndroid Build Coastguard Worker                     const auto status =
7994*38e8c45fSAndroid Build Coastguard Worker                             getHwComposer().setRefreshRateChangedCallbackDebugEnabled(displayId,
7995*38e8c45fSAndroid Build Coastguard Worker                                                                                       enable);
7996*38e8c45fSAndroid Build Coastguard Worker                     if (status != NO_ERROR) {
7997*38e8c45fSAndroid Build Coastguard Worker                         ALOGE("Error %s refresh rate changed callback debug",
7998*38e8c45fSAndroid Build Coastguard Worker                               enable ? "enabling" : "disabling");
7999*38e8c45fSAndroid Build Coastguard Worker                         enableOverlay(/*setByHwc*/ false);
8000*38e8c45fSAndroid Build Coastguard Worker                     }
8001*38e8c45fSAndroid Build Coastguard Worker                 }
8002*38e8c45fSAndroid Build Coastguard Worker             }
8003*38e8c45fSAndroid Build Coastguard Worker         }
8004*38e8c45fSAndroid Build Coastguard Worker     }
8005*38e8c45fSAndroid Build Coastguard Worker }
8006*38e8c45fSAndroid Build Coastguard Worker 
enableHdrSdrRatioOverlay(bool enable)8007*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::enableHdrSdrRatioOverlay(bool enable) {
8008*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [id, display] : mPhysicalDisplays) {
8009*38e8c45fSAndroid Build Coastguard Worker         if (display.snapshot().connectionType() == ui::DisplayConnectionType::Internal) {
8010*38e8c45fSAndroid Build Coastguard Worker             if (const auto device = getDisplayDeviceLocked(id)) {
8011*38e8c45fSAndroid Build Coastguard Worker                 device->enableHdrSdrRatioOverlay(enable);
8012*38e8c45fSAndroid Build Coastguard Worker             }
8013*38e8c45fSAndroid Build Coastguard Worker         }
8014*38e8c45fSAndroid Build Coastguard Worker     }
8015*38e8c45fSAndroid Build Coastguard Worker }
8016*38e8c45fSAndroid Build Coastguard Worker 
getGpuContextPriority()8017*38e8c45fSAndroid Build Coastguard Worker int SurfaceFlinger::getGpuContextPriority() {
8018*38e8c45fSAndroid Build Coastguard Worker     return getRenderEngine().getContextPriority();
8019*38e8c45fSAndroid Build Coastguard Worker }
8020*38e8c45fSAndroid Build Coastguard Worker 
calculateMaxAcquiredBufferCount(Fps refreshRate,std::chrono::nanoseconds presentLatency)8021*38e8c45fSAndroid Build Coastguard Worker int SurfaceFlinger::calculateMaxAcquiredBufferCount(Fps refreshRate,
8022*38e8c45fSAndroid Build Coastguard Worker                                                     std::chrono::nanoseconds presentLatency) {
8023*38e8c45fSAndroid Build Coastguard Worker     auto pipelineDepth = presentLatency.count() / refreshRate.getPeriodNsecs();
8024*38e8c45fSAndroid Build Coastguard Worker     if (presentLatency.count() % refreshRate.getPeriodNsecs()) {
8025*38e8c45fSAndroid Build Coastguard Worker         pipelineDepth++;
8026*38e8c45fSAndroid Build Coastguard Worker     }
8027*38e8c45fSAndroid Build Coastguard Worker     return std::max(minAcquiredBuffers, static_cast<int64_t>(pipelineDepth - 1));
8028*38e8c45fSAndroid Build Coastguard Worker }
8029*38e8c45fSAndroid Build Coastguard Worker 
getMaxAcquiredBufferCount(int * buffers) const8030*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getMaxAcquiredBufferCount(int* buffers) const {
8031*38e8c45fSAndroid Build Coastguard Worker     Fps maxRefreshRate = 60_Hz;
8032*38e8c45fSAndroid Build Coastguard Worker 
8033*38e8c45fSAndroid Build Coastguard Worker     if (!getHwComposer().isHeadless()) {
8034*38e8c45fSAndroid Build Coastguard Worker         if (const auto display = getDefaultDisplayDevice()) {
8035*38e8c45fSAndroid Build Coastguard Worker             maxRefreshRate = display->refreshRateSelector().getSupportedRefreshRateRange().max;
8036*38e8c45fSAndroid Build Coastguard Worker         }
8037*38e8c45fSAndroid Build Coastguard Worker     }
8038*38e8c45fSAndroid Build Coastguard Worker 
8039*38e8c45fSAndroid Build Coastguard Worker     *buffers = getMaxAcquiredBufferCountForRefreshRate(maxRefreshRate);
8040*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
8041*38e8c45fSAndroid Build Coastguard Worker }
8042*38e8c45fSAndroid Build Coastguard Worker 
getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const8043*38e8c45fSAndroid Build Coastguard Worker uint32_t SurfaceFlinger::getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const {
8044*38e8c45fSAndroid Build Coastguard Worker     Fps refreshRate = 60_Hz;
8045*38e8c45fSAndroid Build Coastguard Worker 
8046*38e8c45fSAndroid Build Coastguard Worker     if (const auto frameRateOverride = mScheduler->getFrameRateOverride(uid)) {
8047*38e8c45fSAndroid Build Coastguard Worker         refreshRate = *frameRateOverride;
8048*38e8c45fSAndroid Build Coastguard Worker     } else if (!getHwComposer().isHeadless()) {
8049*38e8c45fSAndroid Build Coastguard Worker         if (const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked())) {
8050*38e8c45fSAndroid Build Coastguard Worker             refreshRate = display->refreshRateSelector().getActiveMode().fps;
8051*38e8c45fSAndroid Build Coastguard Worker         }
8052*38e8c45fSAndroid Build Coastguard Worker     }
8053*38e8c45fSAndroid Build Coastguard Worker 
8054*38e8c45fSAndroid Build Coastguard Worker     return getMaxAcquiredBufferCountForRefreshRate(refreshRate);
8055*38e8c45fSAndroid Build Coastguard Worker }
8056*38e8c45fSAndroid Build Coastguard Worker 
getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) const8057*38e8c45fSAndroid Build Coastguard Worker int SurfaceFlinger::getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) const {
8058*38e8c45fSAndroid Build Coastguard Worker     const auto vsyncConfig =
8059*38e8c45fSAndroid Build Coastguard Worker             mScheduler->getVsyncConfiguration().getConfigsForRefreshRate(refreshRate).late;
8060*38e8c45fSAndroid Build Coastguard Worker     const auto presentLatency = vsyncConfig.appWorkDuration + vsyncConfig.sfWorkDuration;
8061*38e8c45fSAndroid Build Coastguard Worker     return calculateMaxAcquiredBufferCount(refreshRate, presentLatency);
8062*38e8c45fSAndroid Build Coastguard Worker }
8063*38e8c45fSAndroid Build Coastguard Worker 
sample()8064*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::sample() {
8065*38e8c45fSAndroid Build Coastguard Worker     if (!mLumaSampling || !mRegionSamplingThread) {
8066*38e8c45fSAndroid Build Coastguard Worker         return;
8067*38e8c45fSAndroid Build Coastguard Worker     }
8068*38e8c45fSAndroid Build Coastguard Worker 
8069*38e8c45fSAndroid Build Coastguard Worker     const auto scheduledFrameResultOpt = mScheduler->getScheduledFrameResult();
8070*38e8c45fSAndroid Build Coastguard Worker     const auto scheduleFrameTimeOpt = scheduledFrameResultOpt
8071*38e8c45fSAndroid Build Coastguard Worker             ? std::optional{scheduledFrameResultOpt->callbackTime}
8072*38e8c45fSAndroid Build Coastguard Worker             : std::nullopt;
8073*38e8c45fSAndroid Build Coastguard Worker     mRegionSamplingThread->onCompositionComplete(scheduleFrameTimeOpt);
8074*38e8c45fSAndroid Build Coastguard Worker }
8075*38e8c45fSAndroid Build Coastguard Worker 
onActiveDisplaySizeChanged(const DisplayDevice & activeDisplay)8076*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onActiveDisplaySizeChanged(const DisplayDevice& activeDisplay) {
8077*38e8c45fSAndroid Build Coastguard Worker     mScheduler->onActiveDisplayAreaChanged(activeDisplay.getWidth() * activeDisplay.getHeight());
8078*38e8c45fSAndroid Build Coastguard Worker     getRenderEngine().onActiveDisplaySizeChanged(activeDisplay.getSize());
8079*38e8c45fSAndroid Build Coastguard Worker }
8080*38e8c45fSAndroid Build Coastguard Worker 
getActivatableDisplay() const8081*38e8c45fSAndroid Build Coastguard Worker sp<DisplayDevice> SurfaceFlinger::getActivatableDisplay() const {
8082*38e8c45fSAndroid Build Coastguard Worker     if (mPhysicalDisplays.size() == 1) return nullptr;
8083*38e8c45fSAndroid Build Coastguard Worker 
8084*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/255635821): Choose the pacesetter display, considering both internal and external
8085*38e8c45fSAndroid Build Coastguard Worker     // displays. For now, pick the other internal display, assuming a dual-display foldable.
8086*38e8c45fSAndroid Build Coastguard Worker     return findDisplay([this](const DisplayDevice& display) REQUIRES(mStateLock) {
8087*38e8c45fSAndroid Build Coastguard Worker         const auto idOpt = PhysicalDisplayId::tryCast(display.getId());
8088*38e8c45fSAndroid Build Coastguard Worker         return idOpt && *idOpt != mActiveDisplayId && display.isPoweredOn() &&
8089*38e8c45fSAndroid Build Coastguard Worker                 mPhysicalDisplays.get(*idOpt)
8090*38e8c45fSAndroid Build Coastguard Worker                         .transform(&PhysicalDisplay::isInternal)
8091*38e8c45fSAndroid Build Coastguard Worker                         .value_or(false);
8092*38e8c45fSAndroid Build Coastguard Worker     });
8093*38e8c45fSAndroid Build Coastguard Worker }
8094*38e8c45fSAndroid Build Coastguard Worker 
onActiveDisplayChangedLocked(const DisplayDevice * inactiveDisplayPtr,const DisplayDevice & activeDisplay)8095*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveDisplayPtr,
8096*38e8c45fSAndroid Build Coastguard Worker                                                   const DisplayDevice& activeDisplay) {
8097*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
8098*38e8c45fSAndroid Build Coastguard Worker 
8099*38e8c45fSAndroid Build Coastguard Worker     if (inactiveDisplayPtr) {
8100*38e8c45fSAndroid Build Coastguard Worker         inactiveDisplayPtr->getCompositionDisplay()->setLayerCachingTexturePoolEnabled(false);
8101*38e8c45fSAndroid Build Coastguard Worker     }
8102*38e8c45fSAndroid Build Coastguard Worker 
8103*38e8c45fSAndroid Build Coastguard Worker     mActiveDisplayId = activeDisplay.getPhysicalId();
8104*38e8c45fSAndroid Build Coastguard Worker     activeDisplay.getCompositionDisplay()->setLayerCachingTexturePoolEnabled(true);
8105*38e8c45fSAndroid Build Coastguard Worker 
8106*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/255635711): Check for pending mode changes on other displays.
8107*38e8c45fSAndroid Build Coastguard Worker     mScheduler->setModeChangePending(false);
8108*38e8c45fSAndroid Build Coastguard Worker 
8109*38e8c45fSAndroid Build Coastguard Worker     mScheduler->setPacesetterDisplay(mActiveDisplayId);
8110*38e8c45fSAndroid Build Coastguard Worker 
8111*38e8c45fSAndroid Build Coastguard Worker     onActiveDisplaySizeChanged(activeDisplay);
8112*38e8c45fSAndroid Build Coastguard Worker     mActiveDisplayTransformHint = activeDisplay.getTransformHint();
8113*38e8c45fSAndroid Build Coastguard Worker     sActiveDisplayRotationFlags = ui::Transform::toRotationFlags(activeDisplay.getOrientation());
8114*38e8c45fSAndroid Build Coastguard Worker 
8115*38e8c45fSAndroid Build Coastguard Worker     // Whether or not the policy of the new active/pacesetter display changed while it was inactive
8116*38e8c45fSAndroid Build Coastguard Worker     // (in which case its preferred mode has already been propagated to HWC via setDesiredMode), the
8117*38e8c45fSAndroid Build Coastguard Worker     // Scheduler's cachedModeChangedParams must be initialized to the newly active mode, and the
8118*38e8c45fSAndroid Build Coastguard Worker     // kernel idle timer of the newly active display must be toggled.
8119*38e8c45fSAndroid Build Coastguard Worker     applyRefreshRateSelectorPolicy(mActiveDisplayId, activeDisplay.refreshRateSelector());
8120*38e8c45fSAndroid Build Coastguard Worker }
8121*38e8c45fSAndroid Build Coastguard Worker 
addWindowInfosListener(const sp<IWindowInfosListener> & windowInfosListener,gui::WindowInfosListenerInfo * outInfo)8122*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::addWindowInfosListener(const sp<IWindowInfosListener>& windowInfosListener,
8123*38e8c45fSAndroid Build Coastguard Worker                                                 gui::WindowInfosListenerInfo* outInfo) {
8124*38e8c45fSAndroid Build Coastguard Worker     mWindowInfosListenerInvoker->addWindowInfosListener(windowInfosListener, outInfo);
8125*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eInputInfoUpdateNeeded);
8126*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
8127*38e8c45fSAndroid Build Coastguard Worker }
8128*38e8c45fSAndroid Build Coastguard Worker 
removeWindowInfosListener(const sp<IWindowInfosListener> & windowInfosListener) const8129*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::removeWindowInfosListener(
8130*38e8c45fSAndroid Build Coastguard Worker         const sp<IWindowInfosListener>& windowInfosListener) const {
8131*38e8c45fSAndroid Build Coastguard Worker     mWindowInfosListenerInvoker->removeWindowInfosListener(windowInfosListener);
8132*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
8133*38e8c45fSAndroid Build Coastguard Worker }
8134*38e8c45fSAndroid Build Coastguard Worker 
getStalledTransactionInfo(int pid,std::optional<TransactionHandler::StalledTransactionInfo> & result)8135*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceFlinger::getStalledTransactionInfo(
8136*38e8c45fSAndroid Build Coastguard Worker         int pid, std::optional<TransactionHandler::StalledTransactionInfo>& result) {
8137*38e8c45fSAndroid Build Coastguard Worker     // Used to add a stalled transaction which uses an internal lock.
8138*38e8c45fSAndroid Build Coastguard Worker     ftl::FakeGuard guard(kMainThreadContext);
8139*38e8c45fSAndroid Build Coastguard Worker     result = mTransactionHandler.getStalledTransactionInfo(pid);
8140*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
8141*38e8c45fSAndroid Build Coastguard Worker }
8142*38e8c45fSAndroid Build Coastguard Worker 
updateHdcpLevels(hal::HWDisplayId hwcDisplayId,int32_t connectedLevel,int32_t maxLevel)8143*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::updateHdcpLevels(hal::HWDisplayId hwcDisplayId, int32_t connectedLevel,
8144*38e8c45fSAndroid Build Coastguard Worker                                       int32_t maxLevel) {
8145*38e8c45fSAndroid Build Coastguard Worker     if (!FlagManager::getInstance().connected_display()) {
8146*38e8c45fSAndroid Build Coastguard Worker         return;
8147*38e8c45fSAndroid Build Coastguard Worker     }
8148*38e8c45fSAndroid Build Coastguard Worker 
8149*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
8150*38e8c45fSAndroid Build Coastguard Worker 
8151*38e8c45fSAndroid Build Coastguard Worker     const auto idOpt = getHwComposer().toPhysicalDisplayId(hwcDisplayId);
8152*38e8c45fSAndroid Build Coastguard Worker     if (!idOpt) {
8153*38e8c45fSAndroid Build Coastguard Worker         ALOGE("No display found for HDCP level changed event: connected=%d, max=%d for "
8154*38e8c45fSAndroid Build Coastguard Worker               "display=%" PRIu64,
8155*38e8c45fSAndroid Build Coastguard Worker               connectedLevel, maxLevel, hwcDisplayId);
8156*38e8c45fSAndroid Build Coastguard Worker         return;
8157*38e8c45fSAndroid Build Coastguard Worker     }
8158*38e8c45fSAndroid Build Coastguard Worker 
8159*38e8c45fSAndroid Build Coastguard Worker     const bool isInternalDisplay =
8160*38e8c45fSAndroid Build Coastguard Worker             mPhysicalDisplays.get(*idOpt).transform(&PhysicalDisplay::isInternal).value_or(false);
8161*38e8c45fSAndroid Build Coastguard Worker     if (isInternalDisplay) {
8162*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Unexpected HDCP level changed for internal display: connected=%d, max=%d for "
8163*38e8c45fSAndroid Build Coastguard Worker               "display=%" PRIu64,
8164*38e8c45fSAndroid Build Coastguard Worker               connectedLevel, maxLevel, hwcDisplayId);
8165*38e8c45fSAndroid Build Coastguard Worker         return;
8166*38e8c45fSAndroid Build Coastguard Worker     }
8167*38e8c45fSAndroid Build Coastguard Worker 
8168*38e8c45fSAndroid Build Coastguard Worker     static_cast<void>(mScheduler->schedule([this, displayId = *idOpt, connectedLevel, maxLevel]() {
8169*38e8c45fSAndroid Build Coastguard Worker         if (const auto display = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(displayId))) {
8170*38e8c45fSAndroid Build Coastguard Worker             Mutex::Autolock lock(mStateLock);
8171*38e8c45fSAndroid Build Coastguard Worker             display->setSecure(connectedLevel >= 2 /* HDCP_V1 */);
8172*38e8c45fSAndroid Build Coastguard Worker         }
8173*38e8c45fSAndroid Build Coastguard Worker         mScheduler->onHdcpLevelsChanged(scheduler::Cycle::Render, displayId, connectedLevel,
8174*38e8c45fSAndroid Build Coastguard Worker                                         maxLevel);
8175*38e8c45fSAndroid Build Coastguard Worker     }));
8176*38e8c45fSAndroid Build Coastguard Worker }
8177*38e8c45fSAndroid Build Coastguard Worker 
setActivePictureListener(const sp<gui::IActivePictureListener> & listener)8178*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::setActivePictureListener(const sp<gui::IActivePictureListener>& listener) {
8179*38e8c45fSAndroid Build Coastguard Worker     if (com_android_graphics_libgui_flags_apply_picture_profiles()) {
8180*38e8c45fSAndroid Build Coastguard Worker         Mutex::Autolock lock(mStateLock);
8181*38e8c45fSAndroid Build Coastguard Worker         mActivePictureListener = listener;
8182*38e8c45fSAndroid Build Coastguard Worker         mHaveNewActivePictureListener = listener != nullptr;
8183*38e8c45fSAndroid Build Coastguard Worker     }
8184*38e8c45fSAndroid Build Coastguard Worker }
8185*38e8c45fSAndroid Build Coastguard Worker 
getExternalTextureFromBufferData(BufferData & bufferData,const char * layerName,uint64_t transactionId)8186*38e8c45fSAndroid Build Coastguard Worker std::shared_ptr<renderengine::ExternalTexture> SurfaceFlinger::getExternalTextureFromBufferData(
8187*38e8c45fSAndroid Build Coastguard Worker         BufferData& bufferData, const char* layerName, uint64_t transactionId) {
8188*38e8c45fSAndroid Build Coastguard Worker     if (bufferData.buffer &&
8189*38e8c45fSAndroid Build Coastguard Worker         exceedsMaxRenderTargetSize(bufferData.buffer->getWidth(), bufferData.buffer->getHeight())) {
8190*38e8c45fSAndroid Build Coastguard Worker         std::string errorMessage =
8191*38e8c45fSAndroid Build Coastguard Worker                 base::StringPrintf("Attempted to create an ExternalTexture with size (%u, %u) for "
8192*38e8c45fSAndroid Build Coastguard Worker                                    "layer %s that exceeds render target size limit of %u.",
8193*38e8c45fSAndroid Build Coastguard Worker                                    bufferData.buffer->getWidth(), bufferData.buffer->getHeight(),
8194*38e8c45fSAndroid Build Coastguard Worker                                    layerName, static_cast<uint32_t>(mMaxRenderTargetSize));
8195*38e8c45fSAndroid Build Coastguard Worker         ALOGD("%s", errorMessage.c_str());
8196*38e8c45fSAndroid Build Coastguard Worker         if (bufferData.releaseBufferListener) {
8197*38e8c45fSAndroid Build Coastguard Worker             bufferData.releaseBufferListener->onTransactionQueueStalled(
8198*38e8c45fSAndroid Build Coastguard Worker                     String8(errorMessage.c_str()));
8199*38e8c45fSAndroid Build Coastguard Worker         }
8200*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
8201*38e8c45fSAndroid Build Coastguard Worker     }
8202*38e8c45fSAndroid Build Coastguard Worker 
8203*38e8c45fSAndroid Build Coastguard Worker     bool cachedBufferChanged =
8204*38e8c45fSAndroid Build Coastguard Worker             bufferData.flags.test(BufferData::BufferDataChange::cachedBufferChanged);
8205*38e8c45fSAndroid Build Coastguard Worker     if (cachedBufferChanged && bufferData.buffer) {
8206*38e8c45fSAndroid Build Coastguard Worker         auto result = ClientCache::getInstance().add(bufferData.cachedBuffer, bufferData.buffer);
8207*38e8c45fSAndroid Build Coastguard Worker         if (result.ok()) {
8208*38e8c45fSAndroid Build Coastguard Worker             return result.value();
8209*38e8c45fSAndroid Build Coastguard Worker         }
8210*38e8c45fSAndroid Build Coastguard Worker 
8211*38e8c45fSAndroid Build Coastguard Worker         if (result.error() == ClientCache::AddError::CacheFull) {
8212*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Attempted to create an ExternalTexture for layer %s but CacheFull", layerName);
8213*38e8c45fSAndroid Build Coastguard Worker 
8214*38e8c45fSAndroid Build Coastguard Worker             if (bufferData.releaseBufferListener) {
8215*38e8c45fSAndroid Build Coastguard Worker                 bufferData.releaseBufferListener->onTransactionQueueStalled(
8216*38e8c45fSAndroid Build Coastguard Worker                         String8("Buffer processing hung due to full buffer cache"));
8217*38e8c45fSAndroid Build Coastguard Worker             }
8218*38e8c45fSAndroid Build Coastguard Worker         }
8219*38e8c45fSAndroid Build Coastguard Worker 
8220*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
8221*38e8c45fSAndroid Build Coastguard Worker     }
8222*38e8c45fSAndroid Build Coastguard Worker 
8223*38e8c45fSAndroid Build Coastguard Worker     if (cachedBufferChanged) {
8224*38e8c45fSAndroid Build Coastguard Worker         return ClientCache::getInstance().get(bufferData.cachedBuffer);
8225*38e8c45fSAndroid Build Coastguard Worker     }
8226*38e8c45fSAndroid Build Coastguard Worker 
8227*38e8c45fSAndroid Build Coastguard Worker     if (bufferData.buffer) {
8228*38e8c45fSAndroid Build Coastguard Worker         return std::make_shared<
8229*38e8c45fSAndroid Build Coastguard Worker                 renderengine::impl::ExternalTexture>(bufferData.buffer, getRenderEngine(),
8230*38e8c45fSAndroid Build Coastguard Worker                                                      renderengine::impl::ExternalTexture::Usage::
8231*38e8c45fSAndroid Build Coastguard Worker                                                              READABLE);
8232*38e8c45fSAndroid Build Coastguard Worker     }
8233*38e8c45fSAndroid Build Coastguard Worker 
8234*38e8c45fSAndroid Build Coastguard Worker     return nullptr;
8235*38e8c45fSAndroid Build Coastguard Worker }
8236*38e8c45fSAndroid Build Coastguard Worker 
moveSnapshotsFromCompositionArgs(compositionengine::CompositionRefreshArgs & refreshArgs,const std::vector<std::pair<Layer *,LayerFE * >> & layers)8237*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::moveSnapshotsFromCompositionArgs(
8238*38e8c45fSAndroid Build Coastguard Worker         compositionengine::CompositionRefreshArgs& refreshArgs,
8239*38e8c45fSAndroid Build Coastguard Worker         const std::vector<std::pair<Layer*, LayerFE*>>& layers) {
8240*38e8c45fSAndroid Build Coastguard Worker     std::vector<std::unique_ptr<frontend::LayerSnapshot>>& snapshots =
8241*38e8c45fSAndroid Build Coastguard Worker             mLayerSnapshotBuilder.getSnapshots();
8242*38e8c45fSAndroid Build Coastguard Worker     for (auto [_, layerFE] : layers) {
8243*38e8c45fSAndroid Build Coastguard Worker         auto i = layerFE->mSnapshot->globalZ;
8244*38e8c45fSAndroid Build Coastguard Worker         snapshots[i] = std::move(layerFE->mSnapshot);
8245*38e8c45fSAndroid Build Coastguard Worker     }
8246*38e8c45fSAndroid Build Coastguard Worker }
8247*38e8c45fSAndroid Build Coastguard Worker 
moveSnapshotsToCompositionArgs(compositionengine::CompositionRefreshArgs & refreshArgs,bool cursorOnly)8248*38e8c45fSAndroid Build Coastguard Worker std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToCompositionArgs(
8249*38e8c45fSAndroid Build Coastguard Worker         compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly) {
8250*38e8c45fSAndroid Build Coastguard Worker     std::vector<std::pair<Layer*, LayerFE*>> layers;
8251*38e8c45fSAndroid Build Coastguard Worker     nsecs_t currentTime = systemTime();
8252*38e8c45fSAndroid Build Coastguard Worker     const bool needsMetadata = mCompositionEngine->getFeatureFlags().test(
8253*38e8c45fSAndroid Build Coastguard Worker             compositionengine::Feature::kSnapshotLayerMetadata);
8254*38e8c45fSAndroid Build Coastguard Worker     mLayerSnapshotBuilder.forEachSnapshot(
8255*38e8c45fSAndroid Build Coastguard Worker             [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD(
8256*38e8c45fSAndroid Build Coastguard Worker                     kMainThreadContext) {
8257*38e8c45fSAndroid Build Coastguard Worker                 if (cursorOnly &&
8258*38e8c45fSAndroid Build Coastguard Worker                     snapshot->compositionType !=
8259*38e8c45fSAndroid Build Coastguard Worker                             aidl::android::hardware::graphics::composer3::Composition::CURSOR) {
8260*38e8c45fSAndroid Build Coastguard Worker                     return;
8261*38e8c45fSAndroid Build Coastguard Worker                 }
8262*38e8c45fSAndroid Build Coastguard Worker 
8263*38e8c45fSAndroid Build Coastguard Worker                 if (!snapshot->hasSomethingToDraw()) {
8264*38e8c45fSAndroid Build Coastguard Worker                     return;
8265*38e8c45fSAndroid Build Coastguard Worker                 }
8266*38e8c45fSAndroid Build Coastguard Worker 
8267*38e8c45fSAndroid Build Coastguard Worker                 auto it = mLegacyLayers.find(snapshot->sequence);
8268*38e8c45fSAndroid Build Coastguard Worker                 LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
8269*38e8c45fSAndroid Build Coastguard Worker                                                 "Couldnt find layer object for %s",
8270*38e8c45fSAndroid Build Coastguard Worker                                                 snapshot->getDebugString().c_str());
8271*38e8c45fSAndroid Build Coastguard Worker                 auto& legacyLayer = it->second;
8272*38e8c45fSAndroid Build Coastguard Worker                 sp<LayerFE> layerFE = legacyLayer->getCompositionEngineLayerFE(snapshot->path);
8273*38e8c45fSAndroid Build Coastguard Worker                 snapshot->fps = getLayerFramerate(currentTime, snapshot->sequence);
8274*38e8c45fSAndroid Build Coastguard Worker                 layerFE->mSnapshot = std::move(snapshot);
8275*38e8c45fSAndroid Build Coastguard Worker                 refreshArgs.layers.push_back(layerFE);
8276*38e8c45fSAndroid Build Coastguard Worker                 layers.emplace_back(legacyLayer.get(), layerFE.get());
8277*38e8c45fSAndroid Build Coastguard Worker             },
8278*38e8c45fSAndroid Build Coastguard Worker             [needsMetadata](const frontend::LayerSnapshot& snapshot) {
8279*38e8c45fSAndroid Build Coastguard Worker                 return snapshot.isVisible ||
8280*38e8c45fSAndroid Build Coastguard Worker                         (needsMetadata &&
8281*38e8c45fSAndroid Build Coastguard Worker                          snapshot.changes.test(frontend::RequestedLayerState::Changes::Metadata));
8282*38e8c45fSAndroid Build Coastguard Worker             });
8283*38e8c45fSAndroid Build Coastguard Worker     return layers;
8284*38e8c45fSAndroid Build Coastguard Worker }
8285*38e8c45fSAndroid Build Coastguard Worker 
8286*38e8c45fSAndroid Build Coastguard Worker std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>
getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> layerStack,uint32_t uid,std::function<bool (const frontend::LayerSnapshot &,bool & outStopTraversal)> snapshotFilterFn)8287*38e8c45fSAndroid Build Coastguard Worker SurfaceFlinger::getLayerSnapshotsForScreenshots(
8288*38e8c45fSAndroid Build Coastguard Worker         std::optional<ui::LayerStack> layerStack, uint32_t uid,
8289*38e8c45fSAndroid Build Coastguard Worker         std::function<bool(const frontend::LayerSnapshot&, bool& outStopTraversal)>
8290*38e8c45fSAndroid Build Coastguard Worker                 snapshotFilterFn) {
8291*38e8c45fSAndroid Build Coastguard Worker     return [&, layerStack, uid]() FTL_FAKE_GUARD(kMainThreadContext) {
8292*38e8c45fSAndroid Build Coastguard Worker         std::vector<std::pair<Layer*, sp<LayerFE>>> layers;
8293*38e8c45fSAndroid Build Coastguard Worker         bool stopTraversal = false;
8294*38e8c45fSAndroid Build Coastguard Worker         mLayerSnapshotBuilder.forEachVisibleSnapshot(
8295*38e8c45fSAndroid Build Coastguard Worker                 [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD(
8296*38e8c45fSAndroid Build Coastguard Worker                         kMainThreadContext) {
8297*38e8c45fSAndroid Build Coastguard Worker                     if (stopTraversal) {
8298*38e8c45fSAndroid Build Coastguard Worker                         return;
8299*38e8c45fSAndroid Build Coastguard Worker                     }
8300*38e8c45fSAndroid Build Coastguard Worker                     if (layerStack && snapshot->outputFilter.layerStack != *layerStack) {
8301*38e8c45fSAndroid Build Coastguard Worker                         return;
8302*38e8c45fSAndroid Build Coastguard Worker                     }
8303*38e8c45fSAndroid Build Coastguard Worker                     if (uid != CaptureArgs::UNSET_UID && snapshot->uid != gui::Uid(uid)) {
8304*38e8c45fSAndroid Build Coastguard Worker                         return;
8305*38e8c45fSAndroid Build Coastguard Worker                     }
8306*38e8c45fSAndroid Build Coastguard Worker                     if (!snapshot->hasSomethingToDraw()) {
8307*38e8c45fSAndroid Build Coastguard Worker                         return;
8308*38e8c45fSAndroid Build Coastguard Worker                     }
8309*38e8c45fSAndroid Build Coastguard Worker                     if (snapshotFilterFn && !snapshotFilterFn(*snapshot, stopTraversal)) {
8310*38e8c45fSAndroid Build Coastguard Worker                         return;
8311*38e8c45fSAndroid Build Coastguard Worker                     }
8312*38e8c45fSAndroid Build Coastguard Worker 
8313*38e8c45fSAndroid Build Coastguard Worker                     auto it = mLegacyLayers.find(snapshot->sequence);
8314*38e8c45fSAndroid Build Coastguard Worker                     LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
8315*38e8c45fSAndroid Build Coastguard Worker                                                     "Couldnt find layer object for %s",
8316*38e8c45fSAndroid Build Coastguard Worker                                                     snapshot->getDebugString().c_str());
8317*38e8c45fSAndroid Build Coastguard Worker                     Layer* legacyLayer = (it == mLegacyLayers.end()) ? nullptr : it->second.get();
8318*38e8c45fSAndroid Build Coastguard Worker                     sp<LayerFE> layerFE = getFactory().createLayerFE(snapshot->name, legacyLayer);
8319*38e8c45fSAndroid Build Coastguard Worker                     layerFE->mSnapshot = std::make_unique<frontend::LayerSnapshot>(*snapshot);
8320*38e8c45fSAndroid Build Coastguard Worker                     layers.emplace_back(legacyLayer, std::move(layerFE));
8321*38e8c45fSAndroid Build Coastguard Worker                 });
8322*38e8c45fSAndroid Build Coastguard Worker 
8323*38e8c45fSAndroid Build Coastguard Worker         return layers;
8324*38e8c45fSAndroid Build Coastguard Worker     };
8325*38e8c45fSAndroid Build Coastguard Worker }
8326*38e8c45fSAndroid Build Coastguard Worker 
8327*38e8c45fSAndroid Build Coastguard Worker std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>
getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> layerStack,uint32_t uid,std::unordered_set<uint32_t> excludeLayerIds)8328*38e8c45fSAndroid Build Coastguard Worker SurfaceFlinger::getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> layerStack,
8329*38e8c45fSAndroid Build Coastguard Worker                                                 uint32_t uid,
8330*38e8c45fSAndroid Build Coastguard Worker                                                 std::unordered_set<uint32_t> excludeLayerIds) {
8331*38e8c45fSAndroid Build Coastguard Worker     return [&, layerStack, uid,
8332*38e8c45fSAndroid Build Coastguard Worker             excludeLayerIds = std::move(excludeLayerIds)]() FTL_FAKE_GUARD(kMainThreadContext) {
8333*38e8c45fSAndroid Build Coastguard Worker         if (excludeLayerIds.empty()) {
8334*38e8c45fSAndroid Build Coastguard Worker             auto getLayerSnapshotsFn =
8335*38e8c45fSAndroid Build Coastguard Worker                     getLayerSnapshotsForScreenshots(layerStack, uid, /*snapshotFilterFn=*/nullptr);
8336*38e8c45fSAndroid Build Coastguard Worker             std::vector<std::pair<Layer*, sp<LayerFE>>> layers = getLayerSnapshotsFn();
8337*38e8c45fSAndroid Build Coastguard Worker             return layers;
8338*38e8c45fSAndroid Build Coastguard Worker         }
8339*38e8c45fSAndroid Build Coastguard Worker 
8340*38e8c45fSAndroid Build Coastguard Worker         frontend::LayerSnapshotBuilder::Args
8341*38e8c45fSAndroid Build Coastguard Worker                 args{.root = mLayerHierarchyBuilder.getHierarchy(),
8342*38e8c45fSAndroid Build Coastguard Worker                      .layerLifecycleManager = mLayerLifecycleManager,
8343*38e8c45fSAndroid Build Coastguard Worker                      .forceUpdate = frontend::LayerSnapshotBuilder::ForceUpdateFlags::HIERARCHY,
8344*38e8c45fSAndroid Build Coastguard Worker                      .displays = mFrontEndDisplayInfos,
8345*38e8c45fSAndroid Build Coastguard Worker                      .displayChanges = true,
8346*38e8c45fSAndroid Build Coastguard Worker                      .globalShadowSettings = mDrawingState.globalShadowSettings,
8347*38e8c45fSAndroid Build Coastguard Worker                      .supportsBlur = mSupportsBlur,
8348*38e8c45fSAndroid Build Coastguard Worker                      .forceFullDamage = mForceFullDamage,
8349*38e8c45fSAndroid Build Coastguard Worker                      .excludeLayerIds = std::move(excludeLayerIds),
8350*38e8c45fSAndroid Build Coastguard Worker                      .supportedLayerGenericMetadata =
8351*38e8c45fSAndroid Build Coastguard Worker                              getHwComposer().getSupportedLayerGenericMetadata(),
8352*38e8c45fSAndroid Build Coastguard Worker                      .genericLayerMetadataKeyMap = getGenericLayerMetadataKeyMap(),
8353*38e8c45fSAndroid Build Coastguard Worker                      .skipRoundCornersWhenProtected =
8354*38e8c45fSAndroid Build Coastguard Worker                              !getRenderEngine().supportsProtectedContent()};
8355*38e8c45fSAndroid Build Coastguard Worker         mLayerSnapshotBuilder.update(args);
8356*38e8c45fSAndroid Build Coastguard Worker 
8357*38e8c45fSAndroid Build Coastguard Worker         auto getLayerSnapshotsFn =
8358*38e8c45fSAndroid Build Coastguard Worker                 getLayerSnapshotsForScreenshots(layerStack, uid, /*snapshotFilterFn=*/nullptr);
8359*38e8c45fSAndroid Build Coastguard Worker         std::vector<std::pair<Layer*, sp<LayerFE>>> layers = getLayerSnapshotsFn();
8360*38e8c45fSAndroid Build Coastguard Worker 
8361*38e8c45fSAndroid Build Coastguard Worker         args.excludeLayerIds.clear();
8362*38e8c45fSAndroid Build Coastguard Worker         mLayerSnapshotBuilder.update(args);
8363*38e8c45fSAndroid Build Coastguard Worker 
8364*38e8c45fSAndroid Build Coastguard Worker         return layers;
8365*38e8c45fSAndroid Build Coastguard Worker     };
8366*38e8c45fSAndroid Build Coastguard Worker }
8367*38e8c45fSAndroid Build Coastguard Worker 
8368*38e8c45fSAndroid Build Coastguard Worker std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>
getLayerSnapshotsForScreenshots(uint32_t rootLayerId,uint32_t uid,std::unordered_set<uint32_t> excludeLayerIds,bool childrenOnly,const std::optional<FloatRect> & parentCrop)8369*38e8c45fSAndroid Build Coastguard Worker SurfaceFlinger::getLayerSnapshotsForScreenshots(uint32_t rootLayerId, uint32_t uid,
8370*38e8c45fSAndroid Build Coastguard Worker                                                 std::unordered_set<uint32_t> excludeLayerIds,
8371*38e8c45fSAndroid Build Coastguard Worker                                                 bool childrenOnly,
8372*38e8c45fSAndroid Build Coastguard Worker                                                 const std::optional<FloatRect>& parentCrop) {
8373*38e8c45fSAndroid Build Coastguard Worker     return [&, rootLayerId, uid, excludeLayerIds = std::move(excludeLayerIds), childrenOnly,
8374*38e8c45fSAndroid Build Coastguard Worker             parentCrop]() FTL_FAKE_GUARD(kMainThreadContext) {
8375*38e8c45fSAndroid Build Coastguard Worker         auto root = mLayerHierarchyBuilder.getPartialHierarchy(rootLayerId, childrenOnly);
8376*38e8c45fSAndroid Build Coastguard Worker         frontend::LayerSnapshotBuilder::Args
8377*38e8c45fSAndroid Build Coastguard Worker                 args{.root = root,
8378*38e8c45fSAndroid Build Coastguard Worker                      .layerLifecycleManager = mLayerLifecycleManager,
8379*38e8c45fSAndroid Build Coastguard Worker                      .forceUpdate = frontend::LayerSnapshotBuilder::ForceUpdateFlags::HIERARCHY,
8380*38e8c45fSAndroid Build Coastguard Worker                      .displays = mFrontEndDisplayInfos,
8381*38e8c45fSAndroid Build Coastguard Worker                      .displayChanges = true,
8382*38e8c45fSAndroid Build Coastguard Worker                      .globalShadowSettings = mDrawingState.globalShadowSettings,
8383*38e8c45fSAndroid Build Coastguard Worker                      .supportsBlur = mSupportsBlur,
8384*38e8c45fSAndroid Build Coastguard Worker                      .forceFullDamage = mForceFullDamage,
8385*38e8c45fSAndroid Build Coastguard Worker                      .parentCrop = parentCrop,
8386*38e8c45fSAndroid Build Coastguard Worker                      .excludeLayerIds = std::move(excludeLayerIds),
8387*38e8c45fSAndroid Build Coastguard Worker                      .supportedLayerGenericMetadata =
8388*38e8c45fSAndroid Build Coastguard Worker                              getHwComposer().getSupportedLayerGenericMetadata(),
8389*38e8c45fSAndroid Build Coastguard Worker                      .genericLayerMetadataKeyMap = getGenericLayerMetadataKeyMap(),
8390*38e8c45fSAndroid Build Coastguard Worker                      .skipRoundCornersWhenProtected =
8391*38e8c45fSAndroid Build Coastguard Worker                              !getRenderEngine().supportsProtectedContent()};
8392*38e8c45fSAndroid Build Coastguard Worker         // The layer may not exist if it was just created and a screenshot was requested immediately
8393*38e8c45fSAndroid Build Coastguard Worker         // after. In this case, the hierarchy will be empty so we will not render any layers.
8394*38e8c45fSAndroid Build Coastguard Worker         args.rootSnapshot.isSecure = mLayerLifecycleManager.getLayerFromId(rootLayerId) &&
8395*38e8c45fSAndroid Build Coastguard Worker                 mLayerLifecycleManager.isLayerSecure(rootLayerId);
8396*38e8c45fSAndroid Build Coastguard Worker         mLayerSnapshotBuilder.update(args);
8397*38e8c45fSAndroid Build Coastguard Worker 
8398*38e8c45fSAndroid Build Coastguard Worker         auto getLayerSnapshotsFn =
8399*38e8c45fSAndroid Build Coastguard Worker                 getLayerSnapshotsForScreenshots({}, uid, /*snapshotFilterFn=*/nullptr);
8400*38e8c45fSAndroid Build Coastguard Worker         std::vector<std::pair<Layer*, sp<LayerFE>>> layers = getLayerSnapshotsFn();
8401*38e8c45fSAndroid Build Coastguard Worker         args.root = mLayerHierarchyBuilder.getHierarchy();
8402*38e8c45fSAndroid Build Coastguard Worker         args.parentCrop.reset();
8403*38e8c45fSAndroid Build Coastguard Worker         args.excludeLayerIds.clear();
8404*38e8c45fSAndroid Build Coastguard Worker         mLayerSnapshotBuilder.update(args);
8405*38e8c45fSAndroid Build Coastguard Worker         return layers;
8406*38e8c45fSAndroid Build Coastguard Worker     };
8407*38e8c45fSAndroid Build Coastguard Worker }
8408*38e8c45fSAndroid Build Coastguard Worker 
doActiveLayersTracingIfNeeded(bool isCompositionComputed,bool visibleRegionDirty,TimePoint time,VsyncId vsyncId)8409*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::doActiveLayersTracingIfNeeded(bool isCompositionComputed,
8410*38e8c45fSAndroid Build Coastguard Worker                                                    bool visibleRegionDirty, TimePoint time,
8411*38e8c45fSAndroid Build Coastguard Worker                                                    VsyncId vsyncId) {
8412*38e8c45fSAndroid Build Coastguard Worker     if (!mLayerTracing.isActiveTracingStarted()) {
8413*38e8c45fSAndroid Build Coastguard Worker         return;
8414*38e8c45fSAndroid Build Coastguard Worker     }
8415*38e8c45fSAndroid Build Coastguard Worker     if (isCompositionComputed !=
8416*38e8c45fSAndroid Build Coastguard Worker         mLayerTracing.isActiveTracingFlagSet(LayerTracing::Flag::TRACE_COMPOSITION)) {
8417*38e8c45fSAndroid Build Coastguard Worker         return;
8418*38e8c45fSAndroid Build Coastguard Worker     }
8419*38e8c45fSAndroid Build Coastguard Worker     if (!visibleRegionDirty &&
8420*38e8c45fSAndroid Build Coastguard Worker         !mLayerTracing.isActiveTracingFlagSet(LayerTracing::Flag::TRACE_BUFFERS)) {
8421*38e8c45fSAndroid Build Coastguard Worker         return;
8422*38e8c45fSAndroid Build Coastguard Worker     }
8423*38e8c45fSAndroid Build Coastguard Worker     auto snapshot = takeLayersSnapshotProto(mLayerTracing.getActiveTracingFlags(), time, vsyncId,
8424*38e8c45fSAndroid Build Coastguard Worker                                             visibleRegionDirty);
8425*38e8c45fSAndroid Build Coastguard Worker     mLayerTracing.addProtoSnapshotToOstream(std::move(snapshot), LayerTracing::Mode::MODE_ACTIVE);
8426*38e8c45fSAndroid Build Coastguard Worker }
8427*38e8c45fSAndroid Build Coastguard Worker 
takeLayersSnapshotProto(uint32_t traceFlags,TimePoint time,VsyncId vsyncId,bool visibleRegionDirty)8428*38e8c45fSAndroid Build Coastguard Worker perfetto::protos::LayersSnapshotProto SurfaceFlinger::takeLayersSnapshotProto(
8429*38e8c45fSAndroid Build Coastguard Worker         uint32_t traceFlags, TimePoint time, VsyncId vsyncId, bool visibleRegionDirty) {
8430*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
8431*38e8c45fSAndroid Build Coastguard Worker     perfetto::protos::LayersSnapshotProto snapshot;
8432*38e8c45fSAndroid Build Coastguard Worker     snapshot.set_elapsed_realtime_nanos(time.ns());
8433*38e8c45fSAndroid Build Coastguard Worker     snapshot.set_vsync_id(ftl::to_underlying(vsyncId));
8434*38e8c45fSAndroid Build Coastguard Worker     snapshot.set_where(visibleRegionDirty ? "visibleRegionsDirty" : "bufferLatched");
8435*38e8c45fSAndroid Build Coastguard Worker     snapshot.set_excludes_composition_state((traceFlags & LayerTracing::Flag::TRACE_COMPOSITION) ==
8436*38e8c45fSAndroid Build Coastguard Worker                                             0);
8437*38e8c45fSAndroid Build Coastguard Worker 
8438*38e8c45fSAndroid Build Coastguard Worker     auto layers = dumpDrawingStateProto(traceFlags);
8439*38e8c45fSAndroid Build Coastguard Worker     *snapshot.mutable_layers() = std::move(layers);
8440*38e8c45fSAndroid Build Coastguard Worker 
8441*38e8c45fSAndroid Build Coastguard Worker     if (traceFlags & LayerTracing::Flag::TRACE_HWC) {
8442*38e8c45fSAndroid Build Coastguard Worker         std::string hwcDump;
8443*38e8c45fSAndroid Build Coastguard Worker         dumpHwc(hwcDump);
8444*38e8c45fSAndroid Build Coastguard Worker         snapshot.set_hwc_blob(std::move(hwcDump));
8445*38e8c45fSAndroid Build Coastguard Worker     }
8446*38e8c45fSAndroid Build Coastguard Worker 
8447*38e8c45fSAndroid Build Coastguard Worker     *snapshot.mutable_displays() = dumpDisplayProto();
8448*38e8c45fSAndroid Build Coastguard Worker 
8449*38e8c45fSAndroid Build Coastguard Worker     return snapshot;
8450*38e8c45fSAndroid Build Coastguard Worker }
8451*38e8c45fSAndroid Build Coastguard Worker 
8452*38e8c45fSAndroid Build Coastguard Worker // sfdo functions
8453*38e8c45fSAndroid Build Coastguard Worker 
sfdo_enableRefreshRateOverlay(bool active)8454*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::sfdo_enableRefreshRateOverlay(bool active) {
8455*38e8c45fSAndroid Build Coastguard Worker     auto future = mScheduler->schedule(
8456*38e8c45fSAndroid Build Coastguard Worker             [&]() FTL_FAKE_GUARD(mStateLock)
8457*38e8c45fSAndroid Build Coastguard Worker                     FTL_FAKE_GUARD(kMainThreadContext) { enableRefreshRateOverlay(active); });
8458*38e8c45fSAndroid Build Coastguard Worker     future.wait();
8459*38e8c45fSAndroid Build Coastguard Worker }
8460*38e8c45fSAndroid Build Coastguard Worker 
sfdo_setDebugFlash(int delay)8461*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::sfdo_setDebugFlash(int delay) {
8462*38e8c45fSAndroid Build Coastguard Worker     if (delay > 0) {
8463*38e8c45fSAndroid Build Coastguard Worker         mDebugFlashDelay = delay;
8464*38e8c45fSAndroid Build Coastguard Worker     } else {
8465*38e8c45fSAndroid Build Coastguard Worker         mDebugFlashDelay = mDebugFlashDelay ? 0 : 1;
8466*38e8c45fSAndroid Build Coastguard Worker     }
8467*38e8c45fSAndroid Build Coastguard Worker     scheduleRepaint();
8468*38e8c45fSAndroid Build Coastguard Worker }
8469*38e8c45fSAndroid Build Coastguard Worker 
sfdo_scheduleComposite()8470*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::sfdo_scheduleComposite() {
8471*38e8c45fSAndroid Build Coastguard Worker     scheduleComposite(SurfaceFlinger::FrameHint::kActive);
8472*38e8c45fSAndroid Build Coastguard Worker }
8473*38e8c45fSAndroid Build Coastguard Worker 
sfdo_scheduleCommit()8474*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::sfdo_scheduleCommit() {
8475*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mStateLock);
8476*38e8c45fSAndroid Build Coastguard Worker     setTransactionFlags(eTransactionNeeded | eDisplayTransactionNeeded | eTraversalNeeded);
8477*38e8c45fSAndroid Build Coastguard Worker }
8478*38e8c45fSAndroid Build Coastguard Worker 
sfdo_forceClientComposition(bool enabled)8479*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::sfdo_forceClientComposition(bool enabled) {
8480*38e8c45fSAndroid Build Coastguard Worker     mDebugDisableHWC = enabled;
8481*38e8c45fSAndroid Build Coastguard Worker     scheduleRepaint();
8482*38e8c45fSAndroid Build Coastguard Worker }
8483*38e8c45fSAndroid Build Coastguard Worker 
8484*38e8c45fSAndroid Build Coastguard Worker // gui::ISurfaceComposer
8485*38e8c45fSAndroid Build Coastguard Worker 
bootFinished()8486*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::bootFinished() {
8487*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8488*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
8489*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
8490*38e8c45fSAndroid Build Coastguard Worker     }
8491*38e8c45fSAndroid Build Coastguard Worker     mFlinger->bootFinished();
8492*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
8493*38e8c45fSAndroid Build Coastguard Worker }
8494*38e8c45fSAndroid Build Coastguard Worker 
createDisplayEventConnection(VsyncSource vsyncSource,EventRegistration eventRegistration,const sp<IBinder> & layerHandle,sp<IDisplayEventConnection> * outConnection)8495*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::createDisplayEventConnection(
8496*38e8c45fSAndroid Build Coastguard Worker         VsyncSource vsyncSource, EventRegistration eventRegistration,
8497*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& layerHandle, sp<IDisplayEventConnection>* outConnection) {
8498*38e8c45fSAndroid Build Coastguard Worker     sp<IDisplayEventConnection> conn =
8499*38e8c45fSAndroid Build Coastguard Worker             mFlinger->createDisplayEventConnection(vsyncSource, eventRegistration, layerHandle);
8500*38e8c45fSAndroid Build Coastguard Worker     if (conn == nullptr) {
8501*38e8c45fSAndroid Build Coastguard Worker         *outConnection = nullptr;
8502*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(BAD_VALUE);
8503*38e8c45fSAndroid Build Coastguard Worker     } else {
8504*38e8c45fSAndroid Build Coastguard Worker         *outConnection = conn;
8505*38e8c45fSAndroid Build Coastguard Worker         return binder::Status::ok();
8506*38e8c45fSAndroid Build Coastguard Worker     }
8507*38e8c45fSAndroid Build Coastguard Worker }
8508*38e8c45fSAndroid Build Coastguard Worker 
createConnection(sp<gui::ISurfaceComposerClient> * outClient)8509*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::createConnection(sp<gui::ISurfaceComposerClient>* outClient) {
8510*38e8c45fSAndroid Build Coastguard Worker     const sp<Client> client = sp<Client>::make(mFlinger);
8511*38e8c45fSAndroid Build Coastguard Worker     if (client->initCheck() == NO_ERROR) {
8512*38e8c45fSAndroid Build Coastguard Worker         *outClient = client;
8513*38e8c45fSAndroid Build Coastguard Worker         if (FlagManager::getInstance().misc1()) {
8514*38e8c45fSAndroid Build Coastguard Worker             const int policy = SCHED_FIFO;
8515*38e8c45fSAndroid Build Coastguard Worker             client->setMinSchedulerPolicy(policy, sched_get_priority_min(policy));
8516*38e8c45fSAndroid Build Coastguard Worker         }
8517*38e8c45fSAndroid Build Coastguard Worker         return binder::Status::ok();
8518*38e8c45fSAndroid Build Coastguard Worker     } else {
8519*38e8c45fSAndroid Build Coastguard Worker         *outClient = nullptr;
8520*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(BAD_VALUE);
8521*38e8c45fSAndroid Build Coastguard Worker     }
8522*38e8c45fSAndroid Build Coastguard Worker }
8523*38e8c45fSAndroid Build Coastguard Worker 
createVirtualDisplay(const std::string & displayName,bool isSecure,const std::string & uniqueId,float requestedRefreshRate,sp<IBinder> * outDisplay)8524*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::createVirtualDisplay(const std::string& displayName,
8525*38e8c45fSAndroid Build Coastguard Worker                                                          bool isSecure, const std::string& uniqueId,
8526*38e8c45fSAndroid Build Coastguard Worker                                                          float requestedRefreshRate,
8527*38e8c45fSAndroid Build Coastguard Worker                                                          sp<IBinder>* outDisplay) {
8528*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8529*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
8530*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
8531*38e8c45fSAndroid Build Coastguard Worker     }
8532*38e8c45fSAndroid Build Coastguard Worker     *outDisplay =
8533*38e8c45fSAndroid Build Coastguard Worker             mFlinger->createVirtualDisplay(displayName, isSecure, uniqueId, requestedRefreshRate);
8534*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
8535*38e8c45fSAndroid Build Coastguard Worker }
8536*38e8c45fSAndroid Build Coastguard Worker 
destroyVirtualDisplay(const sp<IBinder> & displayToken)8537*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::destroyVirtualDisplay(const sp<IBinder>& displayToken) {
8538*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8539*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
8540*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
8541*38e8c45fSAndroid Build Coastguard Worker     }
8542*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::fromStatusT(mFlinger->destroyVirtualDisplay(displayToken));
8543*38e8c45fSAndroid Build Coastguard Worker }
8544*38e8c45fSAndroid Build Coastguard Worker 
getPhysicalDisplayIds(std::vector<int64_t> * outDisplayIds)8545*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getPhysicalDisplayIds(std::vector<int64_t>* outDisplayIds) {
8546*38e8c45fSAndroid Build Coastguard Worker     std::vector<PhysicalDisplayId> physicalDisplayIds = mFlinger->getPhysicalDisplayIds();
8547*38e8c45fSAndroid Build Coastguard Worker     std::vector<int64_t> displayIds;
8548*38e8c45fSAndroid Build Coastguard Worker     displayIds.reserve(physicalDisplayIds.size());
8549*38e8c45fSAndroid Build Coastguard Worker     for (const auto id : physicalDisplayIds) {
8550*38e8c45fSAndroid Build Coastguard Worker         displayIds.push_back(static_cast<int64_t>(id.value));
8551*38e8c45fSAndroid Build Coastguard Worker     }
8552*38e8c45fSAndroid Build Coastguard Worker     *outDisplayIds = std::move(displayIds);
8553*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
8554*38e8c45fSAndroid Build Coastguard Worker }
8555*38e8c45fSAndroid Build Coastguard Worker 
getPhysicalDisplayToken(int64_t displayId,sp<IBinder> * outDisplay)8556*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getPhysicalDisplayToken(int64_t displayId,
8557*38e8c45fSAndroid Build Coastguard Worker                                                             sp<IBinder>* outDisplay) {
8558*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8559*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
8560*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
8561*38e8c45fSAndroid Build Coastguard Worker     }
8562*38e8c45fSAndroid Build Coastguard Worker     const auto id = DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(displayId));
8563*38e8c45fSAndroid Build Coastguard Worker     *outDisplay = mFlinger->getPhysicalDisplayToken(*id);
8564*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
8565*38e8c45fSAndroid Build Coastguard Worker }
8566*38e8c45fSAndroid Build Coastguard Worker 
setPowerMode(const sp<IBinder> & display,int mode)8567*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setPowerMode(const sp<IBinder>& display, int mode) {
8568*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8569*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
8570*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
8571*38e8c45fSAndroid Build Coastguard Worker     }
8572*38e8c45fSAndroid Build Coastguard Worker     mFlinger->setPowerMode(display, mode);
8573*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
8574*38e8c45fSAndroid Build Coastguard Worker }
8575*38e8c45fSAndroid Build Coastguard Worker 
getSupportedFrameTimestamps(std::vector<FrameEvent> * outSupported)8576*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getSupportedFrameTimestamps(
8577*38e8c45fSAndroid Build Coastguard Worker         std::vector<FrameEvent>* outSupported) {
8578*38e8c45fSAndroid Build Coastguard Worker     status_t status;
8579*38e8c45fSAndroid Build Coastguard Worker     if (!outSupported) {
8580*38e8c45fSAndroid Build Coastguard Worker         status = UNEXPECTED_NULL;
8581*38e8c45fSAndroid Build Coastguard Worker     } else {
8582*38e8c45fSAndroid Build Coastguard Worker         outSupported->clear();
8583*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->getSupportedFrameTimestamps(outSupported);
8584*38e8c45fSAndroid Build Coastguard Worker     }
8585*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8586*38e8c45fSAndroid Build Coastguard Worker }
8587*38e8c45fSAndroid Build Coastguard Worker 
getDisplayStats(const sp<IBinder> & display,gui::DisplayStatInfo * outStatInfo)8588*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getDisplayStats(const sp<IBinder>& display,
8589*38e8c45fSAndroid Build Coastguard Worker                                                     gui::DisplayStatInfo* outStatInfo) {
8590*38e8c45fSAndroid Build Coastguard Worker     DisplayStatInfo statInfo;
8591*38e8c45fSAndroid Build Coastguard Worker     status_t status = mFlinger->getDisplayStats(display, &statInfo);
8592*38e8c45fSAndroid Build Coastguard Worker     if (status == NO_ERROR) {
8593*38e8c45fSAndroid Build Coastguard Worker         outStatInfo->vsyncTime = static_cast<long>(statInfo.vsyncTime);
8594*38e8c45fSAndroid Build Coastguard Worker         outStatInfo->vsyncPeriod = static_cast<long>(statInfo.vsyncPeriod);
8595*38e8c45fSAndroid Build Coastguard Worker     }
8596*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8597*38e8c45fSAndroid Build Coastguard Worker }
8598*38e8c45fSAndroid Build Coastguard Worker 
getDisplayState(const sp<IBinder> & display,gui::DisplayState * outState)8599*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getDisplayState(const sp<IBinder>& display,
8600*38e8c45fSAndroid Build Coastguard Worker                                                     gui::DisplayState* outState) {
8601*38e8c45fSAndroid Build Coastguard Worker     ui::DisplayState state;
8602*38e8c45fSAndroid Build Coastguard Worker     status_t status = mFlinger->getDisplayState(display, &state);
8603*38e8c45fSAndroid Build Coastguard Worker     if (status == NO_ERROR) {
8604*38e8c45fSAndroid Build Coastguard Worker         outState->layerStack = state.layerStack.id;
8605*38e8c45fSAndroid Build Coastguard Worker         outState->orientation = static_cast<gui::Rotation>(state.orientation);
8606*38e8c45fSAndroid Build Coastguard Worker         outState->layerStackSpaceRect.width = state.layerStackSpaceRect.width;
8607*38e8c45fSAndroid Build Coastguard Worker         outState->layerStackSpaceRect.height = state.layerStackSpaceRect.height;
8608*38e8c45fSAndroid Build Coastguard Worker     }
8609*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8610*38e8c45fSAndroid Build Coastguard Worker }
8611*38e8c45fSAndroid Build Coastguard Worker 
getStaticDisplayInfo(int64_t displayId,gui::StaticDisplayInfo * outInfo)8612*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getStaticDisplayInfo(int64_t displayId,
8613*38e8c45fSAndroid Build Coastguard Worker                                                          gui::StaticDisplayInfo* outInfo) {
8614*38e8c45fSAndroid Build Coastguard Worker     using Tag = gui::DeviceProductInfo::ManufactureOrModelDate::Tag;
8615*38e8c45fSAndroid Build Coastguard Worker     ui::StaticDisplayInfo info;
8616*38e8c45fSAndroid Build Coastguard Worker 
8617*38e8c45fSAndroid Build Coastguard Worker     status_t status = mFlinger->getStaticDisplayInfo(displayId, &info);
8618*38e8c45fSAndroid Build Coastguard Worker     if (status == NO_ERROR) {
8619*38e8c45fSAndroid Build Coastguard Worker         // convert ui::StaticDisplayInfo to gui::StaticDisplayInfo
8620*38e8c45fSAndroid Build Coastguard Worker         outInfo->connectionType = static_cast<gui::DisplayConnectionType>(info.connectionType);
8621*38e8c45fSAndroid Build Coastguard Worker         outInfo->density = info.density;
8622*38e8c45fSAndroid Build Coastguard Worker         outInfo->secure = info.secure;
8623*38e8c45fSAndroid Build Coastguard Worker         outInfo->installOrientation = static_cast<gui::Rotation>(info.installOrientation);
8624*38e8c45fSAndroid Build Coastguard Worker 
8625*38e8c45fSAndroid Build Coastguard Worker         if (const std::optional<DeviceProductInfo> dpi = info.deviceProductInfo) {
8626*38e8c45fSAndroid Build Coastguard Worker             gui::DeviceProductInfo dinfo;
8627*38e8c45fSAndroid Build Coastguard Worker             dinfo.name = std::move(dpi->name);
8628*38e8c45fSAndroid Build Coastguard Worker             dinfo.manufacturerPnpId = std::vector<uint8_t>(dpi->manufacturerPnpId.begin(),
8629*38e8c45fSAndroid Build Coastguard Worker                                                            dpi->manufacturerPnpId.end());
8630*38e8c45fSAndroid Build Coastguard Worker             dinfo.productId = dpi->productId;
8631*38e8c45fSAndroid Build Coastguard Worker             dinfo.relativeAddress =
8632*38e8c45fSAndroid Build Coastguard Worker                     std::vector<uint8_t>(dpi->relativeAddress.begin(), dpi->relativeAddress.end());
8633*38e8c45fSAndroid Build Coastguard Worker             if (const auto* model =
8634*38e8c45fSAndroid Build Coastguard Worker                         std::get_if<DeviceProductInfo::ModelYear>(&dpi->manufactureOrModelDate)) {
8635*38e8c45fSAndroid Build Coastguard Worker                 gui::DeviceProductInfo::ModelYear modelYear;
8636*38e8c45fSAndroid Build Coastguard Worker                 modelYear.year = model->year;
8637*38e8c45fSAndroid Build Coastguard Worker                 dinfo.manufactureOrModelDate.set<Tag::modelYear>(modelYear);
8638*38e8c45fSAndroid Build Coastguard Worker             } else if (const auto* manufacture = std::get_if<DeviceProductInfo::ManufactureYear>(
8639*38e8c45fSAndroid Build Coastguard Worker                                &dpi->manufactureOrModelDate)) {
8640*38e8c45fSAndroid Build Coastguard Worker                 gui::DeviceProductInfo::ManufactureYear date;
8641*38e8c45fSAndroid Build Coastguard Worker                 date.modelYear.year = manufacture->year;
8642*38e8c45fSAndroid Build Coastguard Worker                 dinfo.manufactureOrModelDate.set<Tag::manufactureYear>(date);
8643*38e8c45fSAndroid Build Coastguard Worker             } else if (const auto* manufacture =
8644*38e8c45fSAndroid Build Coastguard Worker                                std::get_if<DeviceProductInfo::ManufactureWeekAndYear>(
8645*38e8c45fSAndroid Build Coastguard Worker                                        &dpi->manufactureOrModelDate)) {
8646*38e8c45fSAndroid Build Coastguard Worker                 gui::DeviceProductInfo::ManufactureWeekAndYear date;
8647*38e8c45fSAndroid Build Coastguard Worker                 date.manufactureYear.modelYear.year = manufacture->year;
8648*38e8c45fSAndroid Build Coastguard Worker                 date.week = manufacture->week;
8649*38e8c45fSAndroid Build Coastguard Worker                 dinfo.manufactureOrModelDate.set<Tag::manufactureWeekAndYear>(date);
8650*38e8c45fSAndroid Build Coastguard Worker             }
8651*38e8c45fSAndroid Build Coastguard Worker 
8652*38e8c45fSAndroid Build Coastguard Worker             outInfo->deviceProductInfo = dinfo;
8653*38e8c45fSAndroid Build Coastguard Worker         }
8654*38e8c45fSAndroid Build Coastguard Worker     }
8655*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8656*38e8c45fSAndroid Build Coastguard Worker }
8657*38e8c45fSAndroid Build Coastguard Worker 
getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo & info,gui::DynamicDisplayInfo * & outInfo)8658*38e8c45fSAndroid Build Coastguard Worker void SurfaceComposerAIDL::getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo& info,
8659*38e8c45fSAndroid Build Coastguard Worker                                                         gui::DynamicDisplayInfo*& outInfo) {
8660*38e8c45fSAndroid Build Coastguard Worker     // convert ui::DynamicDisplayInfo to gui::DynamicDisplayInfo
8661*38e8c45fSAndroid Build Coastguard Worker     outInfo->supportedDisplayModes.clear();
8662*38e8c45fSAndroid Build Coastguard Worker     outInfo->supportedDisplayModes.reserve(info.supportedDisplayModes.size());
8663*38e8c45fSAndroid Build Coastguard Worker     for (const auto& mode : info.supportedDisplayModes) {
8664*38e8c45fSAndroid Build Coastguard Worker         gui::DisplayMode outMode;
8665*38e8c45fSAndroid Build Coastguard Worker         outMode.id = mode.id;
8666*38e8c45fSAndroid Build Coastguard Worker         outMode.resolution.width = mode.resolution.width;
8667*38e8c45fSAndroid Build Coastguard Worker         outMode.resolution.height = mode.resolution.height;
8668*38e8c45fSAndroid Build Coastguard Worker         outMode.xDpi = mode.xDpi;
8669*38e8c45fSAndroid Build Coastguard Worker         outMode.yDpi = mode.yDpi;
8670*38e8c45fSAndroid Build Coastguard Worker         outMode.peakRefreshRate = mode.peakRefreshRate;
8671*38e8c45fSAndroid Build Coastguard Worker         outMode.vsyncRate = mode.vsyncRate;
8672*38e8c45fSAndroid Build Coastguard Worker         outMode.appVsyncOffset = mode.appVsyncOffset;
8673*38e8c45fSAndroid Build Coastguard Worker         outMode.sfVsyncOffset = mode.sfVsyncOffset;
8674*38e8c45fSAndroid Build Coastguard Worker         outMode.presentationDeadline = mode.presentationDeadline;
8675*38e8c45fSAndroid Build Coastguard Worker         outMode.group = mode.group;
8676*38e8c45fSAndroid Build Coastguard Worker         std::transform(mode.supportedHdrTypes.begin(), mode.supportedHdrTypes.end(),
8677*38e8c45fSAndroid Build Coastguard Worker                        std::back_inserter(outMode.supportedHdrTypes),
8678*38e8c45fSAndroid Build Coastguard Worker                        [](const ui::Hdr& value) { return static_cast<int32_t>(value); });
8679*38e8c45fSAndroid Build Coastguard Worker         outInfo->supportedDisplayModes.push_back(outMode);
8680*38e8c45fSAndroid Build Coastguard Worker     }
8681*38e8c45fSAndroid Build Coastguard Worker 
8682*38e8c45fSAndroid Build Coastguard Worker     outInfo->activeDisplayModeId = info.activeDisplayModeId;
8683*38e8c45fSAndroid Build Coastguard Worker     outInfo->renderFrameRate = info.renderFrameRate;
8684*38e8c45fSAndroid Build Coastguard Worker     outInfo->hasArrSupport = info.hasArrSupport;
8685*38e8c45fSAndroid Build Coastguard Worker     gui::FrameRateCategoryRate& frameRateCategoryRate = outInfo->frameRateCategoryRate;
8686*38e8c45fSAndroid Build Coastguard Worker     frameRateCategoryRate.normal = info.frameRateCategoryRate.getNormal();
8687*38e8c45fSAndroid Build Coastguard Worker     frameRateCategoryRate.high = info.frameRateCategoryRate.getHigh();
8688*38e8c45fSAndroid Build Coastguard Worker     outInfo->supportedRefreshRates.clear();
8689*38e8c45fSAndroid Build Coastguard Worker     outInfo->supportedRefreshRates.reserve(info.supportedRefreshRates.size());
8690*38e8c45fSAndroid Build Coastguard Worker     for (float supportedRefreshRate : info.supportedRefreshRates) {
8691*38e8c45fSAndroid Build Coastguard Worker         outInfo->supportedRefreshRates.push_back(supportedRefreshRate);
8692*38e8c45fSAndroid Build Coastguard Worker     }
8693*38e8c45fSAndroid Build Coastguard Worker 
8694*38e8c45fSAndroid Build Coastguard Worker     outInfo->supportedColorModes.clear();
8695*38e8c45fSAndroid Build Coastguard Worker     outInfo->supportedColorModes.reserve(info.supportedColorModes.size());
8696*38e8c45fSAndroid Build Coastguard Worker     for (const auto& cmode : info.supportedColorModes) {
8697*38e8c45fSAndroid Build Coastguard Worker         outInfo->supportedColorModes.push_back(static_cast<int32_t>(cmode));
8698*38e8c45fSAndroid Build Coastguard Worker     }
8699*38e8c45fSAndroid Build Coastguard Worker 
8700*38e8c45fSAndroid Build Coastguard Worker     outInfo->activeColorMode = static_cast<int32_t>(info.activeColorMode);
8701*38e8c45fSAndroid Build Coastguard Worker 
8702*38e8c45fSAndroid Build Coastguard Worker     gui::HdrCapabilities& hdrCapabilities = outInfo->hdrCapabilities;
8703*38e8c45fSAndroid Build Coastguard Worker     hdrCapabilities.supportedHdrTypes.clear();
8704*38e8c45fSAndroid Build Coastguard Worker     hdrCapabilities.supportedHdrTypes.reserve(info.hdrCapabilities.getSupportedHdrTypes().size());
8705*38e8c45fSAndroid Build Coastguard Worker     for (const auto& hdr : info.hdrCapabilities.getSupportedHdrTypes()) {
8706*38e8c45fSAndroid Build Coastguard Worker         hdrCapabilities.supportedHdrTypes.push_back(static_cast<int32_t>(hdr));
8707*38e8c45fSAndroid Build Coastguard Worker     }
8708*38e8c45fSAndroid Build Coastguard Worker     hdrCapabilities.maxLuminance = info.hdrCapabilities.getDesiredMaxLuminance();
8709*38e8c45fSAndroid Build Coastguard Worker     hdrCapabilities.maxAverageLuminance = info.hdrCapabilities.getDesiredMaxAverageLuminance();
8710*38e8c45fSAndroid Build Coastguard Worker     hdrCapabilities.minLuminance = info.hdrCapabilities.getDesiredMinLuminance();
8711*38e8c45fSAndroid Build Coastguard Worker 
8712*38e8c45fSAndroid Build Coastguard Worker     outInfo->autoLowLatencyModeSupported = info.autoLowLatencyModeSupported;
8713*38e8c45fSAndroid Build Coastguard Worker     outInfo->gameContentTypeSupported = info.gameContentTypeSupported;
8714*38e8c45fSAndroid Build Coastguard Worker     outInfo->preferredBootDisplayMode = info.preferredBootDisplayMode;
8715*38e8c45fSAndroid Build Coastguard Worker }
8716*38e8c45fSAndroid Build Coastguard Worker 
getDynamicDisplayInfoFromToken(const sp<IBinder> & display,gui::DynamicDisplayInfo * outInfo)8717*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getDynamicDisplayInfoFromToken(
8718*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& display, gui::DynamicDisplayInfo* outInfo) {
8719*38e8c45fSAndroid Build Coastguard Worker     ui::DynamicDisplayInfo info;
8720*38e8c45fSAndroid Build Coastguard Worker     status_t status = mFlinger->getDynamicDisplayInfoFromToken(display, &info);
8721*38e8c45fSAndroid Build Coastguard Worker     if (status == NO_ERROR) {
8722*38e8c45fSAndroid Build Coastguard Worker         getDynamicDisplayInfoInternal(info, outInfo);
8723*38e8c45fSAndroid Build Coastguard Worker     }
8724*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8725*38e8c45fSAndroid Build Coastguard Worker }
8726*38e8c45fSAndroid Build Coastguard Worker 
getDynamicDisplayInfoFromId(int64_t displayId,gui::DynamicDisplayInfo * outInfo)8727*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getDynamicDisplayInfoFromId(int64_t displayId,
8728*38e8c45fSAndroid Build Coastguard Worker                                                                 gui::DynamicDisplayInfo* outInfo) {
8729*38e8c45fSAndroid Build Coastguard Worker     ui::DynamicDisplayInfo info;
8730*38e8c45fSAndroid Build Coastguard Worker     status_t status = mFlinger->getDynamicDisplayInfoFromId(displayId, &info);
8731*38e8c45fSAndroid Build Coastguard Worker     if (status == NO_ERROR) {
8732*38e8c45fSAndroid Build Coastguard Worker         getDynamicDisplayInfoInternal(info, outInfo);
8733*38e8c45fSAndroid Build Coastguard Worker     }
8734*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8735*38e8c45fSAndroid Build Coastguard Worker }
8736*38e8c45fSAndroid Build Coastguard Worker 
getDisplayNativePrimaries(const sp<IBinder> & display,gui::DisplayPrimaries * outPrimaries)8737*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getDisplayNativePrimaries(const sp<IBinder>& display,
8738*38e8c45fSAndroid Build Coastguard Worker                                                               gui::DisplayPrimaries* outPrimaries) {
8739*38e8c45fSAndroid Build Coastguard Worker     ui::DisplayPrimaries primaries;
8740*38e8c45fSAndroid Build Coastguard Worker     status_t status = mFlinger->getDisplayNativePrimaries(display, primaries);
8741*38e8c45fSAndroid Build Coastguard Worker     if (status == NO_ERROR) {
8742*38e8c45fSAndroid Build Coastguard Worker         outPrimaries->red.X = primaries.red.X;
8743*38e8c45fSAndroid Build Coastguard Worker         outPrimaries->red.Y = primaries.red.Y;
8744*38e8c45fSAndroid Build Coastguard Worker         outPrimaries->red.Z = primaries.red.Z;
8745*38e8c45fSAndroid Build Coastguard Worker 
8746*38e8c45fSAndroid Build Coastguard Worker         outPrimaries->green.X = primaries.green.X;
8747*38e8c45fSAndroid Build Coastguard Worker         outPrimaries->green.Y = primaries.green.Y;
8748*38e8c45fSAndroid Build Coastguard Worker         outPrimaries->green.Z = primaries.green.Z;
8749*38e8c45fSAndroid Build Coastguard Worker 
8750*38e8c45fSAndroid Build Coastguard Worker         outPrimaries->blue.X = primaries.blue.X;
8751*38e8c45fSAndroid Build Coastguard Worker         outPrimaries->blue.Y = primaries.blue.Y;
8752*38e8c45fSAndroid Build Coastguard Worker         outPrimaries->blue.Z = primaries.blue.Z;
8753*38e8c45fSAndroid Build Coastguard Worker 
8754*38e8c45fSAndroid Build Coastguard Worker         outPrimaries->white.X = primaries.white.X;
8755*38e8c45fSAndroid Build Coastguard Worker         outPrimaries->white.Y = primaries.white.Y;
8756*38e8c45fSAndroid Build Coastguard Worker         outPrimaries->white.Z = primaries.white.Z;
8757*38e8c45fSAndroid Build Coastguard Worker     }
8758*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8759*38e8c45fSAndroid Build Coastguard Worker }
8760*38e8c45fSAndroid Build Coastguard Worker 
setActiveColorMode(const sp<IBinder> & display,int colorMode)8761*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setActiveColorMode(const sp<IBinder>& display, int colorMode) {
8762*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8763*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
8764*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->setActiveColorMode(display, static_cast<ui::ColorMode>(colorMode));
8765*38e8c45fSAndroid Build Coastguard Worker     }
8766*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8767*38e8c45fSAndroid Build Coastguard Worker }
8768*38e8c45fSAndroid Build Coastguard Worker 
setBootDisplayMode(const sp<IBinder> & display,int displayModeId)8769*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setBootDisplayMode(const sp<IBinder>& display,
8770*38e8c45fSAndroid Build Coastguard Worker                                                        int displayModeId) {
8771*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8772*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
8773*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->setBootDisplayMode(display, DisplayModeId{displayModeId});
8774*38e8c45fSAndroid Build Coastguard Worker     }
8775*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8776*38e8c45fSAndroid Build Coastguard Worker }
8777*38e8c45fSAndroid Build Coastguard Worker 
clearBootDisplayMode(const sp<IBinder> & display)8778*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::clearBootDisplayMode(const sp<IBinder>& display) {
8779*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8780*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
8781*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->clearBootDisplayMode(display);
8782*38e8c45fSAndroid Build Coastguard Worker     }
8783*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8784*38e8c45fSAndroid Build Coastguard Worker }
8785*38e8c45fSAndroid Build Coastguard Worker 
getOverlaySupport(gui::OverlayProperties * outProperties)8786*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getOverlaySupport(gui::OverlayProperties* outProperties) {
8787*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8788*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
8789*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->getOverlaySupport(outProperties);
8790*38e8c45fSAndroid Build Coastguard Worker     }
8791*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8792*38e8c45fSAndroid Build Coastguard Worker }
8793*38e8c45fSAndroid Build Coastguard Worker 
getBootDisplayModeSupport(bool * outMode)8794*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getBootDisplayModeSupport(bool* outMode) {
8795*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8796*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
8797*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->getBootDisplayModeSupport(outMode);
8798*38e8c45fSAndroid Build Coastguard Worker     }
8799*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8800*38e8c45fSAndroid Build Coastguard Worker }
8801*38e8c45fSAndroid Build Coastguard Worker 
getHdrConversionCapabilities(std::vector<gui::HdrConversionCapability> * hdrConversionCapabilities)8802*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getHdrConversionCapabilities(
8803*38e8c45fSAndroid Build Coastguard Worker         std::vector<gui::HdrConversionCapability>* hdrConversionCapabilities) {
8804*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8805*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
8806*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->getHdrConversionCapabilities(hdrConversionCapabilities);
8807*38e8c45fSAndroid Build Coastguard Worker     }
8808*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8809*38e8c45fSAndroid Build Coastguard Worker }
8810*38e8c45fSAndroid Build Coastguard Worker 
setHdrConversionStrategy(const gui::HdrConversionStrategy & hdrConversionStrategy,int32_t * outPreferredHdrOutputType)8811*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setHdrConversionStrategy(
8812*38e8c45fSAndroid Build Coastguard Worker         const gui::HdrConversionStrategy& hdrConversionStrategy,
8813*38e8c45fSAndroid Build Coastguard Worker         int32_t* outPreferredHdrOutputType) {
8814*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8815*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
8816*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->setHdrConversionStrategy(hdrConversionStrategy,
8817*38e8c45fSAndroid Build Coastguard Worker                                                     outPreferredHdrOutputType);
8818*38e8c45fSAndroid Build Coastguard Worker     }
8819*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8820*38e8c45fSAndroid Build Coastguard Worker }
8821*38e8c45fSAndroid Build Coastguard Worker 
getHdrOutputConversionSupport(bool * outMode)8822*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getHdrOutputConversionSupport(bool* outMode) {
8823*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8824*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
8825*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->getHdrOutputConversionSupport(outMode);
8826*38e8c45fSAndroid Build Coastguard Worker     }
8827*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8828*38e8c45fSAndroid Build Coastguard Worker }
8829*38e8c45fSAndroid Build Coastguard Worker 
setAutoLowLatencyMode(const sp<IBinder> & display,bool on)8830*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setAutoLowLatencyMode(const sp<IBinder>& display, bool on) {
8831*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8832*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
8833*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
8834*38e8c45fSAndroid Build Coastguard Worker     }
8835*38e8c45fSAndroid Build Coastguard Worker     mFlinger->setAutoLowLatencyMode(display, on);
8836*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
8837*38e8c45fSAndroid Build Coastguard Worker }
8838*38e8c45fSAndroid Build Coastguard Worker 
setGameContentType(const sp<IBinder> & display,bool on)8839*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setGameContentType(const sp<IBinder>& display, bool on) {
8840*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8841*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
8842*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
8843*38e8c45fSAndroid Build Coastguard Worker     }
8844*38e8c45fSAndroid Build Coastguard Worker     mFlinger->setGameContentType(display, on);
8845*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
8846*38e8c45fSAndroid Build Coastguard Worker }
8847*38e8c45fSAndroid Build Coastguard Worker 
getMaxLayerPictureProfiles(const sp<IBinder> & display,int32_t * outMaxProfiles)8848*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getMaxLayerPictureProfiles(const sp<IBinder>& display,
8849*38e8c45fSAndroid Build Coastguard Worker                                                                int32_t* outMaxProfiles) {
8850*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8851*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
8852*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
8853*38e8c45fSAndroid Build Coastguard Worker     }
8854*38e8c45fSAndroid Build Coastguard Worker     mFlinger->getMaxLayerPictureProfiles(display, outMaxProfiles);
8855*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
8856*38e8c45fSAndroid Build Coastguard Worker }
8857*38e8c45fSAndroid Build Coastguard Worker 
captureDisplay(const DisplayCaptureArgs & args,const sp<IScreenCaptureListener> & captureListener)8858*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::captureDisplay(
8859*38e8c45fSAndroid Build Coastguard Worker         const DisplayCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) {
8860*38e8c45fSAndroid Build Coastguard Worker     mFlinger->captureDisplay(args, captureListener);
8861*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(NO_ERROR);
8862*38e8c45fSAndroid Build Coastguard Worker }
8863*38e8c45fSAndroid Build Coastguard Worker 
captureDisplayById(int64_t displayId,const CaptureArgs & args,const sp<IScreenCaptureListener> & captureListener)8864*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::captureDisplayById(
8865*38e8c45fSAndroid Build Coastguard Worker         int64_t displayId, const CaptureArgs& args,
8866*38e8c45fSAndroid Build Coastguard Worker         const sp<IScreenCaptureListener>& captureListener) {
8867*38e8c45fSAndroid Build Coastguard Worker     // status_t status;
8868*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
8869*38e8c45fSAndroid Build Coastguard Worker     const int uid = ipc->getCallingUid();
8870*38e8c45fSAndroid Build Coastguard Worker     if (uid == AID_ROOT || uid == AID_GRAPHICS || uid == AID_SYSTEM || uid == AID_SHELL) {
8871*38e8c45fSAndroid Build Coastguard Worker         std::optional<DisplayId> id = DisplayId::fromValue(static_cast<uint64_t>(displayId));
8872*38e8c45fSAndroid Build Coastguard Worker         mFlinger->captureDisplay(*id, args, captureListener);
8873*38e8c45fSAndroid Build Coastguard Worker     } else {
8874*38e8c45fSAndroid Build Coastguard Worker         ALOGD("Permission denied to captureDisplayById");
8875*38e8c45fSAndroid Build Coastguard Worker         invokeScreenCaptureError(PERMISSION_DENIED, captureListener);
8876*38e8c45fSAndroid Build Coastguard Worker     }
8877*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(NO_ERROR);
8878*38e8c45fSAndroid Build Coastguard Worker }
8879*38e8c45fSAndroid Build Coastguard Worker 
captureLayersSync(const LayerCaptureArgs & args,ScreenCaptureResults * outResults)8880*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::captureLayersSync(const LayerCaptureArgs& args,
8881*38e8c45fSAndroid Build Coastguard Worker                                                       ScreenCaptureResults* outResults) {
8882*38e8c45fSAndroid Build Coastguard Worker     *outResults = mFlinger->captureLayersSync(args);
8883*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(NO_ERROR);
8884*38e8c45fSAndroid Build Coastguard Worker }
8885*38e8c45fSAndroid Build Coastguard Worker 
captureLayers(const LayerCaptureArgs & args,const sp<IScreenCaptureListener> & captureListener)8886*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::captureLayers(
8887*38e8c45fSAndroid Build Coastguard Worker         const LayerCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) {
8888*38e8c45fSAndroid Build Coastguard Worker     mFlinger->captureLayers(args, captureListener);
8889*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(NO_ERROR);
8890*38e8c45fSAndroid Build Coastguard Worker }
8891*38e8c45fSAndroid Build Coastguard Worker 
overrideHdrTypes(const sp<IBinder> & display,const std::vector<int32_t> & hdrTypes)8892*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::overrideHdrTypes(const sp<IBinder>& display,
8893*38e8c45fSAndroid Build Coastguard Worker                                                      const std::vector<int32_t>& hdrTypes) {
8894*38e8c45fSAndroid Build Coastguard Worker     // overrideHdrTypes is used by CTS tests, which acquire the necessary
8895*38e8c45fSAndroid Build Coastguard Worker     // permission dynamically. Don't use the permission cache for this check.
8896*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission(false);
8897*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
8898*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
8899*38e8c45fSAndroid Build Coastguard Worker     }
8900*38e8c45fSAndroid Build Coastguard Worker 
8901*38e8c45fSAndroid Build Coastguard Worker     std::vector<ui::Hdr> hdrTypesVector;
8902*38e8c45fSAndroid Build Coastguard Worker     for (int32_t i : hdrTypes) {
8903*38e8c45fSAndroid Build Coastguard Worker         hdrTypesVector.push_back(static_cast<ui::Hdr>(i));
8904*38e8c45fSAndroid Build Coastguard Worker     }
8905*38e8c45fSAndroid Build Coastguard Worker     status = mFlinger->overrideHdrTypes(display, hdrTypesVector);
8906*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8907*38e8c45fSAndroid Build Coastguard Worker }
8908*38e8c45fSAndroid Build Coastguard Worker 
onPullAtom(int32_t atomId,gui::PullAtomData * outPullData)8909*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::onPullAtom(int32_t atomId, gui::PullAtomData* outPullData) {
8910*38e8c45fSAndroid Build Coastguard Worker     status_t status;
8911*38e8c45fSAndroid Build Coastguard Worker     const int uid = IPCThreadState::self()->getCallingUid();
8912*38e8c45fSAndroid Build Coastguard Worker     if (uid != AID_SYSTEM) {
8913*38e8c45fSAndroid Build Coastguard Worker         status = PERMISSION_DENIED;
8914*38e8c45fSAndroid Build Coastguard Worker     } else {
8915*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->onPullAtom(atomId, &outPullData->data, &outPullData->success);
8916*38e8c45fSAndroid Build Coastguard Worker     }
8917*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8918*38e8c45fSAndroid Build Coastguard Worker }
8919*38e8c45fSAndroid Build Coastguard Worker 
getCompositionPreference(gui::CompositionPreference * outPref)8920*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getCompositionPreference(gui::CompositionPreference* outPref) {
8921*38e8c45fSAndroid Build Coastguard Worker     ui::Dataspace dataspace;
8922*38e8c45fSAndroid Build Coastguard Worker     ui::PixelFormat pixelFormat;
8923*38e8c45fSAndroid Build Coastguard Worker     ui::Dataspace wideColorGamutDataspace;
8924*38e8c45fSAndroid Build Coastguard Worker     ui::PixelFormat wideColorGamutPixelFormat;
8925*38e8c45fSAndroid Build Coastguard Worker     status_t status =
8926*38e8c45fSAndroid Build Coastguard Worker             mFlinger->getCompositionPreference(&dataspace, &pixelFormat, &wideColorGamutDataspace,
8927*38e8c45fSAndroid Build Coastguard Worker                                                &wideColorGamutPixelFormat);
8928*38e8c45fSAndroid Build Coastguard Worker     if (status == NO_ERROR) {
8929*38e8c45fSAndroid Build Coastguard Worker         outPref->defaultDataspace = static_cast<int32_t>(dataspace);
8930*38e8c45fSAndroid Build Coastguard Worker         outPref->defaultPixelFormat = static_cast<int32_t>(pixelFormat);
8931*38e8c45fSAndroid Build Coastguard Worker         outPref->wideColorGamutDataspace = static_cast<int32_t>(wideColorGamutDataspace);
8932*38e8c45fSAndroid Build Coastguard Worker         outPref->wideColorGamutPixelFormat = static_cast<int32_t>(wideColorGamutPixelFormat);
8933*38e8c45fSAndroid Build Coastguard Worker     }
8934*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8935*38e8c45fSAndroid Build Coastguard Worker }
8936*38e8c45fSAndroid Build Coastguard Worker 
getDisplayedContentSamplingAttributes(const sp<IBinder> & display,gui::ContentSamplingAttributes * outAttrs)8937*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getDisplayedContentSamplingAttributes(
8938*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& display, gui::ContentSamplingAttributes* outAttrs) {
8939*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8940*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
8941*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
8942*38e8c45fSAndroid Build Coastguard Worker     }
8943*38e8c45fSAndroid Build Coastguard Worker 
8944*38e8c45fSAndroid Build Coastguard Worker     ui::PixelFormat format;
8945*38e8c45fSAndroid Build Coastguard Worker     ui::Dataspace dataspace;
8946*38e8c45fSAndroid Build Coastguard Worker     uint8_t componentMask;
8947*38e8c45fSAndroid Build Coastguard Worker     status = mFlinger->getDisplayedContentSamplingAttributes(display, &format, &dataspace,
8948*38e8c45fSAndroid Build Coastguard Worker                                                              &componentMask);
8949*38e8c45fSAndroid Build Coastguard Worker     if (status == NO_ERROR) {
8950*38e8c45fSAndroid Build Coastguard Worker         outAttrs->format = static_cast<int32_t>(format);
8951*38e8c45fSAndroid Build Coastguard Worker         outAttrs->dataspace = static_cast<int32_t>(dataspace);
8952*38e8c45fSAndroid Build Coastguard Worker         outAttrs->componentMask = static_cast<int8_t>(componentMask);
8953*38e8c45fSAndroid Build Coastguard Worker     }
8954*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8955*38e8c45fSAndroid Build Coastguard Worker }
8956*38e8c45fSAndroid Build Coastguard Worker 
setDisplayContentSamplingEnabled(const sp<IBinder> & display,bool enable,int8_t componentMask,int64_t maxFrames)8957*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setDisplayContentSamplingEnabled(const sp<IBinder>& display,
8958*38e8c45fSAndroid Build Coastguard Worker                                                                      bool enable,
8959*38e8c45fSAndroid Build Coastguard Worker                                                                      int8_t componentMask,
8960*38e8c45fSAndroid Build Coastguard Worker                                                                      int64_t maxFrames) {
8961*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8962*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
8963*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->setDisplayContentSamplingEnabled(display, enable,
8964*38e8c45fSAndroid Build Coastguard Worker                                                             static_cast<uint8_t>(componentMask),
8965*38e8c45fSAndroid Build Coastguard Worker                                                             static_cast<uint64_t>(maxFrames));
8966*38e8c45fSAndroid Build Coastguard Worker     }
8967*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
8968*38e8c45fSAndroid Build Coastguard Worker }
8969*38e8c45fSAndroid Build Coastguard Worker 
getDisplayedContentSample(const sp<IBinder> & display,int64_t maxFrames,int64_t timestamp,gui::DisplayedFrameStats * outStats)8970*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getDisplayedContentSample(const sp<IBinder>& display,
8971*38e8c45fSAndroid Build Coastguard Worker                                                               int64_t maxFrames, int64_t timestamp,
8972*38e8c45fSAndroid Build Coastguard Worker                                                               gui::DisplayedFrameStats* outStats) {
8973*38e8c45fSAndroid Build Coastguard Worker     if (!outStats) {
8974*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(BAD_VALUE);
8975*38e8c45fSAndroid Build Coastguard Worker     }
8976*38e8c45fSAndroid Build Coastguard Worker 
8977*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
8978*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
8979*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
8980*38e8c45fSAndroid Build Coastguard Worker     }
8981*38e8c45fSAndroid Build Coastguard Worker 
8982*38e8c45fSAndroid Build Coastguard Worker     DisplayedFrameStats stats;
8983*38e8c45fSAndroid Build Coastguard Worker     status = mFlinger->getDisplayedContentSample(display, static_cast<uint64_t>(maxFrames),
8984*38e8c45fSAndroid Build Coastguard Worker                                                  static_cast<uint64_t>(timestamp), &stats);
8985*38e8c45fSAndroid Build Coastguard Worker     if (status == NO_ERROR) {
8986*38e8c45fSAndroid Build Coastguard Worker         // convert from ui::DisplayedFrameStats to gui::DisplayedFrameStats
8987*38e8c45fSAndroid Build Coastguard Worker         outStats->numFrames = static_cast<int64_t>(stats.numFrames);
8988*38e8c45fSAndroid Build Coastguard Worker         outStats->component_0_sample.reserve(stats.component_0_sample.size());
8989*38e8c45fSAndroid Build Coastguard Worker         for (const auto& s : stats.component_0_sample) {
8990*38e8c45fSAndroid Build Coastguard Worker             outStats->component_0_sample.push_back(static_cast<int64_t>(s));
8991*38e8c45fSAndroid Build Coastguard Worker         }
8992*38e8c45fSAndroid Build Coastguard Worker         outStats->component_1_sample.reserve(stats.component_1_sample.size());
8993*38e8c45fSAndroid Build Coastguard Worker         for (const auto& s : stats.component_1_sample) {
8994*38e8c45fSAndroid Build Coastguard Worker             outStats->component_1_sample.push_back(static_cast<int64_t>(s));
8995*38e8c45fSAndroid Build Coastguard Worker         }
8996*38e8c45fSAndroid Build Coastguard Worker         outStats->component_2_sample.reserve(stats.component_2_sample.size());
8997*38e8c45fSAndroid Build Coastguard Worker         for (const auto& s : stats.component_2_sample) {
8998*38e8c45fSAndroid Build Coastguard Worker             outStats->component_2_sample.push_back(static_cast<int64_t>(s));
8999*38e8c45fSAndroid Build Coastguard Worker         }
9000*38e8c45fSAndroid Build Coastguard Worker         outStats->component_3_sample.reserve(stats.component_3_sample.size());
9001*38e8c45fSAndroid Build Coastguard Worker         for (const auto& s : stats.component_3_sample) {
9002*38e8c45fSAndroid Build Coastguard Worker             outStats->component_3_sample.push_back(static_cast<int64_t>(s));
9003*38e8c45fSAndroid Build Coastguard Worker         }
9004*38e8c45fSAndroid Build Coastguard Worker     }
9005*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9006*38e8c45fSAndroid Build Coastguard Worker }
9007*38e8c45fSAndroid Build Coastguard Worker 
getProtectedContentSupport(bool * outSupported)9008*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getProtectedContentSupport(bool* outSupported) {
9009*38e8c45fSAndroid Build Coastguard Worker     status_t status = mFlinger->getProtectedContentSupport(outSupported);
9010*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9011*38e8c45fSAndroid Build Coastguard Worker }
9012*38e8c45fSAndroid Build Coastguard Worker 
isWideColorDisplay(const sp<IBinder> & token,bool * outIsWideColorDisplay)9013*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::isWideColorDisplay(const sp<IBinder>& token,
9014*38e8c45fSAndroid Build Coastguard Worker                                                        bool* outIsWideColorDisplay) {
9015*38e8c45fSAndroid Build Coastguard Worker     status_t status = mFlinger->isWideColorDisplay(token, outIsWideColorDisplay);
9016*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9017*38e8c45fSAndroid Build Coastguard Worker }
9018*38e8c45fSAndroid Build Coastguard Worker 
addRegionSamplingListener(const gui::ARect & samplingArea,const sp<IBinder> & stopLayerHandle,const sp<gui::IRegionSamplingListener> & listener)9019*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::addRegionSamplingListener(
9020*38e8c45fSAndroid Build Coastguard Worker         const gui::ARect& samplingArea, const sp<IBinder>& stopLayerHandle,
9021*38e8c45fSAndroid Build Coastguard Worker         const sp<gui::IRegionSamplingListener>& listener) {
9022*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkReadFrameBufferPermission();
9023*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
9024*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
9025*38e8c45fSAndroid Build Coastguard Worker     }
9026*38e8c45fSAndroid Build Coastguard Worker     android::Rect rect;
9027*38e8c45fSAndroid Build Coastguard Worker     rect.left = samplingArea.left;
9028*38e8c45fSAndroid Build Coastguard Worker     rect.top = samplingArea.top;
9029*38e8c45fSAndroid Build Coastguard Worker     rect.right = samplingArea.right;
9030*38e8c45fSAndroid Build Coastguard Worker     rect.bottom = samplingArea.bottom;
9031*38e8c45fSAndroid Build Coastguard Worker     status = mFlinger->addRegionSamplingListener(rect, stopLayerHandle, listener);
9032*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9033*38e8c45fSAndroid Build Coastguard Worker }
9034*38e8c45fSAndroid Build Coastguard Worker 
removeRegionSamplingListener(const sp<gui::IRegionSamplingListener> & listener)9035*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::removeRegionSamplingListener(
9036*38e8c45fSAndroid Build Coastguard Worker         const sp<gui::IRegionSamplingListener>& listener) {
9037*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkReadFrameBufferPermission();
9038*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
9039*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->removeRegionSamplingListener(listener);
9040*38e8c45fSAndroid Build Coastguard Worker     }
9041*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9042*38e8c45fSAndroid Build Coastguard Worker }
9043*38e8c45fSAndroid Build Coastguard Worker 
addFpsListener(int32_t taskId,const sp<gui::IFpsListener> & listener)9044*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::addFpsListener(int32_t taskId,
9045*38e8c45fSAndroid Build Coastguard Worker                                                    const sp<gui::IFpsListener>& listener) {
9046*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkReadFrameBufferPermission();
9047*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
9048*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->addFpsListener(taskId, listener);
9049*38e8c45fSAndroid Build Coastguard Worker     }
9050*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9051*38e8c45fSAndroid Build Coastguard Worker }
9052*38e8c45fSAndroid Build Coastguard Worker 
removeFpsListener(const sp<gui::IFpsListener> & listener)9053*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::removeFpsListener(const sp<gui::IFpsListener>& listener) {
9054*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkReadFrameBufferPermission();
9055*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
9056*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->removeFpsListener(listener);
9057*38e8c45fSAndroid Build Coastguard Worker     }
9058*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9059*38e8c45fSAndroid Build Coastguard Worker }
9060*38e8c45fSAndroid Build Coastguard Worker 
addTunnelModeEnabledListener(const sp<gui::ITunnelModeEnabledListener> & listener)9061*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::addTunnelModeEnabledListener(
9062*38e8c45fSAndroid Build Coastguard Worker         const sp<gui::ITunnelModeEnabledListener>& listener) {
9063*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
9064*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
9065*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->addTunnelModeEnabledListener(listener);
9066*38e8c45fSAndroid Build Coastguard Worker     }
9067*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9068*38e8c45fSAndroid Build Coastguard Worker }
9069*38e8c45fSAndroid Build Coastguard Worker 
removeTunnelModeEnabledListener(const sp<gui::ITunnelModeEnabledListener> & listener)9070*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::removeTunnelModeEnabledListener(
9071*38e8c45fSAndroid Build Coastguard Worker         const sp<gui::ITunnelModeEnabledListener>& listener) {
9072*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
9073*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
9074*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->removeTunnelModeEnabledListener(listener);
9075*38e8c45fSAndroid Build Coastguard Worker     }
9076*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9077*38e8c45fSAndroid Build Coastguard Worker }
9078*38e8c45fSAndroid Build Coastguard Worker 
setDesiredDisplayModeSpecs(const sp<IBinder> & displayToken,const gui::DisplayModeSpecs & specs)9079*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
9080*38e8c45fSAndroid Build Coastguard Worker                                                                const gui::DisplayModeSpecs& specs) {
9081*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
9082*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
9083*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->setDesiredDisplayModeSpecs(displayToken, specs);
9084*38e8c45fSAndroid Build Coastguard Worker     }
9085*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9086*38e8c45fSAndroid Build Coastguard Worker }
9087*38e8c45fSAndroid Build Coastguard Worker 
getDesiredDisplayModeSpecs(const sp<IBinder> & displayToken,gui::DisplayModeSpecs * outSpecs)9088*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
9089*38e8c45fSAndroid Build Coastguard Worker                                                                gui::DisplayModeSpecs* outSpecs) {
9090*38e8c45fSAndroid Build Coastguard Worker     if (!outSpecs) {
9091*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(BAD_VALUE);
9092*38e8c45fSAndroid Build Coastguard Worker     }
9093*38e8c45fSAndroid Build Coastguard Worker 
9094*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
9095*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
9096*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
9097*38e8c45fSAndroid Build Coastguard Worker     }
9098*38e8c45fSAndroid Build Coastguard Worker 
9099*38e8c45fSAndroid Build Coastguard Worker     status = mFlinger->getDesiredDisplayModeSpecs(displayToken, outSpecs);
9100*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9101*38e8c45fSAndroid Build Coastguard Worker }
9102*38e8c45fSAndroid Build Coastguard Worker 
getDisplayBrightnessSupport(const sp<IBinder> & displayToken,bool * outSupport)9103*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getDisplayBrightnessSupport(const sp<IBinder>& displayToken,
9104*38e8c45fSAndroid Build Coastguard Worker                                                                 bool* outSupport) {
9105*38e8c45fSAndroid Build Coastguard Worker     status_t status = mFlinger->getDisplayBrightnessSupport(displayToken, outSupport);
9106*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9107*38e8c45fSAndroid Build Coastguard Worker }
9108*38e8c45fSAndroid Build Coastguard Worker 
setDisplayBrightness(const sp<IBinder> & displayToken,const gui::DisplayBrightness & brightness)9109*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setDisplayBrightness(const sp<IBinder>& displayToken,
9110*38e8c45fSAndroid Build Coastguard Worker                                                          const gui::DisplayBrightness& brightness) {
9111*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkControlDisplayBrightnessPermission();
9112*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
9113*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->setDisplayBrightness(displayToken, brightness);
9114*38e8c45fSAndroid Build Coastguard Worker     }
9115*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9116*38e8c45fSAndroid Build Coastguard Worker }
9117*38e8c45fSAndroid Build Coastguard Worker 
addHdrLayerInfoListener(const sp<IBinder> & displayToken,const sp<gui::IHdrLayerInfoListener> & listener)9118*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::addHdrLayerInfoListener(
9119*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener) {
9120*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkControlDisplayBrightnessPermission();
9121*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
9122*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->addHdrLayerInfoListener(displayToken, listener);
9123*38e8c45fSAndroid Build Coastguard Worker     }
9124*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9125*38e8c45fSAndroid Build Coastguard Worker }
9126*38e8c45fSAndroid Build Coastguard Worker 
removeHdrLayerInfoListener(const sp<IBinder> & displayToken,const sp<gui::IHdrLayerInfoListener> & listener)9127*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::removeHdrLayerInfoListener(
9128*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener) {
9129*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkControlDisplayBrightnessPermission();
9130*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
9131*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->removeHdrLayerInfoListener(displayToken, listener);
9132*38e8c45fSAndroid Build Coastguard Worker     }
9133*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9134*38e8c45fSAndroid Build Coastguard Worker }
9135*38e8c45fSAndroid Build Coastguard Worker 
setActivePictureListener(const sp<gui::IActivePictureListener> & listener)9136*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setActivePictureListener(
9137*38e8c45fSAndroid Build Coastguard Worker         const sp<gui::IActivePictureListener>& listener) {
9138*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkObservePictureProfilesPermission();
9139*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
9140*38e8c45fSAndroid Build Coastguard Worker         mFlinger->setActivePictureListener(listener);
9141*38e8c45fSAndroid Build Coastguard Worker     }
9142*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9143*38e8c45fSAndroid Build Coastguard Worker }
9144*38e8c45fSAndroid Build Coastguard Worker 
notifyPowerBoost(int boostId)9145*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::notifyPowerBoost(int boostId) {
9146*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
9147*38e8c45fSAndroid Build Coastguard Worker     if (status == OK) {
9148*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->notifyPowerBoost(boostId);
9149*38e8c45fSAndroid Build Coastguard Worker     }
9150*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9151*38e8c45fSAndroid Build Coastguard Worker }
9152*38e8c45fSAndroid Build Coastguard Worker 
setGlobalShadowSettings(const gui::Color & ambientColor,const gui::Color & spotColor,float lightPosY,float lightPosZ,float lightRadius)9153*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setGlobalShadowSettings(const gui::Color& ambientColor,
9154*38e8c45fSAndroid Build Coastguard Worker                                                             const gui::Color& spotColor,
9155*38e8c45fSAndroid Build Coastguard Worker                                                             float lightPosY, float lightPosZ,
9156*38e8c45fSAndroid Build Coastguard Worker                                                             float lightRadius) {
9157*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
9158*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
9159*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
9160*38e8c45fSAndroid Build Coastguard Worker     }
9161*38e8c45fSAndroid Build Coastguard Worker 
9162*38e8c45fSAndroid Build Coastguard Worker     half4 ambientColorHalf = {ambientColor.r, ambientColor.g, ambientColor.b, ambientColor.a};
9163*38e8c45fSAndroid Build Coastguard Worker     half4 spotColorHalf = {spotColor.r, spotColor.g, spotColor.b, spotColor.a};
9164*38e8c45fSAndroid Build Coastguard Worker     status = mFlinger->setGlobalShadowSettings(ambientColorHalf, spotColorHalf, lightPosY,
9165*38e8c45fSAndroid Build Coastguard Worker                                                lightPosZ, lightRadius);
9166*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9167*38e8c45fSAndroid Build Coastguard Worker }
9168*38e8c45fSAndroid Build Coastguard Worker 
getDisplayDecorationSupport(const sp<IBinder> & displayToken,std::optional<gui::DisplayDecorationSupport> * outSupport)9169*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getDisplayDecorationSupport(
9170*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& displayToken, std::optional<gui::DisplayDecorationSupport>* outSupport) {
9171*38e8c45fSAndroid Build Coastguard Worker     std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport> support;
9172*38e8c45fSAndroid Build Coastguard Worker     status_t status = mFlinger->getDisplayDecorationSupport(displayToken, &support);
9173*38e8c45fSAndroid Build Coastguard Worker     if (status != NO_ERROR) {
9174*38e8c45fSAndroid Build Coastguard Worker         ALOGE("getDisplayDecorationSupport failed with error %d", status);
9175*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
9176*38e8c45fSAndroid Build Coastguard Worker     }
9177*38e8c45fSAndroid Build Coastguard Worker 
9178*38e8c45fSAndroid Build Coastguard Worker     if (!support || !support.has_value()) {
9179*38e8c45fSAndroid Build Coastguard Worker         outSupport->reset();
9180*38e8c45fSAndroid Build Coastguard Worker     } else {
9181*38e8c45fSAndroid Build Coastguard Worker         outSupport->emplace();
9182*38e8c45fSAndroid Build Coastguard Worker         outSupport->value().format = static_cast<int32_t>(support->format);
9183*38e8c45fSAndroid Build Coastguard Worker         outSupport->value().alphaInterpretation =
9184*38e8c45fSAndroid Build Coastguard Worker                 static_cast<int32_t>(support->alphaInterpretation);
9185*38e8c45fSAndroid Build Coastguard Worker     }
9186*38e8c45fSAndroid Build Coastguard Worker 
9187*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
9188*38e8c45fSAndroid Build Coastguard Worker }
9189*38e8c45fSAndroid Build Coastguard Worker 
setGameModeFrameRateOverride(int32_t uid,float frameRate)9190*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setGameModeFrameRateOverride(int32_t uid, float frameRate) {
9191*38e8c45fSAndroid Build Coastguard Worker     status_t status;
9192*38e8c45fSAndroid Build Coastguard Worker     const int c_uid = IPCThreadState::self()->getCallingUid();
9193*38e8c45fSAndroid Build Coastguard Worker     if (c_uid == AID_ROOT || c_uid == AID_SYSTEM) {
9194*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->setGameModeFrameRateOverride(uid, frameRate);
9195*38e8c45fSAndroid Build Coastguard Worker     } else {
9196*38e8c45fSAndroid Build Coastguard Worker         ALOGE("setGameModeFrameRateOverride() permission denied for uid: %d", c_uid);
9197*38e8c45fSAndroid Build Coastguard Worker         status = PERMISSION_DENIED;
9198*38e8c45fSAndroid Build Coastguard Worker     }
9199*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9200*38e8c45fSAndroid Build Coastguard Worker }
9201*38e8c45fSAndroid Build Coastguard Worker 
setGameDefaultFrameRateOverride(int32_t uid,float frameRate)9202*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setGameDefaultFrameRateOverride(int32_t uid, float frameRate) {
9203*38e8c45fSAndroid Build Coastguard Worker     status_t status;
9204*38e8c45fSAndroid Build Coastguard Worker     const int c_uid = IPCThreadState::self()->getCallingUid();
9205*38e8c45fSAndroid Build Coastguard Worker     if (c_uid == AID_ROOT || c_uid == AID_SYSTEM) {
9206*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->setGameDefaultFrameRateOverride(uid, frameRate);
9207*38e8c45fSAndroid Build Coastguard Worker     } else {
9208*38e8c45fSAndroid Build Coastguard Worker         ALOGE("setGameDefaultFrameRateOverride() permission denied for uid: %d", c_uid);
9209*38e8c45fSAndroid Build Coastguard Worker         status = PERMISSION_DENIED;
9210*38e8c45fSAndroid Build Coastguard Worker     }
9211*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9212*38e8c45fSAndroid Build Coastguard Worker }
9213*38e8c45fSAndroid Build Coastguard Worker 
enableRefreshRateOverlay(bool active)9214*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::enableRefreshRateOverlay(bool active) {
9215*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
9216*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
9217*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
9218*38e8c45fSAndroid Build Coastguard Worker     }
9219*38e8c45fSAndroid Build Coastguard Worker     mFlinger->sfdo_enableRefreshRateOverlay(active);
9220*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
9221*38e8c45fSAndroid Build Coastguard Worker }
9222*38e8c45fSAndroid Build Coastguard Worker 
setDebugFlash(int delay)9223*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setDebugFlash(int delay) {
9224*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
9225*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
9226*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
9227*38e8c45fSAndroid Build Coastguard Worker     }
9228*38e8c45fSAndroid Build Coastguard Worker     mFlinger->sfdo_setDebugFlash(delay);
9229*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
9230*38e8c45fSAndroid Build Coastguard Worker }
9231*38e8c45fSAndroid Build Coastguard Worker 
scheduleComposite()9232*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::scheduleComposite() {
9233*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
9234*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
9235*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
9236*38e8c45fSAndroid Build Coastguard Worker     }
9237*38e8c45fSAndroid Build Coastguard Worker     mFlinger->sfdo_scheduleComposite();
9238*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
9239*38e8c45fSAndroid Build Coastguard Worker }
9240*38e8c45fSAndroid Build Coastguard Worker 
scheduleCommit()9241*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::scheduleCommit() {
9242*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
9243*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
9244*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
9245*38e8c45fSAndroid Build Coastguard Worker     }
9246*38e8c45fSAndroid Build Coastguard Worker     mFlinger->sfdo_scheduleCommit();
9247*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
9248*38e8c45fSAndroid Build Coastguard Worker }
9249*38e8c45fSAndroid Build Coastguard Worker 
forceClientComposition(bool enabled)9250*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::forceClientComposition(bool enabled) {
9251*38e8c45fSAndroid Build Coastguard Worker     status_t status = checkAccessPermission();
9252*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
9253*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(status);
9254*38e8c45fSAndroid Build Coastguard Worker     }
9255*38e8c45fSAndroid Build Coastguard Worker     mFlinger->sfdo_forceClientComposition(enabled);
9256*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
9257*38e8c45fSAndroid Build Coastguard Worker }
9258*38e8c45fSAndroid Build Coastguard Worker 
updateSmallAreaDetection(const std::vector<int32_t> & appIds,const std::vector<float> & thresholds)9259*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::updateSmallAreaDetection(const std::vector<int32_t>& appIds,
9260*38e8c45fSAndroid Build Coastguard Worker                                                              const std::vector<float>& thresholds) {
9261*38e8c45fSAndroid Build Coastguard Worker     status_t status;
9262*38e8c45fSAndroid Build Coastguard Worker     const int c_uid = IPCThreadState::self()->getCallingUid();
9263*38e8c45fSAndroid Build Coastguard Worker     if (c_uid == AID_ROOT || c_uid == AID_SYSTEM) {
9264*38e8c45fSAndroid Build Coastguard Worker         if (appIds.size() != thresholds.size()) return binderStatusFromStatusT(BAD_VALUE);
9265*38e8c45fSAndroid Build Coastguard Worker 
9266*38e8c45fSAndroid Build Coastguard Worker         std::vector<std::pair<int32_t, float>> mappings;
9267*38e8c45fSAndroid Build Coastguard Worker         const size_t size = appIds.size();
9268*38e8c45fSAndroid Build Coastguard Worker         mappings.reserve(size);
9269*38e8c45fSAndroid Build Coastguard Worker         for (int i = 0; i < size; i++) {
9270*38e8c45fSAndroid Build Coastguard Worker             auto row = std::make_pair(appIds[i], thresholds[i]);
9271*38e8c45fSAndroid Build Coastguard Worker             mappings.push_back(row);
9272*38e8c45fSAndroid Build Coastguard Worker         }
9273*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->updateSmallAreaDetection(mappings);
9274*38e8c45fSAndroid Build Coastguard Worker     } else {
9275*38e8c45fSAndroid Build Coastguard Worker         ALOGE("updateSmallAreaDetection() permission denied for uid: %d", c_uid);
9276*38e8c45fSAndroid Build Coastguard Worker         status = PERMISSION_DENIED;
9277*38e8c45fSAndroid Build Coastguard Worker     }
9278*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9279*38e8c45fSAndroid Build Coastguard Worker }
9280*38e8c45fSAndroid Build Coastguard Worker 
setSmallAreaDetectionThreshold(int32_t appId,float threshold)9281*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::setSmallAreaDetectionThreshold(int32_t appId, float threshold) {
9282*38e8c45fSAndroid Build Coastguard Worker     status_t status;
9283*38e8c45fSAndroid Build Coastguard Worker     const int c_uid = IPCThreadState::self()->getCallingUid();
9284*38e8c45fSAndroid Build Coastguard Worker     if (c_uid == AID_ROOT || c_uid == AID_SYSTEM) {
9285*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->setSmallAreaDetectionThreshold(appId, threshold);
9286*38e8c45fSAndroid Build Coastguard Worker     } else {
9287*38e8c45fSAndroid Build Coastguard Worker         ALOGE("setSmallAreaDetectionThreshold() permission denied for uid: %d", c_uid);
9288*38e8c45fSAndroid Build Coastguard Worker         status = PERMISSION_DENIED;
9289*38e8c45fSAndroid Build Coastguard Worker     }
9290*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9291*38e8c45fSAndroid Build Coastguard Worker }
9292*38e8c45fSAndroid Build Coastguard Worker 
getGpuContextPriority(int32_t * outPriority)9293*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getGpuContextPriority(int32_t* outPriority) {
9294*38e8c45fSAndroid Build Coastguard Worker     *outPriority = mFlinger->getGpuContextPriority();
9295*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
9296*38e8c45fSAndroid Build Coastguard Worker }
9297*38e8c45fSAndroid Build Coastguard Worker 
getMaxAcquiredBufferCount(int32_t * buffers)9298*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getMaxAcquiredBufferCount(int32_t* buffers) {
9299*38e8c45fSAndroid Build Coastguard Worker     status_t status = mFlinger->getMaxAcquiredBufferCount(buffers);
9300*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9301*38e8c45fSAndroid Build Coastguard Worker }
9302*38e8c45fSAndroid Build Coastguard Worker 
addWindowInfosListener(const sp<gui::IWindowInfosListener> & windowInfosListener,gui::WindowInfosListenerInfo * outInfo)9303*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::addWindowInfosListener(
9304*38e8c45fSAndroid Build Coastguard Worker         const sp<gui::IWindowInfosListener>& windowInfosListener,
9305*38e8c45fSAndroid Build Coastguard Worker         gui::WindowInfosListenerInfo* outInfo) {
9306*38e8c45fSAndroid Build Coastguard Worker     status_t status;
9307*38e8c45fSAndroid Build Coastguard Worker     const int pid = IPCThreadState::self()->getCallingPid();
9308*38e8c45fSAndroid Build Coastguard Worker     const int uid = IPCThreadState::self()->getCallingUid();
9309*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/270566761) update permissions check so that only system_server and shell can add
9310*38e8c45fSAndroid Build Coastguard Worker     // WindowInfosListeners
9311*38e8c45fSAndroid Build Coastguard Worker     if (uid == AID_SYSTEM || uid == AID_GRAPHICS ||
9312*38e8c45fSAndroid Build Coastguard Worker         checkPermission(sAccessSurfaceFlinger, pid, uid)) {
9313*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->addWindowInfosListener(windowInfosListener, outInfo);
9314*38e8c45fSAndroid Build Coastguard Worker     } else {
9315*38e8c45fSAndroid Build Coastguard Worker         status = PERMISSION_DENIED;
9316*38e8c45fSAndroid Build Coastguard Worker     }
9317*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9318*38e8c45fSAndroid Build Coastguard Worker }
9319*38e8c45fSAndroid Build Coastguard Worker 
removeWindowInfosListener(const sp<gui::IWindowInfosListener> & windowInfosListener)9320*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::removeWindowInfosListener(
9321*38e8c45fSAndroid Build Coastguard Worker         const sp<gui::IWindowInfosListener>& windowInfosListener) {
9322*38e8c45fSAndroid Build Coastguard Worker     status_t status;
9323*38e8c45fSAndroid Build Coastguard Worker     const int pid = IPCThreadState::self()->getCallingPid();
9324*38e8c45fSAndroid Build Coastguard Worker     const int uid = IPCThreadState::self()->getCallingUid();
9325*38e8c45fSAndroid Build Coastguard Worker     if (uid == AID_SYSTEM || uid == AID_GRAPHICS ||
9326*38e8c45fSAndroid Build Coastguard Worker         checkPermission(sAccessSurfaceFlinger, pid, uid)) {
9327*38e8c45fSAndroid Build Coastguard Worker         status = mFlinger->removeWindowInfosListener(windowInfosListener);
9328*38e8c45fSAndroid Build Coastguard Worker     } else {
9329*38e8c45fSAndroid Build Coastguard Worker         status = PERMISSION_DENIED;
9330*38e8c45fSAndroid Build Coastguard Worker     }
9331*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9332*38e8c45fSAndroid Build Coastguard Worker }
9333*38e8c45fSAndroid Build Coastguard Worker 
getStalledTransactionInfo(int pid,std::optional<gui::StalledTransactionInfo> * outInfo)9334*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getStalledTransactionInfo(
9335*38e8c45fSAndroid Build Coastguard Worker         int pid, std::optional<gui::StalledTransactionInfo>* outInfo) {
9336*38e8c45fSAndroid Build Coastguard Worker     const int callingPid = IPCThreadState::self()->getCallingPid();
9337*38e8c45fSAndroid Build Coastguard Worker     const int callingUid = IPCThreadState::self()->getCallingUid();
9338*38e8c45fSAndroid Build Coastguard Worker     if (!checkPermission(sAccessSurfaceFlinger, callingPid, callingUid)) {
9339*38e8c45fSAndroid Build Coastguard Worker         return binderStatusFromStatusT(PERMISSION_DENIED);
9340*38e8c45fSAndroid Build Coastguard Worker     }
9341*38e8c45fSAndroid Build Coastguard Worker 
9342*38e8c45fSAndroid Build Coastguard Worker     std::optional<TransactionHandler::StalledTransactionInfo> stalledTransactionInfo;
9343*38e8c45fSAndroid Build Coastguard Worker     status_t status = mFlinger->getStalledTransactionInfo(pid, stalledTransactionInfo);
9344*38e8c45fSAndroid Build Coastguard Worker     if (stalledTransactionInfo) {
9345*38e8c45fSAndroid Build Coastguard Worker         gui::StalledTransactionInfo result;
9346*38e8c45fSAndroid Build Coastguard Worker         result.layerName = String16{stalledTransactionInfo->layerName.c_str()},
9347*38e8c45fSAndroid Build Coastguard Worker         result.bufferId = stalledTransactionInfo->bufferId,
9348*38e8c45fSAndroid Build Coastguard Worker         result.frameNumber = stalledTransactionInfo->frameNumber,
9349*38e8c45fSAndroid Build Coastguard Worker         outInfo->emplace(std::move(result));
9350*38e8c45fSAndroid Build Coastguard Worker     } else {
9351*38e8c45fSAndroid Build Coastguard Worker         outInfo->reset();
9352*38e8c45fSAndroid Build Coastguard Worker     }
9353*38e8c45fSAndroid Build Coastguard Worker     return binderStatusFromStatusT(status);
9354*38e8c45fSAndroid Build Coastguard Worker }
9355*38e8c45fSAndroid Build Coastguard Worker 
getSchedulingPolicy(gui::SchedulingPolicy * outPolicy)9356*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) {
9357*38e8c45fSAndroid Build Coastguard Worker     return gui::getSchedulingPolicy(outPolicy);
9358*38e8c45fSAndroid Build Coastguard Worker }
9359*38e8c45fSAndroid Build Coastguard Worker 
notifyShutdown()9360*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::notifyShutdown() {
9361*38e8c45fSAndroid Build Coastguard Worker     TransactionTraceWriter::getInstance().invoke("systemShutdown_", /* overwrite= */ false);
9362*38e8c45fSAndroid Build Coastguard Worker     return ::android::binder::Status::ok();
9363*38e8c45fSAndroid Build Coastguard Worker }
9364*38e8c45fSAndroid Build Coastguard Worker 
addJankListener(const sp<IBinder> & layerHandle,const sp<gui::IJankListener> & listener)9365*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::addJankListener(const sp<IBinder>& layerHandle,
9366*38e8c45fSAndroid Build Coastguard Worker                                                     const sp<gui::IJankListener>& listener) {
9367*38e8c45fSAndroid Build Coastguard Worker     sp<Layer> layer = LayerHandle::getLayer(layerHandle);
9368*38e8c45fSAndroid Build Coastguard Worker     if (layer == nullptr) {
9369*38e8c45fSAndroid Build Coastguard Worker         return binder::Status::fromExceptionCode(binder::Status::EX_NULL_POINTER);
9370*38e8c45fSAndroid Build Coastguard Worker     }
9371*38e8c45fSAndroid Build Coastguard Worker     JankTracker::addJankListener(layer->sequence, IInterface::asBinder(listener));
9372*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
9373*38e8c45fSAndroid Build Coastguard Worker }
9374*38e8c45fSAndroid Build Coastguard Worker 
flushJankData(int32_t layerId)9375*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::flushJankData(int32_t layerId) {
9376*38e8c45fSAndroid Build Coastguard Worker     JankTracker::flushJankData(layerId);
9377*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
9378*38e8c45fSAndroid Build Coastguard Worker }
9379*38e8c45fSAndroid Build Coastguard Worker 
removeJankListener(int32_t layerId,const sp<gui::IJankListener> & listener,int64_t afterVsync)9380*38e8c45fSAndroid Build Coastguard Worker binder::Status SurfaceComposerAIDL::removeJankListener(int32_t layerId,
9381*38e8c45fSAndroid Build Coastguard Worker                                                        const sp<gui::IJankListener>& listener,
9382*38e8c45fSAndroid Build Coastguard Worker                                                        int64_t afterVsync) {
9383*38e8c45fSAndroid Build Coastguard Worker     JankTracker::removeJankListener(layerId, IInterface::asBinder(listener), afterVsync);
9384*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
9385*38e8c45fSAndroid Build Coastguard Worker }
9386*38e8c45fSAndroid Build Coastguard Worker 
checkAccessPermission(bool usePermissionCache)9387*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceComposerAIDL::checkAccessPermission(bool usePermissionCache) {
9388*38e8c45fSAndroid Build Coastguard Worker     if (!mFlinger->callingThreadHasUnscopedSurfaceFlingerAccess(usePermissionCache)) {
9389*38e8c45fSAndroid Build Coastguard Worker         IPCThreadState* ipc = IPCThreadState::self();
9390*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", ipc->getCallingPid(),
9391*38e8c45fSAndroid Build Coastguard Worker               ipc->getCallingUid());
9392*38e8c45fSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
9393*38e8c45fSAndroid Build Coastguard Worker     }
9394*38e8c45fSAndroid Build Coastguard Worker     return OK;
9395*38e8c45fSAndroid Build Coastguard Worker }
9396*38e8c45fSAndroid Build Coastguard Worker 
checkControlDisplayBrightnessPermission()9397*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceComposerAIDL::checkControlDisplayBrightnessPermission() {
9398*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
9399*38e8c45fSAndroid Build Coastguard Worker     const int pid = ipc->getCallingPid();
9400*38e8c45fSAndroid Build Coastguard Worker     const int uid = ipc->getCallingUid();
9401*38e8c45fSAndroid Build Coastguard Worker     if ((uid != AID_GRAPHICS) && (uid != AID_SYSTEM) &&
9402*38e8c45fSAndroid Build Coastguard Worker         !PermissionCache::checkPermission(sControlDisplayBrightness, pid, uid)) {
9403*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Permission Denial: can't control brightness pid=%d, uid=%d", pid, uid);
9404*38e8c45fSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
9405*38e8c45fSAndroid Build Coastguard Worker     }
9406*38e8c45fSAndroid Build Coastguard Worker     return OK;
9407*38e8c45fSAndroid Build Coastguard Worker }
9408*38e8c45fSAndroid Build Coastguard Worker 
checkReadFrameBufferPermission()9409*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceComposerAIDL::checkReadFrameBufferPermission() {
9410*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
9411*38e8c45fSAndroid Build Coastguard Worker     const int pid = ipc->getCallingPid();
9412*38e8c45fSAndroid Build Coastguard Worker     const int uid = ipc->getCallingUid();
9413*38e8c45fSAndroid Build Coastguard Worker     if ((uid != AID_GRAPHICS) && !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
9414*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Permission Denial: can't read framebuffer pid=%d, uid=%d", pid, uid);
9415*38e8c45fSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
9416*38e8c45fSAndroid Build Coastguard Worker     }
9417*38e8c45fSAndroid Build Coastguard Worker     return OK;
9418*38e8c45fSAndroid Build Coastguard Worker }
9419*38e8c45fSAndroid Build Coastguard Worker 
checkObservePictureProfilesPermission()9420*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceComposerAIDL::checkObservePictureProfilesPermission() {
9421*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
9422*38e8c45fSAndroid Build Coastguard Worker     const int pid = ipc->getCallingPid();
9423*38e8c45fSAndroid Build Coastguard Worker     const int uid = ipc->getCallingUid();
9424*38e8c45fSAndroid Build Coastguard Worker     if (!PermissionCache::checkPermission(sObservePictureProfiles, pid, uid)) {
9425*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Permission Denial: can't manage picture profiles pid=%d, uid=%d", pid, uid);
9426*38e8c45fSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
9427*38e8c45fSAndroid Build Coastguard Worker     }
9428*38e8c45fSAndroid Build Coastguard Worker     return OK;
9429*38e8c45fSAndroid Build Coastguard Worker }
9430*38e8c45fSAndroid Build Coastguard Worker 
forceFutureUpdate(int delayInMs)9431*38e8c45fSAndroid Build Coastguard Worker void SurfaceFlinger::forceFutureUpdate(int delayInMs) {
9432*38e8c45fSAndroid Build Coastguard Worker     static_cast<void>(mScheduler->scheduleDelayed([&]() { scheduleRepaint(); }, ms2ns(delayInMs)));
9433*38e8c45fSAndroid Build Coastguard Worker }
9434*38e8c45fSAndroid Build Coastguard Worker 
getDisplayFromLayerStack(ui::LayerStack layerStack)9435*38e8c45fSAndroid Build Coastguard Worker const DisplayDevice* SurfaceFlinger::getDisplayFromLayerStack(ui::LayerStack layerStack) {
9436*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [_, display] : mDisplays) {
9437*38e8c45fSAndroid Build Coastguard Worker         if (display->getLayerStack() == layerStack) {
9438*38e8c45fSAndroid Build Coastguard Worker             return display.get();
9439*38e8c45fSAndroid Build Coastguard Worker         }
9440*38e8c45fSAndroid Build Coastguard Worker     }
9441*38e8c45fSAndroid Build Coastguard Worker     return nullptr;
9442*38e8c45fSAndroid Build Coastguard Worker }
9443*38e8c45fSAndroid Build Coastguard Worker 
9444*38e8c45fSAndroid Build Coastguard Worker } // namespace android
9445*38e8c45fSAndroid Build Coastguard Worker 
9446*38e8c45fSAndroid Build Coastguard Worker #if defined(__gl_h_)
9447*38e8c45fSAndroid Build Coastguard Worker #error "don't include gl/gl.h in this file"
9448*38e8c45fSAndroid Build Coastguard Worker #endif
9449*38e8c45fSAndroid Build Coastguard Worker 
9450*38e8c45fSAndroid Build Coastguard Worker #if defined(__gl2_h_)
9451*38e8c45fSAndroid Build Coastguard Worker #error "don't include gl2/gl2.h in this file"
9452*38e8c45fSAndroid Build Coastguard Worker #endif
9453*38e8c45fSAndroid Build Coastguard Worker 
9454*38e8c45fSAndroid Build Coastguard Worker // TODO(b/129481165): remove the #pragma below and fix conversion issues
9455*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
9456