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, ¶m) != 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