1 /*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20 #pragma clang diagnostic ignored "-Wextra"
21
22 // #define LOG_NDEBUG 0
23 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
24
25 #include "SurfaceFlinger.h"
26
27 #include <aidl/android/hardware/power/Boost.h>
28 #include <android-base/parseint.h>
29 #include <android-base/properties.h>
30 #include <android-base/stringprintf.h>
31 #include <android-base/strings.h>
32 #include <android/configuration.h>
33 #include <android/gui/IDisplayEventConnection.h>
34 #include <android/gui/StaticDisplayInfo.h>
35 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
36 #include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
37 #include <android/hardware/configstore/1.1/types.h>
38 #include <android/native_window.h>
39 #include <android/os/IInputFlinger.h>
40 #include <android_os.h>
41 #include <binder/IPCThreadState.h>
42 #include <binder/IServiceManager.h>
43 #include <binder/PermissionCache.h>
44 #include <com_android_graphics_libgui_flags.h>
45 #include <com_android_graphics_surfaceflinger_flags.h>
46 #include <common/FlagManager.h>
47 #include <common/WorkloadTracer.h>
48 #include <common/trace.h>
49 #include <compositionengine/CompositionEngine.h>
50 #include <compositionengine/CompositionRefreshArgs.h>
51 #include <compositionengine/Display.h>
52 #include <compositionengine/DisplayColorProfile.h>
53 #include <compositionengine/DisplayColorProfileCreationArgs.h>
54 #include <compositionengine/DisplayCreationArgs.h>
55 #include <compositionengine/LayerFECompositionState.h>
56 #include <compositionengine/OutputLayer.h>
57 #include <compositionengine/RenderSurface.h>
58 #include <compositionengine/impl/DisplayColorProfile.h>
59 #include <compositionengine/impl/OutputCompositionState.h>
60 #include <compositionengine/impl/OutputLayerCompositionState.h>
61 #include <configstore/Utils.h>
62 #include <cutils/compiler.h>
63 #include <cutils/properties.h>
64 #include <fmt/format.h>
65 #include <ftl/algorithm.h>
66 #include <ftl/concat.h>
67 #include <ftl/fake_guard.h>
68 #include <ftl/future.h>
69 #include <ftl/unit.h>
70 #include <gui/AidlUtil.h>
71 #include <gui/BufferQueue.h>
72 #include <gui/DebugEGLImageTracker.h>
73 #include <gui/IProducerListener.h>
74 #include <gui/LayerMetadata.h>
75 #include <gui/LayerState.h>
76 #include <gui/Surface.h>
77 #include <gui/SurfaceComposerClient.h>
78 #include <hidl/ServiceManagement.h>
79 #include <layerproto/LayerProtoHeader.h>
80 #include <linux/sched/types.h>
81 #include <log/log.h>
82 #include <private/android_filesystem_config.h>
83 #include <private/gui/SyncFeatures.h>
84 #include <processgroup/processgroup.h>
85 #include <renderengine/RenderEngine.h>
86 #include <renderengine/impl/ExternalTexture.h>
87 #include <scheduler/FrameTargeter.h>
88 #include <statslog_surfaceflinger.h>
89 #include <sys/types.h>
90 #include <ui/ColorSpace.h>
91 #include <ui/DebugUtils.h>
92 #include <ui/DisplayId.h>
93 #include <ui/DisplayMode.h>
94 #include <ui/DisplayStatInfo.h>
95 #include <ui/DisplayState.h>
96 #include <ui/DynamicDisplayInfo.h>
97 #include <ui/FrameRateCategoryRate.h>
98 #include <ui/GraphicBufferAllocator.h>
99 #include <ui/HdrRenderTypeUtils.h>
100 #include <ui/LayerStack.h>
101 #include <ui/PixelFormat.h>
102 #include <ui/StaticDisplayInfo.h>
103 #include <unistd.h>
104 #include <utils/StopWatch.h>
105 #include <utils/String16.h>
106 #include <utils/String8.h>
107 #include <utils/Timers.h>
108 #include <utils/misc.h>
109 #include <algorithm>
110 #include <cerrno>
111 #include <cinttypes>
112 #include <cmath>
113 #include <cstdint>
114 #include <filesystem>
115 #include <functional>
116 #include <memory>
117 #include <mutex>
118 #include <optional>
119 #include <string>
120 #include <type_traits>
121 #include <unordered_map>
122 #include <vector>
123
124 #include <common/FlagManager.h>
125 #include <gui/LayerStatePermissions.h>
126 #include <gui/SchedulingPolicy.h>
127 #include <gui/SyncScreenCaptureListener.h>
128 #include <ui/DisplayIdentification.h>
129 #include "BackgroundExecutor.h"
130 #include "Client.h"
131 #include "ClientCache.h"
132 #include "Colorizer.h"
133 #include "DisplayDevice.h"
134 #include "DisplayHardware/ComposerHal.h"
135 #include "DisplayHardware/FramebufferSurface.h"
136 #include "DisplayHardware/Hal.h"
137 #include "DisplayHardware/VirtualDisplaySurface.h"
138 #include "Effects/Daltonizer.h"
139 #include "FpsReporter.h"
140 #include "FrameTimeline/FrameTimeline.h"
141 #include "FrameTracer/FrameTracer.h"
142 #include "FrontEnd/LayerCreationArgs.h"
143 #include "FrontEnd/LayerHandle.h"
144 #include "FrontEnd/LayerLifecycleManager.h"
145 #include "FrontEnd/LayerLog.h"
146 #include "FrontEnd/LayerSnapshot.h"
147 #include "HdrLayerInfoReporter.h"
148 #include "Jank/JankTracker.h"
149 #include "Layer.h"
150 #include "LayerProtoHelper.h"
151 #include "LayerVector.h"
152 #include "MutexUtils.h"
153 #include "NativeWindowSurface.h"
154 #include "PowerAdvisor/PowerAdvisor.h"
155 #include "PowerAdvisor/Workload.h"
156 #include "RegionSamplingThread.h"
157 #include "Scheduler/EventThread.h"
158 #include "Scheduler/LayerHistory.h"
159 #include "Scheduler/Scheduler.h"
160 #include "Scheduler/VsyncConfiguration.h"
161 #include "Scheduler/VsyncModulator.h"
162 #include "ScreenCaptureOutput.h"
163 #include "SurfaceFlingerProperties.h"
164 #include "TimeStats/TimeStats.h"
165 #include "TunnelModeEnabledReporter.h"
166 #include "Utils/Dumper.h"
167 #include "WindowInfosListenerInvoker.h"
168
169 #include <aidl/android/hardware/graphics/common/DisplayDecorationSupport.h>
170 #include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
171 #include <aidl/android/hardware/graphics/composer3/OutputType.h>
172 #include <aidl/android/hardware/graphics/composer3/RenderIntent.h>
173
174 #undef NO_THREAD_SAFETY_ANALYSIS
175 #define NO_THREAD_SAFETY_ANALYSIS \
176 _Pragma("GCC error \"Prefer <ftl/fake_guard.h> or MutexUtils.h helpers.\"")
177
178 namespace android {
179 using namespace std::chrono_literals;
180 using namespace std::string_literals;
181 using namespace std::string_view_literals;
182
183 using namespace hardware::configstore;
184 using namespace hardware::configstore::V1_0;
185 using namespace sysprop;
186 using ftl::Flags;
187 using namespace ftl::flag_operators;
188
189 using aidl::android::hardware::graphics::common::DisplayDecorationSupport;
190 using aidl::android::hardware::graphics::composer3::Capability;
191 using aidl::android::hardware::graphics::composer3::DisplayCapability;
192 using CompositionStrategyPredictionState = android::compositionengine::impl::
193 OutputCompositionState::CompositionStrategyPredictionState;
194
195 using base::StringAppendF;
196 using display::PhysicalDisplay;
197 using display::PhysicalDisplays;
198 using frontend::TransactionHandler;
199 using gui::DisplayInfo;
200 using gui::GameMode;
201 using gui::IDisplayEventConnection;
202 using gui::IWindowInfosListener;
203 using gui::LayerMetadata;
204 using gui::WindowInfo;
205 using gui::aidl_utils::binderStatusFromStatusT;
206 using scheduler::VsyncModulator;
207 using ui::Dataspace;
208 using ui::DisplayPrimaries;
209 using ui::RenderIntent;
210
211 namespace hal = android::hardware::graphics::composer::hal;
212
213 namespace {
214
215 static constexpr int FOUR_K_WIDTH = 3840;
216 static constexpr int FOUR_K_HEIGHT = 2160;
217
218 // TODO(b/141333600): Consolidate with DisplayMode::Builder::getDefaultDensity.
219 constexpr float FALLBACK_DENSITY = ACONFIGURATION_DENSITY_TV;
220
getDensityFromProperty(const char * property,bool required)221 float getDensityFromProperty(const char* property, bool required) {
222 char value[PROPERTY_VALUE_MAX];
223 const float density = property_get(property, value, nullptr) > 0 ? std::atof(value) : 0.f;
224 if (!density && required) {
225 ALOGE("%s must be defined as a build property", property);
226 return FALLBACK_DENSITY;
227 }
228 return density;
229 }
230
231 // Currently we only support V0_SRGB and DISPLAY_P3 as composition preference.
validateCompositionDataspace(Dataspace dataspace)232 bool validateCompositionDataspace(Dataspace dataspace) {
233 return dataspace == Dataspace::V0_SRGB || dataspace == Dataspace::DISPLAY_P3;
234 }
235
getIdleTimerTimeout(PhysicalDisplayId displayId)236 std::chrono::milliseconds getIdleTimerTimeout(PhysicalDisplayId displayId) {
237 if (const int32_t displayIdleTimerMs =
238 base::GetIntProperty("debug.sf.set_idle_timer_ms_"s +
239 std::to_string(displayId.value),
240 0);
241 displayIdleTimerMs > 0) {
242 return std::chrono::milliseconds(displayIdleTimerMs);
243 }
244
245 const int32_t setIdleTimerMs = base::GetIntProperty("debug.sf.set_idle_timer_ms"s, 0);
246 const int32_t millis = setIdleTimerMs ? setIdleTimerMs : sysprop::set_idle_timer_ms(0);
247 return std::chrono::milliseconds(millis);
248 }
249
getKernelIdleTimerSyspropConfig(PhysicalDisplayId displayId)250 bool getKernelIdleTimerSyspropConfig(PhysicalDisplayId displayId) {
251 const bool displaySupportKernelIdleTimer =
252 base::GetBoolProperty("debug.sf.support_kernel_idle_timer_"s +
253 std::to_string(displayId.value),
254 false);
255
256 return displaySupportKernelIdleTimer || sysprop::support_kernel_idle_timer(false);
257 }
258
isAbove4k30(const ui::DisplayMode & outMode)259 bool isAbove4k30(const ui::DisplayMode& outMode) {
260 using fps_approx_ops::operator>;
261 Fps refreshRate = Fps::fromValue(outMode.peakRefreshRate);
262 return outMode.resolution.getWidth() >= FOUR_K_WIDTH &&
263 outMode.resolution.getHeight() >= FOUR_K_HEIGHT && refreshRate > 30_Hz;
264 }
265
excludeDolbyVisionIf4k30Present(const std::vector<ui::Hdr> & displayHdrTypes,ui::DisplayMode & outMode)266 void excludeDolbyVisionIf4k30Present(const std::vector<ui::Hdr>& displayHdrTypes,
267 ui::DisplayMode& outMode) {
268 if (isAbove4k30(outMode) &&
269 std::any_of(displayHdrTypes.begin(), displayHdrTypes.end(),
270 [](ui::Hdr type) { return type == ui::Hdr::DOLBY_VISION_4K30; })) {
271 for (ui::Hdr type : displayHdrTypes) {
272 if (type != ui::Hdr::DOLBY_VISION_4K30 && type != ui::Hdr::DOLBY_VISION) {
273 outMode.supportedHdrTypes.push_back(type);
274 }
275 }
276 } else {
277 for (ui::Hdr type : displayHdrTypes) {
278 if (type != ui::Hdr::DOLBY_VISION_4K30) {
279 outMode.supportedHdrTypes.push_back(type);
280 }
281 }
282 }
283 }
284
filterOut4k30(const HdrCapabilities & displayHdrCapabilities)285 HdrCapabilities filterOut4k30(const HdrCapabilities& displayHdrCapabilities) {
286 std::vector<ui::Hdr> hdrTypes;
287 for (ui::Hdr type : displayHdrCapabilities.getSupportedHdrTypes()) {
288 if (type != ui::Hdr::DOLBY_VISION_4K30) {
289 hdrTypes.push_back(type);
290 }
291 }
292 return {hdrTypes, displayHdrCapabilities.getDesiredMaxLuminance(),
293 displayHdrCapabilities.getDesiredMaxAverageLuminance(),
294 displayHdrCapabilities.getDesiredMinLuminance()};
295 }
296
getLayerIdFromSurfaceControl(sp<SurfaceControl> surfaceControl)297 uint32_t getLayerIdFromSurfaceControl(sp<SurfaceControl> surfaceControl) {
298 if (!surfaceControl) {
299 return UNASSIGNED_LAYER_ID;
300 }
301 return LayerHandle::getLayerId(surfaceControl->getHandle());
302 }
303
304 /**
305 * Returns true if the file at path exists and is newer than duration.
306 */
fileNewerThan(const std::string & path,std::chrono::minutes duration)307 bool fileNewerThan(const std::string& path, std::chrono::minutes duration) {
308 using Clock = std::filesystem::file_time_type::clock;
309 std::error_code error;
310 std::filesystem::file_time_type updateTime = std::filesystem::last_write_time(path, error);
311 if (error) {
312 return false;
313 }
314 return duration > (Clock::now() - updateTime);
315 }
316
isFrameIntervalOnCadence(TimePoint expectedPresentTime,TimePoint lastExpectedPresentTimestamp,Fps lastFrameInterval,Period timeout,Duration threshold)317 bool isFrameIntervalOnCadence(TimePoint expectedPresentTime, TimePoint lastExpectedPresentTimestamp,
318 Fps lastFrameInterval, Period timeout, Duration threshold) {
319 if (lastFrameInterval.getPeriodNsecs() == 0) {
320 return false;
321 }
322
323 const auto expectedPresentTimeDeltaNs =
324 expectedPresentTime.ns() - lastExpectedPresentTimestamp.ns();
325
326 if (expectedPresentTimeDeltaNs > timeout.ns()) {
327 return false;
328 }
329
330 const auto expectedPresentPeriods = static_cast<nsecs_t>(
331 std::round(static_cast<float>(expectedPresentTimeDeltaNs) /
332 static_cast<float>(lastFrameInterval.getPeriodNsecs())));
333 const auto calculatedPeriodsOutNs = lastFrameInterval.getPeriodNsecs() * expectedPresentPeriods;
334 const auto calculatedExpectedPresentTimeNs =
335 lastExpectedPresentTimestamp.ns() + calculatedPeriodsOutNs;
336 const auto presentTimeDelta =
337 std::abs(expectedPresentTime.ns() - calculatedExpectedPresentTimeNs);
338 return presentTimeDelta < threshold.ns();
339 }
340
isExpectedPresentWithinTimeout(TimePoint expectedPresentTime,TimePoint lastExpectedPresentTimestamp,std::optional<Period> timeoutOpt,Duration threshold)341 bool isExpectedPresentWithinTimeout(TimePoint expectedPresentTime,
342 TimePoint lastExpectedPresentTimestamp,
343 std::optional<Period> timeoutOpt, Duration threshold) {
344 if (!timeoutOpt) {
345 // Always within timeout if timeoutOpt is absent and don't send hint
346 // for the timeout
347 return true;
348 }
349
350 if (timeoutOpt->ns() == 0) {
351 // Always outside timeout if timeoutOpt is 0 and always send
352 // the hint for the timeout.
353 return false;
354 }
355
356 if (expectedPresentTime.ns() < lastExpectedPresentTimestamp.ns() + timeoutOpt->ns()) {
357 return true;
358 }
359
360 // Check if within the threshold as it can be just outside the timeout
361 return std::abs(expectedPresentTime.ns() -
362 (lastExpectedPresentTimestamp.ns() + timeoutOpt->ns())) < threshold.ns();
363 }
364 } // namespace
365
366 // ---------------------------------------------------------------------------
367
368 const String16 sHardwareTest("android.permission.HARDWARE_TEST");
369 const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
370 const String16 sRotateSurfaceFlinger("android.permission.ROTATE_SURFACE_FLINGER");
371 const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
372 const String16 sControlDisplayBrightness("android.permission.CONTROL_DISPLAY_BRIGHTNESS");
373 const String16 sObservePictureProfiles("android.permission.OBSERVE_PICTURE_PROFILES");
374 const String16 sDump("android.permission.DUMP");
375 const String16 sCaptureBlackoutContent("android.permission.CAPTURE_BLACKOUT_CONTENT");
376 const String16 sInternalSystemWindow("android.permission.INTERNAL_SYSTEM_WINDOW");
377 const String16 sWakeupSurfaceFlinger("android.permission.WAKEUP_SURFACE_FLINGER");
378
379 // ---------------------------------------------------------------------------
380 int64_t SurfaceFlinger::dispSyncPresentTimeOffset;
381 bool SurfaceFlinger::useHwcForRgbToYuv;
382 bool SurfaceFlinger::hasSyncFramework;
383 int64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers;
384 int64_t SurfaceFlinger::minAcquiredBuffers = 1;
385 std::optional<int64_t> SurfaceFlinger::maxAcquiredBuffersOpt;
386 uint32_t SurfaceFlinger::maxGraphicsWidth;
387 uint32_t SurfaceFlinger::maxGraphicsHeight;
388 bool SurfaceFlinger::useContextPriority;
389 Dataspace SurfaceFlinger::defaultCompositionDataspace = Dataspace::V0_SRGB;
390 ui::PixelFormat SurfaceFlinger::defaultCompositionPixelFormat = ui::PixelFormat::RGBA_8888;
391 Dataspace SurfaceFlinger::wideColorGamutCompositionDataspace = Dataspace::V0_SRGB;
392 ui::PixelFormat SurfaceFlinger::wideColorGamutCompositionPixelFormat = ui::PixelFormat::RGBA_8888;
393 LatchUnsignaledConfig SurfaceFlinger::enableLatchUnsignaledConfig;
394
decodeDisplayColorSetting(DisplayColorSetting displayColorSetting)395 std::string decodeDisplayColorSetting(DisplayColorSetting displayColorSetting) {
396 switch (displayColorSetting) {
397 case DisplayColorSetting::kManaged:
398 return std::string("Managed");
399 case DisplayColorSetting::kUnmanaged:
400 return std::string("Unmanaged");
401 case DisplayColorSetting::kEnhanced:
402 return std::string("Enhanced");
403 default:
404 return std::string("Unknown ") + std::to_string(static_cast<int>(displayColorSetting));
405 }
406 }
407
callingThreadHasPermission(const String16 & permission)408 bool callingThreadHasPermission(const String16& permission) {
409 IPCThreadState* ipc = IPCThreadState::self();
410 const int pid = ipc->getCallingPid();
411 const int uid = ipc->getCallingUid();
412 return uid == AID_GRAPHICS || uid == AID_SYSTEM ||
413 PermissionCache::checkPermission(permission, pid, uid);
414 }
415
416 ui::Transform::RotationFlags SurfaceFlinger::sActiveDisplayRotationFlags = ui::Transform::ROT_0;
417
SurfaceFlinger(Factory & factory,SkipInitializationTag)418 SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
419 : mFactory(factory),
420 mPid(getpid()),
421 mTimeStats(std::make_shared<impl::TimeStats>()),
422 mFrameTracer(mFactory.createFrameTracer()),
423 mFrameTimeline(mFactory.createFrameTimeline(mTimeStats, mPid)),
424 mCompositionEngine(mFactory.createCompositionEngine()),
425 mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)),
426 mTunnelModeEnabledReporter(sp<TunnelModeEnabledReporter>::make()),
427 mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)),
428 mInternalDisplayDensity(
429 getDensityFromProperty("ro.sf.lcd_density", !mEmulatedDisplayDensity)),
430 mPowerAdvisor(std::make_unique<
431 adpf::impl::PowerAdvisor>([this] { disableExpensiveRendering(); },
432 std::chrono::milliseconds(
433 sysprop::display_update_imminent_timeout_ms(
434 80)))),
435 mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make()),
436 mSkipPowerOnForQuiescent(base::GetBoolProperty("ro.boot.quiescent"s, false)) {
437 ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str());
438 }
439
SurfaceFlinger(Factory & factory)440 SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {
441 SFTRACE_CALL();
442 ALOGI("SurfaceFlinger is starting");
443
444 hasSyncFramework = running_without_sync_framework(true);
445
446 dispSyncPresentTimeOffset = present_time_offset_from_vsync_ns(0);
447
448 useHwcForRgbToYuv = force_hwc_copy_for_virtual_displays(false);
449
450 maxFrameBufferAcquiredBuffers = max_frame_buffer_acquired_buffers(2);
451 minAcquiredBuffers =
452 SurfaceFlingerProperties::min_acquired_buffers().value_or(minAcquiredBuffers);
453 maxAcquiredBuffersOpt = SurfaceFlingerProperties::max_acquired_buffers();
454
455 maxGraphicsWidth = std::max(max_graphics_width(0), 0);
456 maxGraphicsHeight = std::max(max_graphics_height(0), 0);
457
458 mSupportsWideColor = has_wide_color_display(false);
459 mDefaultCompositionDataspace =
460 static_cast<ui::Dataspace>(default_composition_dataspace(Dataspace::V0_SRGB));
461 mWideColorGamutCompositionDataspace = static_cast<ui::Dataspace>(wcg_composition_dataspace(
462 mSupportsWideColor ? Dataspace::DISPLAY_P3 : Dataspace::V0_SRGB));
463 defaultCompositionDataspace = mDefaultCompositionDataspace;
464 wideColorGamutCompositionDataspace = mWideColorGamutCompositionDataspace;
465 defaultCompositionPixelFormat = static_cast<ui::PixelFormat>(
466 default_composition_pixel_format(ui::PixelFormat::RGBA_8888));
467 wideColorGamutCompositionPixelFormat =
468 static_cast<ui::PixelFormat>(wcg_composition_pixel_format(ui::PixelFormat::RGBA_8888));
469
470 mLayerCachingEnabled =
471 base::GetBoolProperty("debug.sf.enable_layer_caching"s,
472 sysprop::SurfaceFlingerProperties::enable_layer_caching()
473 .value_or(false));
474
475 useContextPriority = use_context_priority(true);
476
477 mInternalDisplayPrimaries = sysprop::getDisplayNativePrimaries();
478
479 // debugging stuff...
480 char value[PROPERTY_VALUE_MAX];
481
482 property_get("ro.build.type", value, "user");
483 mIsUserBuild = strcmp(value, "user") == 0;
484
485 mDebugFlashDelay = base::GetUintProperty("debug.sf.showupdates"s, 0u);
486
487 mBackpressureGpuComposition = base::GetBoolProperty("debug.sf.enable_gl_backpressure"s, true);
488 ALOGI_IF(mBackpressureGpuComposition, "Enabling backpressure for GPU composition");
489
490 property_get("ro.surface_flinger.supports_background_blur", value, "0");
491 bool supportsBlurs = atoi(value);
492 mSupportsBlur = supportsBlurs;
493 ALOGI_IF(!mSupportsBlur, "Disabling blur effects, they are not supported.");
494
495 property_get("debug.sf.luma_sampling", value, "1");
496 mLumaSampling = atoi(value);
497
498 property_get("debug.sf.disable_client_composition_cache", value, "0");
499 mDisableClientCompositionCache = atoi(value);
500
501 property_get("debug.sf.predict_hwc_composition_strategy", value, "1");
502 mPredictCompositionStrategy = atoi(value);
503
504 property_get("debug.sf.treat_170m_as_sRGB", value, "0");
505 mTreat170mAsSrgb = atoi(value);
506
507 property_get("debug.sf.dim_in_gamma_in_enhanced_screenshots", value, 0);
508 mDimInGammaSpaceForEnhancedScreenshots = atoi(value);
509
510 mIgnoreHwcPhysicalDisplayOrientation =
511 base::GetBoolProperty("debug.sf.ignore_hwc_physical_display_orientation"s, false);
512
513 // We should be reading 'persist.sys.sf.color_saturation' here
514 // but since /data may be encrypted, we need to wait until after vold
515 // comes online to attempt to read the property. The property is
516 // instead read after the boot animation
517
518 if (base::GetBoolProperty("debug.sf.treble_testing_override"s, false)) {
519 // Without the override SurfaceFlinger cannot connect to HIDL
520 // services that are not listed in the manifests. Considered
521 // deriving the setting from the set service name, but it
522 // would be brittle if the name that's not 'default' is used
523 // for production purposes later on.
524 ALOGI("Enabling Treble testing override");
525 android::hardware::details::setTrebleTestingOverride(true);
526 }
527
528 // TODO (b/270966065) Update the HWC based refresh rate overlay to support spinner
529 mRefreshRateOverlaySpinner = property_get_bool("debug.sf.show_refresh_rate_overlay_spinner", 0);
530 mRefreshRateOverlayRenderRate =
531 property_get_bool("debug.sf.show_refresh_rate_overlay_render_rate", 0);
532 mRefreshRateOverlayShowInMiddle =
533 property_get_bool("debug.sf.show_refresh_rate_overlay_in_middle", 0);
534
535 if (!mIsUserBuild && base::GetBoolProperty("debug.sf.enable_transaction_tracing"s, true)) {
536 mTransactionTracing.emplace();
537 mLayerTracing.setTransactionTracing(*mTransactionTracing);
538 }
539
540 mIgnoreHdrCameraLayers = ignore_hdr_camera_layers(false);
541 }
542
getLatchUnsignaledConfig()543 LatchUnsignaledConfig SurfaceFlinger::getLatchUnsignaledConfig() {
544 if (base::GetBoolProperty("debug.sf.auto_latch_unsignaled"s, true)) {
545 return LatchUnsignaledConfig::AutoSingleLayer;
546 }
547
548 return LatchUnsignaledConfig::Disabled;
549 }
550
551 SurfaceFlinger::~SurfaceFlinger() = default;
552
binderDied(const wp<IBinder> &)553 void SurfaceFlinger::binderDied(const wp<IBinder>&) {
554 // the window manager died on us. prepare its eulogy.
555 mBootFinished = false;
556
557 static_cast<void>(mScheduler->schedule([this]() FTL_FAKE_GUARD(kMainThreadContext) {
558 // Sever the link to inputflinger since it's gone as well.
559 mInputFlinger.clear();
560
561 initializeDisplays();
562 }));
563
564 mInitBootPropsFuture.callOnce([this] {
565 return std::async(std::launch::async, &SurfaceFlinger::initBootProperties, this);
566 });
567
568 mInitBootPropsFuture.wait();
569 }
570
run()571 void SurfaceFlinger::run() {
572 mScheduler->run();
573 }
574
createVirtualDisplay(const std::string & displayName,bool isSecure,gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy,const std::string & uniqueId,float requestedRefreshRate)575 sp<IBinder> SurfaceFlinger::createVirtualDisplay(
576 const std::string& displayName, bool isSecure,
577 gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy, const std::string& uniqueId,
578 float requestedRefreshRate) {
579 // SurfaceComposerAIDL checks for some permissions, but adding an additional check here.
580 // This is to ensure that only root, system, and graphics can request to create a secure
581 // display. Secure displays can show secure content so we add an additional restriction on it.
582 const uid_t uid = IPCThreadState::self()->getCallingUid();
583 if (isSecure && uid != AID_ROOT && uid != AID_GRAPHICS && uid != AID_SYSTEM) {
584 ALOGE("Only privileged processes can create a secure display");
585 return nullptr;
586 }
587
588 ALOGD("Creating virtual display: %s", displayName.c_str());
589
590 class DisplayToken : public BBinder {
591 sp<SurfaceFlinger> flinger;
592 virtual ~DisplayToken() {
593 // no more references, this display must be terminated
594 Mutex::Autolock _l(flinger->mStateLock);
595 flinger->mCurrentState.displays.removeItem(wp<IBinder>::fromExisting(this));
596 flinger->setTransactionFlags(eDisplayTransactionNeeded);
597 }
598
599 public:
600 explicit DisplayToken(const sp<SurfaceFlinger>& flinger) : flinger(flinger) {}
601 };
602
603 sp<BBinder> token = sp<DisplayToken>::make(sp<SurfaceFlinger>::fromExisting(this));
604
605 Mutex::Autolock _l(mStateLock);
606 // Display ID is assigned when virtual display is allocated by HWC.
607 DisplayDeviceState state;
608 state.isSecure = isSecure;
609 // Set display as protected when marked as secure to ensure no behavior change
610 // TODO (b/314820005): separate as a different arg when creating the display.
611 state.isProtected = isSecure;
612 state.optimizationPolicy = optimizationPolicy;
613 // Virtual displays start in ON mode.
614 state.initialPowerMode = hal::PowerMode::ON;
615 state.displayName = displayName;
616 state.uniqueId = uniqueId;
617 state.requestedRefreshRate = Fps::fromValue(requestedRefreshRate);
618 mCurrentState.displays.add(token, state);
619 return token;
620 }
621
destroyVirtualDisplay(const sp<IBinder> & displayToken)622 status_t SurfaceFlinger::destroyVirtualDisplay(const sp<IBinder>& displayToken) {
623 Mutex::Autolock lock(mStateLock);
624
625 const ssize_t index = mCurrentState.displays.indexOfKey(displayToken);
626 if (index < 0) {
627 ALOGE("%s: Invalid display token %p", __func__, displayToken.get());
628 return NAME_NOT_FOUND;
629 }
630
631 const DisplayDeviceState& state = mCurrentState.displays.valueAt(index);
632 if (state.physical) {
633 ALOGE("%s: Invalid operation on physical display", __func__);
634 return INVALID_OPERATION;
635 }
636
637 ALOGD("Destroying virtual display: %s", state.displayName.c_str());
638
639 mCurrentState.displays.removeItemsAt(index);
640 setTransactionFlags(eDisplayTransactionNeeded);
641 return NO_ERROR;
642 }
643
enableHalVirtualDisplays(bool enable)644 void SurfaceFlinger::enableHalVirtualDisplays(bool enable) {
645 auto& generator = mVirtualDisplayIdGenerators.hal;
646 if (!generator && enable) {
647 ALOGI("Enabling HAL virtual displays");
648 generator.emplace(getHwComposer().getMaxVirtualDisplayCount());
649 } else if (generator && !enable) {
650 ALOGW_IF(generator->inUse(), "Disabling HAL virtual displays while in use");
651 generator.reset();
652 }
653 }
654
acquireVirtualDisplay(ui::Size resolution,ui::PixelFormat format,const std::string & uniqueId,compositionengine::DisplayCreationArgsBuilder & builder)655 std::optional<VirtualDisplayIdVariant> SurfaceFlinger::acquireVirtualDisplay(
656 ui::Size resolution, ui::PixelFormat format, const std::string& uniqueId,
657 compositionengine::DisplayCreationArgsBuilder& builder) {
658 if (auto& generator = mVirtualDisplayIdGenerators.hal) {
659 if (const auto id = generator->generateId()) {
660 if (getHwComposer().allocateVirtualDisplay(*id, resolution, &format)) {
661 acquireVirtualDisplaySnapshot(*id, uniqueId);
662 builder.setId(*id);
663 return *id;
664 }
665
666 generator->releaseId(*id);
667 } else {
668 ALOGW("%s: Exhausted HAL virtual displays", __func__);
669 }
670
671 ALOGW("%s: Falling back to GPU virtual display", __func__);
672 }
673
674 const auto id = mVirtualDisplayIdGenerators.gpu.generateId();
675 LOG_ALWAYS_FATAL_IF(!id, "Failed to generate ID for GPU virtual display");
676 acquireVirtualDisplaySnapshot(*id, uniqueId);
677 builder.setId(*id);
678 return *id;
679 }
680
releaseVirtualDisplay(VirtualDisplayIdVariant displayId)681 void SurfaceFlinger::releaseVirtualDisplay(VirtualDisplayIdVariant displayId) {
682 ftl::match(
683 displayId,
684 [this](HalVirtualDisplayId halVirtualDisplayId) {
685 if (auto& generator = mVirtualDisplayIdGenerators.hal) {
686 generator->releaseId(halVirtualDisplayId);
687 releaseVirtualDisplaySnapshot(halVirtualDisplayId);
688 }
689 },
690 [this](GpuVirtualDisplayId gpuVirtualDisplayId) {
691 mVirtualDisplayIdGenerators.gpu.releaseId(gpuVirtualDisplayId);
692 releaseVirtualDisplaySnapshot(gpuVirtualDisplayId);
693 });
694 }
695
releaseVirtualDisplaySnapshot(VirtualDisplayId displayId)696 void SurfaceFlinger::releaseVirtualDisplaySnapshot(VirtualDisplayId displayId) {
697 std::lock_guard lock(mVirtualDisplaysMutex);
698 if (!mVirtualDisplays.erase(displayId)) {
699 ALOGW("%s: Virtual display snapshot was not removed", __func__);
700 }
701 }
702
getPhysicalDisplayIdsLocked() const703 std::vector<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIdsLocked() const {
704 std::vector<PhysicalDisplayId> displayIds;
705 displayIds.reserve(mPhysicalDisplays.size());
706
707 const auto defaultDisplayId = getDefaultDisplayDeviceLocked()->getPhysicalId();
708 displayIds.push_back(defaultDisplayId);
709
710 for (const auto& [id, display] : mPhysicalDisplays) {
711 if (id != defaultDisplayId) {
712 displayIds.push_back(id);
713 }
714 }
715
716 return displayIds;
717 }
718
getPhysicalDisplayIdLocked(const sp<display::DisplayToken> & displayToken) const719 std::optional<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIdLocked(
720 const sp<display::DisplayToken>& displayToken) const {
721 return ftl::find_if(mPhysicalDisplays, PhysicalDisplay::hasToken(displayToken))
722 .transform(&ftl::to_key<PhysicalDisplays>);
723 }
724
getPhysicalDisplayToken(PhysicalDisplayId displayId) const725 sp<IBinder> SurfaceFlinger::getPhysicalDisplayToken(PhysicalDisplayId displayId) const {
726 Mutex::Autolock lock(mStateLock);
727 return getPhysicalDisplayTokenLocked(displayId);
728 }
729
getHwComposer() const730 HWComposer& SurfaceFlinger::getHwComposer() const {
731 return mCompositionEngine->getHwComposer();
732 }
733
getRenderEngine() const734 renderengine::RenderEngine& SurfaceFlinger::getRenderEngine() const {
735 return *mRenderEngine;
736 }
737
getCompositionEngine() const738 compositionengine::CompositionEngine& SurfaceFlinger::getCompositionEngine() const {
739 return *mCompositionEngine.get();
740 }
741
bootFinished()742 void SurfaceFlinger::bootFinished() {
743 if (mBootFinished == true) {
744 ALOGE("Extra call to bootFinished");
745 return;
746 }
747 mBootFinished = true;
748 FlagManager::getMutableInstance().markBootCompleted();
749
750 if (android::os::perfetto_sdk_tracing()) {
751 ::tracing_perfetto::registerWithPerfetto();
752 }
753
754 mInitBootPropsFuture.wait();
755 mRenderEnginePrimeCacheFuture.wait();
756
757 const nsecs_t now = systemTime();
758 const nsecs_t duration = now - mBootTime;
759 ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)));
760
761 mFrameTracer->initialize();
762 mFrameTimeline->onBootFinished();
763 getRenderEngine().setEnableTracing(FlagManager::getInstance().use_skia_tracing());
764
765 // wait patiently for the window manager death
766 const String16 name("window");
767 mWindowManager = defaultServiceManager()->waitForService(name);
768 if (mWindowManager != 0) {
769 mWindowManager->linkToDeath(sp<IBinder::DeathRecipient>::fromExisting(this));
770 }
771
772 // stop boot animation
773 // formerly we would just kill the process, but we now ask it to exit so it
774 // can choose where to stop the animation.
775 property_set("service.bootanim.exit", "1");
776
777 const int LOGTAG_SF_STOP_BOOTANIM = 60110;
778 LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
779
780 sp<IBinder> input(defaultServiceManager()->waitForService(String16("inputflinger")));
781
782 static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) {
783 if (input == nullptr) {
784 ALOGE("Failed to link to input service");
785 } else {
786 mInputFlinger = interface_cast<os::IInputFlinger>(input);
787 }
788
789 readPersistentProperties();
790 const bool hintSessionEnabled = FlagManager::getInstance().use_adpf_cpu_hint();
791 mPowerAdvisor->enablePowerHintSession(hintSessionEnabled);
792 const bool hintSessionUsed = mPowerAdvisor->usePowerHintSession();
793 // Ordering is important here, as onBootFinished signals to PowerAdvisor that concurrency
794 // is safe because its variables are initialized.
795 mPowerAdvisor->onBootFinished();
796 ALOGD("Power hint is %s",
797 hintSessionUsed ? "supported" : (hintSessionEnabled ? "unsupported" : "disabled"));
798 if (hintSessionUsed) {
799 std::optional<pid_t> renderEngineTid = getRenderEngine().getRenderEngineTid();
800 std::vector<int32_t> tidList;
801 tidList.emplace_back(gettid());
802 if (renderEngineTid.has_value()) {
803 tidList.emplace_back(*renderEngineTid);
804 }
805 if (!mPowerAdvisor->startPowerHintSession(std::move(tidList))) {
806 ALOGW("Cannot start power hint session");
807 }
808 }
809
810 mBootStage = BootStage::FINISHED;
811
812 if (base::GetBoolProperty("sf.debug.show_refresh_rate_overlay"s, false)) {
813 ftl::FakeGuard guard(mStateLock);
814 enableRefreshRateOverlay(true);
815 }
816 }));
817 }
818
shouldUseGraphiteIfCompiledAndSupported()819 bool shouldUseGraphiteIfCompiledAndSupported() {
820 return FlagManager::getInstance().graphite_renderengine() ||
821 (FlagManager::getInstance().graphite_renderengine_preview_rollout() &&
822 base::GetBoolProperty(PROPERTY_DEBUG_RENDERENGINE_GRAPHITE_PREVIEW_OPTIN, false));
823 }
824
chooseRenderEngineType(renderengine::RenderEngineCreationArgs::Builder & builder)825 void chooseRenderEngineType(renderengine::RenderEngineCreationArgs::Builder& builder) {
826 char prop[PROPERTY_VALUE_MAX];
827 property_get(PROPERTY_DEBUG_RENDERENGINE_BACKEND, prop, "");
828
829 // TODO: b/293371537 - Once GraphiteVk is deemed relatively stable, log a warning that
830 // PROPERTY_DEBUG_RENDERENGINE_BACKEND is deprecated
831 if (strcmp(prop, "skiagl") == 0) {
832 builder.setThreaded(renderengine::RenderEngine::Threaded::NO)
833 .setGraphicsApi(renderengine::RenderEngine::GraphicsApi::GL);
834 } else if (strcmp(prop, "skiaglthreaded") == 0) {
835 builder.setThreaded(renderengine::RenderEngine::Threaded::YES)
836 .setGraphicsApi(renderengine::RenderEngine::GraphicsApi::GL);
837 } else if (strcmp(prop, "skiavk") == 0) {
838 builder.setThreaded(renderengine::RenderEngine::Threaded::NO)
839 .setGraphicsApi(renderengine::RenderEngine::GraphicsApi::VK);
840 } else if (strcmp(prop, "skiavkthreaded") == 0) {
841 builder.setThreaded(renderengine::RenderEngine::Threaded::YES)
842 .setGraphicsApi(renderengine::RenderEngine::GraphicsApi::VK);
843 } else {
844 const auto kVulkan = renderengine::RenderEngine::GraphicsApi::VK;
845 // TODO: b/341728634 - Clean up conditional compilation.
846 // Note: this guard in particular must check e.g.
847 // COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS_GRAPHITE_RENDERENGINE directly (instead of calling e.g.
848 // COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS(GRAPHITE_RENDERENGINE)) because that macro is undefined
849 // in the libsurfaceflingerflags_test variant of com_android_graphics_surfaceflinger_flags.h, which
850 // is used by layertracegenerator (which also needs SurfaceFlinger.cpp). :)
851 #if COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS_GRAPHITE_RENDERENGINE || \
852 COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS_FORCE_COMPILE_GRAPHITE_RENDERENGINE
853 const bool useGraphite = shouldUseGraphiteIfCompiledAndSupported() &&
854 renderengine::RenderEngine::canSupport(kVulkan);
855 #else
856 const bool useGraphite = false;
857 if (shouldUseGraphiteIfCompiledAndSupported()) {
858 ALOGE("RenderEngine's Graphite Skia backend was requested, but it is not compiled in "
859 "this build! Falling back to Ganesh backend selection logic.");
860 }
861 #endif
862 const bool useVulkan = useGraphite ||
863 (FlagManager::getInstance().vulkan_renderengine() &&
864 renderengine::RenderEngine::canSupport(kVulkan));
865
866 builder.setSkiaBackend(useGraphite ? renderengine::RenderEngine::SkiaBackend::GRAPHITE
867 : renderengine::RenderEngine::SkiaBackend::GANESH);
868 builder.setGraphicsApi(useVulkan ? kVulkan : renderengine::RenderEngine::GraphicsApi::GL);
869 }
870 }
871
872 /**
873 * Choose a suggested blurring algorithm if supportsBlur is true. By default Kawase will be
874 * suggested as it's faster than a full Gaussian blur and looks close enough.
875 */
chooseBlurAlgorithm(bool supportsBlur)876 renderengine::RenderEngine::BlurAlgorithm chooseBlurAlgorithm(bool supportsBlur) {
877 if (!supportsBlur) {
878 return renderengine::RenderEngine::BlurAlgorithm::NONE;
879 }
880
881 auto const algorithm = base::GetProperty(PROPERTY_DEBUG_RENDERENGINE_BLUR_ALGORITHM, "");
882 if (algorithm == "gaussian") {
883 return renderengine::RenderEngine::BlurAlgorithm::GAUSSIAN;
884 } else if (algorithm == "kawase2") {
885 return renderengine::RenderEngine::BlurAlgorithm::KAWASE_DUAL_FILTER;
886 } else if (algorithm == "kawase") {
887 return renderengine::RenderEngine::BlurAlgorithm::KAWASE;
888 } else {
889 if (FlagManager::getInstance().window_blur_kawase2()) {
890 return renderengine::RenderEngine::BlurAlgorithm::KAWASE_DUAL_FILTER;
891 }
892 return renderengine::RenderEngine::BlurAlgorithm::KAWASE;
893 }
894 }
895
init()896 void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {
897 SFTRACE_CALL();
898 ALOGI("SurfaceFlinger's main thread ready to run. "
899 "Initializing graphics H/W...");
900 addTransactionReadyFilters();
901 Mutex::Autolock lock(mStateLock);
902
903 // Get a RenderEngine for the given display / config (can't fail)
904 // TODO(b/77156734): We need to stop casting and use HAL types when possible.
905 // Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
906 auto builder = renderengine::RenderEngineCreationArgs::Builder()
907 .setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
908 .setImageCacheSize(maxFrameBufferAcquiredBuffers)
909 .setEnableProtectedContext(enable_protected_contents(false))
910 .setPrecacheToneMapperShaderOnly(false)
911 .setBlurAlgorithm(chooseBlurAlgorithm(mSupportsBlur))
912 .setContextPriority(
913 useContextPriority
914 ? renderengine::RenderEngine::ContextPriority::REALTIME
915 : renderengine::RenderEngine::ContextPriority::MEDIUM);
916 chooseRenderEngineType(builder);
917 mRenderEngine = renderengine::RenderEngine::create(builder.build());
918 mCompositionEngine->setRenderEngine(mRenderEngine.get());
919 mMaxRenderTargetSize =
920 std::min(getRenderEngine().getMaxTextureSize(), getRenderEngine().getMaxViewportDims());
921
922 // Set SF main policy after initializing RenderEngine which has its own policy.
923 if (!SetTaskProfiles(0, {"SFMainPolicy"})) {
924 ALOGW("Failed to set main task profile");
925 }
926
927 mCompositionEngine->setTimeStats(mTimeStats);
928
929 mHWComposer = getFactory().createHWComposer(mHwcServiceName);
930 mCompositionEngine->setHwComposer(mHWComposer.get());
931 auto& composer = mCompositionEngine->getHwComposer();
932 composer.setCallback(*this);
933 mDisplayModeController.setHwComposer(&composer);
934
935 ClientCache::getInstance().setRenderEngine(&getRenderEngine());
936
937 mHasReliablePresentFences =
938 !getHwComposer().hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
939
940 enableLatchUnsignaledConfig = getLatchUnsignaledConfig();
941
942 if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) {
943 enableHalVirtualDisplays(true);
944 }
945
946 // Process hotplug for displays connected at boot.
947 LOG_ALWAYS_FATAL_IF(!configureLocked(),
948 "Initial display configuration failed: HWC did not hotplug");
949
950 mActiveDisplayId = getPrimaryDisplayIdLocked();
951
952 // Commit primary display.
953 sp<const DisplayDevice> display;
954 if (const auto indexOpt = mCurrentState.getDisplayIndex(mActiveDisplayId)) {
955 const auto& displays = mCurrentState.displays;
956
957 const auto& token = displays.keyAt(*indexOpt);
958 const auto& state = displays.valueAt(*indexOpt);
959
960 processDisplayAdded(token, state);
961 mDrawingState.displays.add(token, state);
962
963 display = getDefaultDisplayDeviceLocked();
964 }
965
966 LOG_ALWAYS_FATAL_IF(!display, "Failed to configure the primary display");
967 LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(display->getPhysicalId()),
968 "Primary display is disconnected");
969
970 // TODO(b/241285876): The Scheduler needlessly depends on creating the CompositionEngine part of
971 // the DisplayDevice, hence the above commit of the primary display. Remove that special case by
972 // initializing the Scheduler after configureLocked, once decoupled from DisplayDevice.
973 initScheduler(display);
974
975 // Start listening after creating the Scheduler, since the listener calls into it.
976 mDisplayModeController.setActiveModeListener(
977 display::DisplayModeController::ActiveModeListener::make(
978 [this](PhysicalDisplayId displayId, Fps vsyncRate, Fps renderRate) {
979 // This callback cannot lock mStateLock, as some callers already lock it.
980 // Instead, switch context to the main thread.
981 static_cast<void>(mScheduler->schedule([=,
982 this]() FTL_FAKE_GUARD(mStateLock) {
983 if (const auto display = getDisplayDeviceLocked(displayId)) {
984 display->updateRefreshRateOverlayRate(vsyncRate, renderRate);
985 }
986 }));
987 }));
988
989 mLayerTracing.setTakeLayersSnapshotProtoFunction(
990 [&](uint32_t traceFlags,
991 const LayerTracing::OnLayersSnapshotCallback& onLayersSnapshot) {
992 // Do not wait the future to avoid deadlocks
993 // between main and Perfetto threads (b/313130597)
994 static_cast<void>(mScheduler->schedule(
995 [&, traceFlags, onLayersSnapshot]() FTL_FAKE_GUARD(mStateLock)
996 FTL_FAKE_GUARD(kMainThreadContext) {
997 auto snapshot =
998 takeLayersSnapshotProto(traceFlags, TimePoint::now(),
999 mLastCommittedVsyncId, true);
1000 onLayersSnapshot(std::move(snapshot));
1001 }));
1002 });
1003
1004 // Commit secondary display(s).
1005 processDisplayChangesLocked();
1006
1007 // initialize our drawing state
1008 mDrawingState = mCurrentState;
1009
1010 onActiveDisplayChangedLocked(nullptr, *display);
1011
1012 static_cast<void>(mScheduler->schedule(
1013 [this]() FTL_FAKE_GUARD(kMainThreadContext) { initializeDisplays(); }));
1014
1015 mPowerAdvisor->init();
1016
1017 if (base::GetBoolProperty("service.sf.prime_shader_cache"s, true)) {
1018 constexpr const char* kWhence = "primeCache";
1019 setSchedFifo(false, kWhence);
1020
1021 mRenderEnginePrimeCacheFuture.callOnce([this] {
1022 renderengine::PrimeCacheConfig config;
1023 config.cacheHolePunchLayer =
1024 base::GetBoolProperty("debug.sf.prime_shader_cache.hole_punch"s, true);
1025 config.cacheSolidLayers =
1026 base::GetBoolProperty("debug.sf.prime_shader_cache.solid_layers"s, true);
1027 config.cacheSolidDimmedLayers =
1028 base::GetBoolProperty("debug.sf.prime_shader_cache.solid_dimmed_layers"s, true);
1029 config.cacheImageLayers =
1030 base::GetBoolProperty("debug.sf.prime_shader_cache.image_layers"s, true);
1031 config.cacheImageDimmedLayers =
1032 base::GetBoolProperty("debug.sf.prime_shader_cache.image_dimmed_layers"s, true);
1033 config.cacheClippedLayers =
1034 base::GetBoolProperty("debug.sf.prime_shader_cache.clipped_layers"s, true);
1035 config.cacheShadowLayers =
1036 base::GetBoolProperty("debug.sf.prime_shader_cache.shadow_layers"s, true);
1037 config.cachePIPImageLayers =
1038 base::GetBoolProperty("debug.sf.prime_shader_cache.pip_image_layers"s, true);
1039 config.cacheTransparentImageDimmedLayers = base::
1040 GetBoolProperty("debug.sf.prime_shader_cache.transparent_image_dimmed_layers"s,
1041 true);
1042 config.cacheClippedDimmedImageLayers = base::
1043 GetBoolProperty("debug.sf.prime_shader_cache.clipped_dimmed_image_layers"s,
1044 true);
1045 // ro.surface_flinger.prime_chader_cache.ultrahdr exists as a previous ro property
1046 // which we maintain for backwards compatibility.
1047 config.cacheUltraHDR =
1048 base::GetBoolProperty("ro.surface_flinger.prime_shader_cache.ultrahdr"s, false);
1049 config.cacheEdgeExtension =
1050 base::GetBoolProperty("debug.sf.prime_shader_cache.edge_extension_shader"s,
1051 true);
1052 return getRenderEngine().primeCache(config);
1053 });
1054
1055 setSchedFifo(true, kWhence);
1056 }
1057
1058 // Avoid blocking the main thread on `init` to set properties.
1059 mInitBootPropsFuture.callOnce([this] {
1060 return std::async(std::launch::async, &SurfaceFlinger::initBootProperties, this);
1061 });
1062
1063 initTransactionTraceWriter();
1064 ALOGV("Done initializing");
1065 }
1066
1067 // During boot, offload `initBootProperties` to another thread. `property_set` depends on
1068 // `property_service`, which may be delayed by slow operations like `mount_all --late` in
1069 // the `init` process. See b/34499826 and b/63844978.
initBootProperties()1070 void SurfaceFlinger::initBootProperties() {
1071 property_set("service.sf.present_timestamp", mHasReliablePresentFences ? "1" : "0");
1072
1073 if (base::GetBoolProperty("debug.sf.boot_animation"s, true) &&
1074 (base::GetIntProperty("debug.sf.nobootanimation"s, 0) == 0)) {
1075 // Reset and (if needed) start BootAnimation.
1076 property_set("service.bootanim.exit", "0");
1077 property_set("service.bootanim.progress", "0");
1078 property_set("ctl.start", "bootanim");
1079 }
1080 }
1081
initTransactionTraceWriter()1082 void SurfaceFlinger::initTransactionTraceWriter() {
1083 if (!mTransactionTracing) {
1084 return;
1085 }
1086 TransactionTraceWriter::getInstance().setWriterFunction(
1087 [&](const std::string& filename, bool overwrite) {
1088 auto writeFn = [&]() {
1089 if (!overwrite && fileNewerThan(filename, std::chrono::minutes{10})) {
1090 ALOGD("TransactionTraceWriter: file=%s already exists", filename.c_str());
1091 return;
1092 }
1093 ALOGD("TransactionTraceWriter: writing file=%s", filename.c_str());
1094 mTransactionTracing->writeToFile(filename);
1095 mTransactionTracing->flush();
1096 };
1097 if (std::this_thread::get_id() == mMainThreadId) {
1098 writeFn();
1099 } else {
1100 mScheduler->schedule(writeFn).get();
1101 }
1102 });
1103 }
1104
readPersistentProperties()1105 void SurfaceFlinger::readPersistentProperties() {
1106 Mutex::Autolock _l(mStateLock);
1107
1108 char value[PROPERTY_VALUE_MAX];
1109
1110 property_get("persist.sys.sf.color_saturation", value, "1.0");
1111 mGlobalSaturationFactor = atof(value);
1112 updateColorMatrixLocked();
1113 ALOGV("Saturation is set to %.2f", mGlobalSaturationFactor);
1114
1115 property_get("persist.sys.sf.native_mode", value, "0");
1116 mDisplayColorSetting = static_cast<DisplayColorSetting>(atoi(value));
1117
1118 mForceColorMode =
1119 static_cast<ui::ColorMode>(base::GetIntProperty("persist.sys.sf.color_mode"s, 0));
1120 }
1121
getSupportedFrameTimestamps(std::vector<FrameEvent> * outSupported) const1122 status_t SurfaceFlinger::getSupportedFrameTimestamps(std::vector<FrameEvent>* outSupported) const {
1123 *outSupported = {
1124 FrameEvent::REQUESTED_PRESENT,
1125 FrameEvent::ACQUIRE,
1126 FrameEvent::LATCH,
1127 FrameEvent::FIRST_REFRESH_START,
1128 FrameEvent::LAST_REFRESH_START,
1129 FrameEvent::GPU_COMPOSITION_DONE,
1130 FrameEvent::DEQUEUE_READY,
1131 FrameEvent::RELEASE,
1132 };
1133
1134 if (mHasReliablePresentFences) {
1135 outSupported->push_back(FrameEvent::DISPLAY_PRESENT);
1136 }
1137 return NO_ERROR;
1138 }
1139
getDisplayState(const sp<IBinder> & displayToken,ui::DisplayState * state)1140 status_t SurfaceFlinger::getDisplayState(const sp<IBinder>& displayToken, ui::DisplayState* state) {
1141 if (!displayToken || !state) {
1142 return BAD_VALUE;
1143 }
1144
1145 Mutex::Autolock lock(mStateLock);
1146
1147 const auto display = getDisplayDeviceLocked(displayToken);
1148 if (!display) {
1149 return NAME_NOT_FOUND;
1150 }
1151
1152 state->layerStack = display->getLayerStack();
1153 state->orientation = display->getOrientation();
1154
1155 const Rect layerStackRect = display->getLayerStackSpaceRect();
1156 state->layerStackSpaceRect =
1157 layerStackRect.isValid() ? layerStackRect.getSize() : display->getSize();
1158
1159 return NO_ERROR;
1160 }
1161
getStaticDisplayInfo(int64_t displayId,ui::StaticDisplayInfo * info)1162 status_t SurfaceFlinger::getStaticDisplayInfo(int64_t displayId, ui::StaticDisplayInfo* info) {
1163 if (!info) {
1164 return BAD_VALUE;
1165 }
1166
1167 Mutex::Autolock lock(mStateLock);
1168 const PhysicalDisplayId id = PhysicalDisplayId::fromValue(static_cast<uint64_t>(displayId));
1169 const auto displayOpt = mPhysicalDisplays.get(id).and_then(getDisplayDeviceAndSnapshot());
1170
1171 if (!displayOpt) {
1172 return NAME_NOT_FOUND;
1173 }
1174
1175 const auto& [display, snapshotRef] = *displayOpt;
1176 const auto& snapshot = snapshotRef.get();
1177
1178 info->connectionType = snapshot.connectionType();
1179 info->port = snapshot.port();
1180 info->deviceProductInfo = snapshot.deviceProductInfo();
1181
1182 if (mEmulatedDisplayDensity) {
1183 info->density = mEmulatedDisplayDensity;
1184 } else {
1185 info->density = info->connectionType == ui::DisplayConnectionType::Internal
1186 ? mInternalDisplayDensity
1187 : FALLBACK_DENSITY;
1188 }
1189 info->density /= ACONFIGURATION_DENSITY_MEDIUM;
1190
1191 info->secure = display->isSecure();
1192 info->installOrientation = display->getPhysicalOrientation();
1193
1194 return NO_ERROR;
1195 }
1196
getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo * & info,const sp<DisplayDevice> & display,const display::DisplaySnapshot & snapshot)1197 void SurfaceFlinger::getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo*& info,
1198 const sp<DisplayDevice>& display,
1199 const display::DisplaySnapshot& snapshot) {
1200 const auto& displayModes = snapshot.displayModes();
1201 info->supportedDisplayModes.clear();
1202 info->supportedDisplayModes.reserve(displayModes.size());
1203
1204 for (const auto& [id, mode] : displayModes) {
1205 ui::DisplayMode outMode;
1206 outMode.id = ftl::to_underlying(id);
1207
1208 auto [width, height] = mode->getResolution();
1209 auto [xDpi, yDpi] = mode->getDpi();
1210
1211 if (const auto physicalOrientation = display->getPhysicalOrientation();
1212 physicalOrientation == ui::ROTATION_90 || physicalOrientation == ui::ROTATION_270) {
1213 std::swap(width, height);
1214 std::swap(xDpi, yDpi);
1215 }
1216
1217 outMode.resolution = ui::Size(width, height);
1218
1219 outMode.xDpi = xDpi;
1220 outMode.yDpi = yDpi;
1221
1222 const auto peakFps = mode->getPeakFps();
1223 outMode.peakRefreshRate = peakFps.getValue();
1224 outMode.vsyncRate = mode->getVsyncRate().getValue();
1225
1226 const auto vsyncConfigSet =
1227 mScheduler->getVsyncConfigsForRefreshRate(Fps::fromValue(outMode.peakRefreshRate));
1228 outMode.appVsyncOffset = vsyncConfigSet.late.appOffset;
1229 outMode.sfVsyncOffset = vsyncConfigSet.late.sfOffset;
1230 outMode.group = mode->getGroup();
1231
1232 // This is how far in advance a buffer must be queued for
1233 // presentation at a given time. If you want a buffer to appear
1234 // on the screen at time N, you must submit the buffer before
1235 // (N - presentationDeadline).
1236 //
1237 // Normally it's one full refresh period (to give SF a chance to
1238 // latch the buffer), but this can be reduced by configuring a
1239 // VsyncController offset. Any additional delays introduced by the hardware
1240 // composer or panel must be accounted for here.
1241 //
1242 // We add an additional 1ms to allow for processing time and
1243 // differences between the ideal and actual refresh rate.
1244 outMode.presentationDeadline = peakFps.getPeriodNsecs() - outMode.sfVsyncOffset + 1000000;
1245 excludeDolbyVisionIf4k30Present(display->getHdrCapabilities().getSupportedHdrTypes(),
1246 outMode);
1247 info->supportedDisplayModes.push_back(outMode);
1248 }
1249
1250 info->supportedColorModes = snapshot.filterColorModes(mSupportsWideColor);
1251
1252 const PhysicalDisplayId displayId = snapshot.displayId();
1253
1254 const auto mode = display->refreshRateSelector().getActiveMode();
1255 info->activeDisplayModeId = ftl::to_underlying(mode.modePtr->getId());
1256 info->renderFrameRate = mode.fps.getValue();
1257 info->hasArrSupport = mode.modePtr->getVrrConfig() && FlagManager::getInstance().vrr_config();
1258
1259 const auto [normal, high] = display->refreshRateSelector().getFrameRateCategoryRates();
1260 ui::FrameRateCategoryRate frameRateCategoryRate(normal.getValue(), high.getValue());
1261 info->frameRateCategoryRate = frameRateCategoryRate;
1262
1263 if (info->hasArrSupport) {
1264 info->supportedRefreshRates = display->refreshRateSelector().getSupportedFrameRates();
1265 } else {
1266 // On non-ARR devices, list the refresh rates same as the supported display modes.
1267 std::vector<float> supportedFrameRates;
1268 supportedFrameRates.reserve(info->supportedDisplayModes.size());
1269 std::transform(info->supportedDisplayModes.begin(), info->supportedDisplayModes.end(),
1270 std::back_inserter(supportedFrameRates),
1271 [](ui::DisplayMode mode) { return mode.peakRefreshRate; });
1272 info->supportedRefreshRates = supportedFrameRates;
1273 }
1274 info->activeColorMode = display->getCompositionDisplay()->getState().colorMode;
1275 info->hdrCapabilities = filterOut4k30(display->getHdrCapabilities());
1276
1277 info->autoLowLatencyModeSupported =
1278 getHwComposer().hasDisplayCapability(displayId,
1279 DisplayCapability::AUTO_LOW_LATENCY_MODE);
1280 info->gameContentTypeSupported =
1281 getHwComposer().supportsContentType(displayId, hal::ContentType::GAME);
1282
1283 info->preferredBootDisplayMode = static_cast<ui::DisplayModeId>(-1);
1284
1285 if (getHwComposer().hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
1286 if (const auto hwcId = getHwComposer().getPreferredBootDisplayMode(displayId)) {
1287 if (const auto modeId = snapshot.translateModeId(*hwcId)) {
1288 info->preferredBootDisplayMode = ftl::to_underlying(*modeId);
1289 }
1290 }
1291 }
1292 }
1293
getDynamicDisplayInfoFromId(int64_t physicalDisplayId,ui::DynamicDisplayInfo * info)1294 status_t SurfaceFlinger::getDynamicDisplayInfoFromId(int64_t physicalDisplayId,
1295 ui::DynamicDisplayInfo* info) {
1296 if (!info) {
1297 return BAD_VALUE;
1298 }
1299
1300 Mutex::Autolock lock(mStateLock);
1301
1302 const PhysicalDisplayId id =
1303 PhysicalDisplayId::fromValue(static_cast<uint64_t>(physicalDisplayId));
1304 const auto displayOpt = mPhysicalDisplays.get(id).and_then(getDisplayDeviceAndSnapshot());
1305
1306 if (!displayOpt) {
1307 return NAME_NOT_FOUND;
1308 }
1309
1310 const auto& [display, snapshotRef] = *displayOpt;
1311 getDynamicDisplayInfoInternal(info, display, snapshotRef.get());
1312 return NO_ERROR;
1313 }
1314
getDynamicDisplayInfoFromToken(const sp<IBinder> & displayToken,ui::DynamicDisplayInfo * info)1315 status_t SurfaceFlinger::getDynamicDisplayInfoFromToken(const sp<IBinder>& displayToken,
1316 ui::DynamicDisplayInfo* info) {
1317 if (!displayToken || !info) {
1318 return BAD_VALUE;
1319 }
1320
1321 Mutex::Autolock lock(mStateLock);
1322
1323 const auto displayOpt = ftl::find_if(mPhysicalDisplays, PhysicalDisplay::hasToken(displayToken))
1324 .transform(&ftl::to_mapped_ref<PhysicalDisplays>)
1325 .and_then(getDisplayDeviceAndSnapshot());
1326
1327 if (!displayOpt) {
1328 return NAME_NOT_FOUND;
1329 }
1330
1331 const auto& [display, snapshotRef] = *displayOpt;
1332 getDynamicDisplayInfoInternal(info, display, snapshotRef.get());
1333 return NO_ERROR;
1334 }
1335
getDisplayStats(const sp<IBinder> & displayToken,DisplayStatInfo * outStats)1336 status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& displayToken,
1337 DisplayStatInfo* outStats) {
1338 if (!outStats) {
1339 return BAD_VALUE;
1340 }
1341
1342 // TODO: b/277364366 - Require a display token from clients and remove fallback to pacesetter.
1343 std::optional<PhysicalDisplayId> displayIdOpt;
1344 if (displayToken) {
1345 Mutex::Autolock lock(mStateLock);
1346 displayIdOpt = getPhysicalDisplayIdLocked(displayToken);
1347 if (!displayIdOpt) {
1348 ALOGW("%s: Invalid physical display token %p", __func__, displayToken.get());
1349 return NAME_NOT_FOUND;
1350 }
1351 }
1352
1353 const auto schedule = mScheduler->getVsyncSchedule(displayIdOpt);
1354 if (!schedule) {
1355 ALOGE("%s: Missing VSYNC schedule for display %s!", __func__,
1356 to_string(*displayIdOpt).c_str());
1357 return NAME_NOT_FOUND;
1358 }
1359 outStats->vsyncTime = schedule->vsyncDeadlineAfter(TimePoint::now()).ns();
1360 outStats->vsyncPeriod = schedule->period().ns();
1361 return NO_ERROR;
1362 }
1363
setDesiredMode(display::DisplayModeRequest && desiredMode)1364 void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& desiredMode) {
1365 const auto mode = desiredMode.mode;
1366 const auto displayId = mode.modePtr->getPhysicalDisplayId();
1367
1368 SFTRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str());
1369
1370 const bool emitEvent = desiredMode.emitEvent;
1371
1372 using DesiredModeAction = display::DisplayModeController::DesiredModeAction;
1373
1374 switch (mDisplayModeController.setDesiredMode(displayId, std::move(desiredMode))) {
1375 case DesiredModeAction::InitiateDisplayModeSwitch: {
1376 const auto selectorPtr = mDisplayModeController.selectorPtrFor(displayId);
1377 if (!selectorPtr) break;
1378
1379 const auto activeMode = selectorPtr->getActiveMode();
1380 const Fps renderRate = activeMode.fps;
1381
1382 // DisplayModeController::setDesiredMode updated the render rate, so inform Scheduler.
1383 mScheduler->setRenderRate(displayId, renderRate, true /* applyImmediately */);
1384
1385 // Schedule a new frame to initiate the display mode switch.
1386 scheduleComposite(FrameHint::kNone);
1387
1388 // Start receiving vsync samples now, so that we can detect a period
1389 // switch.
1390 mScheduler->resyncToHardwareVsync(displayId, true /* allowToEnable */,
1391 mode.modePtr.get());
1392
1393 // As we called to set period, we will call to onRefreshRateChangeCompleted once
1394 // VsyncController model is locked.
1395 mScheduler->modulateVsync(displayId, &VsyncModulator::onRefreshRateChangeInitiated);
1396
1397 mScheduler->updatePhaseConfiguration(displayId, mode.fps);
1398 mScheduler->setModeChangePending(true);
1399
1400 // The mode set to switch resolution is not initiated until the display transaction that
1401 // resizes the display. DM sends this transaction in response to a mode change event, so
1402 // emit the event now, not when finalizing the mode change as for a refresh rate switch.
1403 if (FlagManager::getInstance().synced_resolution_switch() &&
1404 !mode.matchesResolution(activeMode)) {
1405 mScheduler->onDisplayModeChanged(displayId, mode,
1406 /*clearContentRequirements*/ true);
1407 }
1408 break;
1409 }
1410 case DesiredModeAction::InitiateRenderRateSwitch:
1411 mScheduler->setRenderRate(displayId, mode.fps, /*applyImmediately*/ false);
1412 mScheduler->updatePhaseConfiguration(displayId, mode.fps);
1413
1414 if (emitEvent) {
1415 mScheduler->onDisplayModeChanged(displayId, mode,
1416 /*clearContentRequirements*/ false);
1417 }
1418 break;
1419 case DesiredModeAction::None:
1420 break;
1421 }
1422 }
1423
setActiveModeFromBackdoor(const sp<display::DisplayToken> & displayToken,DisplayModeId modeId,Fps minFps,Fps maxFps)1424 status_t SurfaceFlinger::setActiveModeFromBackdoor(const sp<display::DisplayToken>& displayToken,
1425 DisplayModeId modeId, Fps minFps, Fps maxFps) {
1426 SFTRACE_CALL();
1427
1428 if (!displayToken) {
1429 return BAD_VALUE;
1430 }
1431
1432 const char* const whence = __func__;
1433 auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) -> status_t {
1434 const auto displayOpt =
1435 FTL_FAKE_GUARD(mStateLock,
1436 ftl::find_if(mPhysicalDisplays,
1437 PhysicalDisplay::hasToken(displayToken))
1438 .transform(&ftl::to_mapped_ref<PhysicalDisplays>)
1439 .and_then(getDisplayDeviceAndSnapshot()));
1440 if (!displayOpt) {
1441 ALOGE("%s: Invalid physical display token %p", whence, displayToken.get());
1442 return NAME_NOT_FOUND;
1443 }
1444
1445 const auto& [display, snapshotRef] = *displayOpt;
1446 const auto& snapshot = snapshotRef.get();
1447
1448 const auto fpsOpt = snapshot.displayModes().get(modeId).transform(
1449 [](const DisplayModePtr& mode) { return mode->getPeakFps(); });
1450
1451 if (!fpsOpt) {
1452 ALOGE("%s: Invalid mode %d for display %s", whence, ftl::to_underlying(modeId),
1453 to_string(snapshot.displayId()).c_str());
1454 return BAD_VALUE;
1455 }
1456
1457 const Fps fps = *fpsOpt;
1458 const FpsRange physical = {fps, fps};
1459 const FpsRange render = {minFps.isValid() ? minFps : fps, maxFps.isValid() ? maxFps : fps};
1460 const FpsRanges ranges = {physical, render};
1461
1462 // Keep the old switching type.
1463 const bool allowGroupSwitching =
1464 display->refreshRateSelector().getCurrentPolicy().allowGroupSwitching;
1465
1466 const scheduler::RefreshRateSelector::DisplayManagerPolicy policy{modeId, ranges, ranges,
1467 allowGroupSwitching};
1468
1469 return setDesiredDisplayModeSpecsInternal(display, policy);
1470 });
1471
1472 return future.get();
1473 }
1474
finalizeDisplayModeChange(PhysicalDisplayId displayId)1475 bool SurfaceFlinger::finalizeDisplayModeChange(PhysicalDisplayId displayId) {
1476 SFTRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str());
1477
1478 const auto pendingModeOpt = mDisplayModeController.getPendingMode(displayId);
1479 if (!pendingModeOpt) {
1480 // There is no pending mode change. This can happen if the active
1481 // display changed and the mode change happened on a different display.
1482 return true;
1483 }
1484
1485 const auto& activeMode = pendingModeOpt->mode;
1486 const bool resolutionMatch = !FlagManager::getInstance().synced_resolution_switch() ||
1487 activeMode.matchesResolution(mDisplayModeController.getActiveMode(displayId));
1488
1489 if (!FlagManager::getInstance().synced_resolution_switch()) {
1490 if (const auto oldResolution =
1491 mDisplayModeController.getActiveMode(displayId).modePtr->getResolution();
1492 oldResolution != activeMode.modePtr->getResolution()) {
1493 auto& state =
1494 mCurrentState.displays.editValueFor(getPhysicalDisplayTokenLocked(displayId));
1495 // We need to generate new sequenceId in order to recreate the display (and this
1496 // way the framebuffer).
1497 state.sequenceId = DisplayDeviceState{}.sequenceId;
1498 state.physical->activeMode = activeMode.modePtr.get();
1499 processDisplayChangesLocked();
1500
1501 // The DisplayDevice has been destroyed, so abort the commit for the now dead
1502 // FrameTargeter.
1503 return false;
1504 }
1505 }
1506
1507 mDisplayModeController.finalizeModeChange(displayId, activeMode.modePtr->getId(),
1508 activeMode.modePtr->getVsyncRate(), activeMode.fps);
1509
1510 mScheduler->updatePhaseConfiguration(displayId, activeMode.fps);
1511
1512 // Skip for resolution changes, since the event was already emitted on setting the desired mode.
1513 if (resolutionMatch && pendingModeOpt->emitEvent) {
1514 mScheduler->onDisplayModeChanged(displayId, activeMode, /*clearContentRequirements*/ true);
1515 }
1516
1517 return true;
1518 }
1519
dropModeRequest(PhysicalDisplayId displayId)1520 void SurfaceFlinger::dropModeRequest(PhysicalDisplayId displayId) {
1521 mDisplayModeController.clearDesiredMode(displayId);
1522 if (displayId == mActiveDisplayId) {
1523 // TODO(b/255635711): Check for pending mode changes on other displays.
1524 mScheduler->setModeChangePending(false);
1525 }
1526 }
1527
applyActiveMode(PhysicalDisplayId displayId)1528 void SurfaceFlinger::applyActiveMode(PhysicalDisplayId displayId) {
1529 const auto activeModeOpt = mDisplayModeController.getDesiredMode(displayId);
1530 auto activeModePtr = activeModeOpt->mode.modePtr;
1531 const auto renderFps = activeModeOpt->mode.fps;
1532
1533 dropModeRequest(displayId);
1534
1535 constexpr bool kAllowToEnable = true;
1536 mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable, std::move(activeModePtr).take());
1537
1538 mScheduler->setRenderRate(displayId, renderFps, /*applyImmediately*/ true);
1539 mScheduler->updatePhaseConfiguration(displayId, renderFps);
1540 }
1541
initiateDisplayModeChanges()1542 void SurfaceFlinger::initiateDisplayModeChanges() {
1543 SFTRACE_CALL();
1544
1545 for (const auto& [displayId, physical] : mPhysicalDisplays) {
1546 auto desiredModeOpt = mDisplayModeController.getDesiredMode(displayId);
1547 if (!desiredModeOpt) {
1548 continue;
1549 }
1550
1551 const auto desiredModeId = desiredModeOpt->mode.modePtr->getId();
1552 const auto displayModePtrOpt = physical.snapshot().displayModes().get(desiredModeId);
1553
1554 if (!displayModePtrOpt) {
1555 ALOGW("Desired display mode is no longer supported. Mode ID = %d",
1556 ftl::to_underlying(desiredModeId));
1557 continue;
1558 }
1559
1560 ALOGV("%s changing active mode to %d(%s) for display %s", __func__,
1561 ftl::to_underlying(desiredModeId),
1562 to_string(displayModePtrOpt->get()->getVsyncRate()).c_str(),
1563 to_string(displayId).c_str());
1564
1565 const auto activeMode = mDisplayModeController.getActiveMode(displayId);
1566
1567 if (!desiredModeOpt->force && desiredModeOpt->mode == activeMode) {
1568 applyActiveMode(displayId);
1569 continue;
1570 }
1571
1572 const auto selectorPtr = mDisplayModeController.selectorPtrFor(displayId);
1573
1574 // Desired active mode was set, it is different than the mode currently in use, however
1575 // allowed modes might have changed by the time we process the refresh.
1576 // Make sure the desired mode is still allowed
1577 if (!selectorPtr->isModeAllowed(desiredModeOpt->mode)) {
1578 dropModeRequest(displayId);
1579 continue;
1580 }
1581
1582 // TODO(b/142753666) use constrains
1583 hal::VsyncPeriodChangeConstraints constraints;
1584 constraints.desiredTimeNanos = systemTime();
1585 constraints.seamlessRequired = false;
1586 hal::VsyncPeriodChangeTimeline outTimeline;
1587
1588 // When initiating a resolution change, wait until the commit that resizes the display.
1589 if (FlagManager::getInstance().synced_resolution_switch() &&
1590 !activeMode.matchesResolution(desiredModeOpt->mode)) {
1591 const auto display = getDisplayDeviceLocked(displayId);
1592 if (display->getSize() != desiredModeOpt->mode.modePtr->getResolution()) {
1593 continue;
1594 }
1595 }
1596
1597 const auto error =
1598 mDisplayModeController.initiateModeChange(displayId, std::move(*desiredModeOpt),
1599 constraints, outTimeline);
1600 if (error != display::DisplayModeController::ModeChangeResult::Changed) {
1601 dropModeRequest(displayId);
1602 if (FlagManager::getInstance().display_config_error_hal() &&
1603 error == display::DisplayModeController::ModeChangeResult::Rejected) {
1604 mScheduler->onDisplayModeRejected(displayId, desiredModeId);
1605 }
1606 continue;
1607 }
1608
1609 selectorPtr->onModeChangeInitiated();
1610 mScheduler->onNewVsyncPeriodChangeTimeline(outTimeline);
1611
1612 if (outTimeline.refreshRequired) {
1613 scheduleComposite(FrameHint::kNone);
1614 } else {
1615 // HWC has requested to apply the mode change immediately rather than on the next frame.
1616 finalizeDisplayModeChange(displayId);
1617
1618 const auto desiredModeOpt = mDisplayModeController.getDesiredMode(displayId);
1619 if (desiredModeOpt &&
1620 mDisplayModeController.getActiveMode(displayId) == desiredModeOpt->mode) {
1621 applyActiveMode(displayId);
1622 }
1623 }
1624 }
1625 }
1626
disableExpensiveRendering()1627 void SurfaceFlinger::disableExpensiveRendering() {
1628 const char* const whence = __func__;
1629 auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) {
1630 SFTRACE_NAME(whence);
1631 if (mPowerAdvisor->isUsingExpensiveRendering()) {
1632 for (const auto& [_, display] : mDisplays) {
1633 constexpr bool kDisable = false;
1634 mPowerAdvisor->setExpensiveRenderingExpected(display->getId(), kDisable);
1635 }
1636 }
1637 });
1638
1639 future.wait();
1640 }
1641
getDisplayNativePrimaries(const sp<IBinder> & displayToken,ui::DisplayPrimaries & primaries)1642 status_t SurfaceFlinger::getDisplayNativePrimaries(const sp<IBinder>& displayToken,
1643 ui::DisplayPrimaries& primaries) {
1644 if (!displayToken) {
1645 return BAD_VALUE;
1646 }
1647
1648 Mutex::Autolock lock(mStateLock);
1649
1650 const auto display = ftl::find_if(mPhysicalDisplays, PhysicalDisplay::hasToken(displayToken))
1651 .transform(&ftl::to_mapped_ref<PhysicalDisplays>);
1652 if (!display) {
1653 return NAME_NOT_FOUND;
1654 }
1655
1656 if (!display.transform(&PhysicalDisplay::isInternal).value()) {
1657 return INVALID_OPERATION;
1658 }
1659
1660 // TODO(b/229846990): For now, assume that all internal displays have the same primaries.
1661 primaries = mInternalDisplayPrimaries;
1662 return NO_ERROR;
1663 }
1664
setActiveColorMode(const sp<IBinder> & displayToken,ui::ColorMode mode)1665 status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& displayToken, ui::ColorMode mode) {
1666 if (!displayToken) {
1667 return BAD_VALUE;
1668 }
1669
1670 const char* const whence = __func__;
1671 auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) -> status_t {
1672 const auto displayOpt =
1673 ftl::find_if(mPhysicalDisplays, PhysicalDisplay::hasToken(displayToken))
1674 .transform(&ftl::to_mapped_ref<PhysicalDisplays>)
1675 .and_then(getDisplayDeviceAndSnapshot());
1676
1677 if (!displayOpt) {
1678 ALOGE("%s: Invalid physical display token %p", whence, displayToken.get());
1679 return NAME_NOT_FOUND;
1680 }
1681
1682 const auto& [display, snapshotRef] = *displayOpt;
1683 const auto& snapshot = snapshotRef.get();
1684
1685 const auto modes = snapshot.filterColorModes(mSupportsWideColor);
1686 const bool exists = std::find(modes.begin(), modes.end(), mode) != modes.end();
1687
1688 if (mode < ui::ColorMode::NATIVE || !exists) {
1689 ALOGE("%s: Invalid color mode %s (%d) for display %s", whence,
1690 decodeColorMode(mode).c_str(), mode, to_string(snapshot.displayId()).c_str());
1691 return BAD_VALUE;
1692 }
1693
1694 display->getCompositionDisplay()->setColorProfile(
1695 {mode, Dataspace::UNKNOWN, RenderIntent::COLORIMETRIC});
1696
1697 return NO_ERROR;
1698 });
1699
1700 // TODO(b/195698395): Propagate error.
1701 future.wait();
1702 return NO_ERROR;
1703 }
1704
getBootDisplayModeSupport(bool * outSupport) const1705 status_t SurfaceFlinger::getBootDisplayModeSupport(bool* outSupport) const {
1706 auto future = mScheduler->schedule(
1707 [this] { return getHwComposer().hasCapability(Capability::BOOT_DISPLAY_CONFIG); });
1708
1709 *outSupport = future.get();
1710 return NO_ERROR;
1711 }
1712
getOverlaySupport(gui::OverlayProperties * outProperties) const1713 status_t SurfaceFlinger::getOverlaySupport(gui::OverlayProperties* outProperties) const {
1714 const auto& aidlProperties = getHwComposer().getOverlaySupport();
1715 // convert aidl OverlayProperties to gui::OverlayProperties
1716 outProperties->combinations.reserve(aidlProperties.combinations.size());
1717 for (const auto& combination : aidlProperties.combinations) {
1718 std::vector<int32_t> pixelFormats;
1719 pixelFormats.reserve(combination.pixelFormats.size());
1720 std::transform(combination.pixelFormats.cbegin(), combination.pixelFormats.cend(),
1721 std::back_inserter(pixelFormats),
1722 [](const auto& val) { return static_cast<int32_t>(val); });
1723 std::vector<int32_t> standards;
1724 standards.reserve(combination.standards.size());
1725 std::transform(combination.standards.cbegin(), combination.standards.cend(),
1726 std::back_inserter(standards),
1727 [](const auto& val) { return static_cast<int32_t>(val); });
1728 std::vector<int32_t> transfers;
1729 transfers.reserve(combination.transfers.size());
1730 std::transform(combination.transfers.cbegin(), combination.transfers.cend(),
1731 std::back_inserter(transfers),
1732 [](const auto& val) { return static_cast<int32_t>(val); });
1733 std::vector<int32_t> ranges;
1734 ranges.reserve(combination.ranges.size());
1735 std::transform(combination.ranges.cbegin(), combination.ranges.cend(),
1736 std::back_inserter(ranges),
1737 [](const auto& val) { return static_cast<int32_t>(val); });
1738 gui::OverlayProperties::SupportedBufferCombinations outCombination;
1739 outCombination.pixelFormats = std::move(pixelFormats);
1740 outCombination.standards = std::move(standards);
1741 outCombination.transfers = std::move(transfers);
1742 outCombination.ranges = std::move(ranges);
1743 outProperties->combinations.emplace_back(outCombination);
1744 }
1745 outProperties->supportMixedColorSpaces = aidlProperties.supportMixedColorSpaces;
1746 if (aidlProperties.lutProperties) {
1747 std::vector<gui::LutProperties> outLutProperties;
1748 for (auto properties : *aidlProperties.lutProperties) {
1749 if (!properties) {
1750 gui::LutProperties currentProperties;
1751 currentProperties.dimension =
1752 static_cast<gui::LutProperties::Dimension>(properties->dimension);
1753 currentProperties.size = properties->size;
1754 currentProperties.samplingKeys.reserve(properties->samplingKeys.size());
1755 std::transform(properties->samplingKeys.cbegin(), properties->samplingKeys.cend(),
1756 std::back_inserter(currentProperties.samplingKeys),
1757 [](const auto& val) {
1758 return static_cast<gui::LutProperties::SamplingKey>(val);
1759 });
1760 outLutProperties.push_back(std::move(currentProperties));
1761 }
1762 }
1763 outProperties->lutProperties.emplace(outLutProperties.begin(), outLutProperties.end());
1764 }
1765 return NO_ERROR;
1766 }
1767
setBootDisplayMode(const sp<display::DisplayToken> & displayToken,DisplayModeId modeId)1768 status_t SurfaceFlinger::setBootDisplayMode(const sp<display::DisplayToken>& displayToken,
1769 DisplayModeId modeId) {
1770 const char* const whence = __func__;
1771 auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) -> status_t {
1772 const auto snapshotOpt =
1773 ftl::find_if(mPhysicalDisplays, PhysicalDisplay::hasToken(displayToken))
1774 .transform(&ftl::to_mapped_ref<PhysicalDisplays>)
1775 .transform(&PhysicalDisplay::snapshotRef);
1776
1777 if (!snapshotOpt) {
1778 ALOGE("%s: Invalid physical display token %p", whence, displayToken.get());
1779 return NAME_NOT_FOUND;
1780 }
1781
1782 const auto& snapshot = snapshotOpt->get();
1783 const auto hwcIdOpt = snapshot.displayModes().get(modeId).transform(
1784 [](const DisplayModePtr& mode) { return mode->getHwcId(); });
1785
1786 if (!hwcIdOpt) {
1787 ALOGE("%s: Invalid mode %d for display %s", whence, ftl::to_underlying(modeId),
1788 to_string(snapshot.displayId()).c_str());
1789 return BAD_VALUE;
1790 }
1791
1792 return getHwComposer().setBootDisplayMode(snapshot.displayId(), *hwcIdOpt);
1793 });
1794 return future.get();
1795 }
1796
clearBootDisplayMode(const sp<IBinder> & displayToken)1797 status_t SurfaceFlinger::clearBootDisplayMode(const sp<IBinder>& displayToken) {
1798 const char* const whence = __func__;
1799 auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) -> status_t {
1800 if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
1801 return getHwComposer().clearBootDisplayMode(*displayId);
1802 } else {
1803 ALOGE("%s: Invalid display token %p", whence, displayToken.get());
1804 return BAD_VALUE;
1805 }
1806 });
1807 return future.get();
1808 }
1809
getHdrConversionCapabilities(std::vector<gui::HdrConversionCapability> * hdrConversionCapabilities) const1810 status_t SurfaceFlinger::getHdrConversionCapabilities(
1811 std::vector<gui::HdrConversionCapability>* hdrConversionCapabilities) const {
1812 bool hdrOutputConversionSupport;
1813 getHdrOutputConversionSupport(&hdrOutputConversionSupport);
1814 if (hdrOutputConversionSupport == false) {
1815 ALOGE("hdrOutputConversion is not supported by this device.");
1816 return INVALID_OPERATION;
1817 }
1818 const auto aidlConversionCapability = getHwComposer().getHdrConversionCapabilities();
1819 for (auto capability : aidlConversionCapability) {
1820 gui::HdrConversionCapability tempCapability;
1821 tempCapability.sourceType = static_cast<int>(capability.sourceType);
1822 tempCapability.outputType = static_cast<int>(capability.outputType);
1823 tempCapability.addsLatency = capability.addsLatency;
1824 hdrConversionCapabilities->push_back(tempCapability);
1825 }
1826 return NO_ERROR;
1827 }
1828
setHdrConversionStrategy(const gui::HdrConversionStrategy & hdrConversionStrategy,int32_t * outPreferredHdrOutputType)1829 status_t SurfaceFlinger::setHdrConversionStrategy(
1830 const gui::HdrConversionStrategy& hdrConversionStrategy,
1831 int32_t* outPreferredHdrOutputType) {
1832 bool hdrOutputConversionSupport;
1833 getHdrOutputConversionSupport(&hdrOutputConversionSupport);
1834 if (hdrOutputConversionSupport == false) {
1835 ALOGE("hdrOutputConversion is not supported by this device.");
1836 return INVALID_OPERATION;
1837 }
1838 auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) mutable -> status_t {
1839 using AidlHdrConversionStrategy =
1840 aidl::android::hardware::graphics::common::HdrConversionStrategy;
1841 using GuiHdrConversionStrategyTag = gui::HdrConversionStrategy::Tag;
1842 AidlHdrConversionStrategy aidlConversionStrategy;
1843 status_t status;
1844 aidl::android::hardware::graphics::common::Hdr aidlPreferredHdrOutputType;
1845 switch (hdrConversionStrategy.getTag()) {
1846 case GuiHdrConversionStrategyTag::passthrough: {
1847 aidlConversionStrategy.set<AidlHdrConversionStrategy::Tag::passthrough>(
1848 hdrConversionStrategy.get<GuiHdrConversionStrategyTag::passthrough>());
1849 status = getHwComposer().setHdrConversionStrategy(aidlConversionStrategy,
1850 &aidlPreferredHdrOutputType);
1851 *outPreferredHdrOutputType = static_cast<int32_t>(aidlPreferredHdrOutputType);
1852 return status;
1853 }
1854 case GuiHdrConversionStrategyTag::autoAllowedHdrTypes: {
1855 auto autoHdrTypes =
1856 hdrConversionStrategy
1857 .get<GuiHdrConversionStrategyTag::autoAllowedHdrTypes>();
1858 std::vector<aidl::android::hardware::graphics::common::Hdr> aidlAutoHdrTypes;
1859 for (auto type : autoHdrTypes) {
1860 aidlAutoHdrTypes.push_back(
1861 static_cast<aidl::android::hardware::graphics::common::Hdr>(type));
1862 }
1863 aidlConversionStrategy.set<AidlHdrConversionStrategy::Tag::autoAllowedHdrTypes>(
1864 aidlAutoHdrTypes);
1865 status = getHwComposer().setHdrConversionStrategy(aidlConversionStrategy,
1866 &aidlPreferredHdrOutputType);
1867 *outPreferredHdrOutputType = static_cast<int32_t>(aidlPreferredHdrOutputType);
1868 return status;
1869 }
1870 case GuiHdrConversionStrategyTag::forceHdrConversion: {
1871 auto forceHdrConversion =
1872 hdrConversionStrategy
1873 .get<GuiHdrConversionStrategyTag::forceHdrConversion>();
1874 aidlConversionStrategy.set<AidlHdrConversionStrategy::Tag::forceHdrConversion>(
1875 static_cast<aidl::android::hardware::graphics::common::Hdr>(
1876 forceHdrConversion));
1877 status = getHwComposer().setHdrConversionStrategy(aidlConversionStrategy,
1878 &aidlPreferredHdrOutputType);
1879 *outPreferredHdrOutputType = static_cast<int32_t>(aidlPreferredHdrOutputType);
1880 return status;
1881 }
1882 }
1883 });
1884 return future.get();
1885 }
1886
getHdrOutputConversionSupport(bool * outSupport) const1887 status_t SurfaceFlinger::getHdrOutputConversionSupport(bool* outSupport) const {
1888 auto future = mScheduler->schedule([this] {
1889 return getHwComposer().hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG);
1890 });
1891
1892 *outSupport = future.get();
1893 return NO_ERROR;
1894 }
1895
setAutoLowLatencyMode(const sp<IBinder> & displayToken,bool on)1896 void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) {
1897 const char* const whence = __func__;
1898 static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) {
1899 if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
1900 getHwComposer().setAutoLowLatencyMode(*displayId, on);
1901 } else {
1902 ALOGE("%s: Invalid display token %p", whence, displayToken.get());
1903 }
1904 }));
1905 }
1906
setGameContentType(const sp<IBinder> & displayToken,bool on)1907 void SurfaceFlinger::setGameContentType(const sp<IBinder>& displayToken, bool on) {
1908 const char* const whence = __func__;
1909 static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) {
1910 if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
1911 const auto type = on ? hal::ContentType::GAME : hal::ContentType::NONE;
1912 getHwComposer().setContentType(*displayId, type);
1913 } else {
1914 ALOGE("%s: Invalid display token %p", whence, displayToken.get());
1915 }
1916 }));
1917 }
1918
getMaxLayerPictureProfiles(const sp<IBinder> & displayToken,int32_t * outMaxProfiles)1919 status_t SurfaceFlinger::getMaxLayerPictureProfiles(const sp<IBinder>& displayToken,
1920 int32_t* outMaxProfiles) {
1921 const char* const whence = __func__;
1922 auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) {
1923 const ssize_t index = mCurrentState.displays.indexOfKey(displayToken);
1924 if (index < 0) {
1925 ALOGE("%s: Invalid display token %p", whence, displayToken.get());
1926 return 0;
1927 }
1928 const DisplayDeviceState& state = mCurrentState.displays.valueAt(index);
1929 return state.maxLayerPictureProfiles > 0 ? state.maxLayerPictureProfiles
1930 : state.hasPictureProcessing ? 1
1931 : 0;
1932 });
1933 *outMaxProfiles = future.get();
1934 return NO_ERROR;
1935 }
1936
overrideHdrTypes(const sp<IBinder> & displayToken,const std::vector<ui::Hdr> & hdrTypes)1937 status_t SurfaceFlinger::overrideHdrTypes(const sp<IBinder>& displayToken,
1938 const std::vector<ui::Hdr>& hdrTypes) {
1939 Mutex::Autolock lock(mStateLock);
1940
1941 auto display = getDisplayDeviceLocked(displayToken);
1942 if (!display) {
1943 ALOGE("%s: Invalid display token %p", __func__, displayToken.get());
1944 return NAME_NOT_FOUND;
1945 }
1946
1947 display->overrideHdrTypes(hdrTypes);
1948 mScheduler->dispatchHotplug(display->getPhysicalId(), scheduler::Scheduler::Hotplug::Connected);
1949 return NO_ERROR;
1950 }
1951
onPullAtom(const int32_t atomId,std::vector<uint8_t> * pulledData,bool * success)1952 status_t SurfaceFlinger::onPullAtom(const int32_t atomId, std::vector<uint8_t>* pulledData,
1953 bool* success) {
1954 *success = mTimeStats->onPullAtom(atomId, pulledData);
1955 return NO_ERROR;
1956 }
1957
getDisplayedContentSamplingAttributes(const sp<IBinder> & displayToken,ui::PixelFormat * outFormat,ui::Dataspace * outDataspace,uint8_t * outComponentMask) const1958 status_t SurfaceFlinger::getDisplayedContentSamplingAttributes(const sp<IBinder>& displayToken,
1959 ui::PixelFormat* outFormat,
1960 ui::Dataspace* outDataspace,
1961 uint8_t* outComponentMask) const {
1962 if (!outFormat || !outDataspace || !outComponentMask) {
1963 return BAD_VALUE;
1964 }
1965
1966 Mutex::Autolock lock(mStateLock);
1967
1968 const auto displayId = getPhysicalDisplayIdLocked(displayToken);
1969 if (!displayId) {
1970 return NAME_NOT_FOUND;
1971 }
1972
1973 return getHwComposer().getDisplayedContentSamplingAttributes(*displayId, outFormat,
1974 outDataspace, outComponentMask);
1975 }
1976
setDisplayContentSamplingEnabled(const sp<IBinder> & displayToken,bool enable,uint8_t componentMask,uint64_t maxFrames)1977 status_t SurfaceFlinger::setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken,
1978 bool enable, uint8_t componentMask,
1979 uint64_t maxFrames) {
1980 const char* const whence = __func__;
1981 auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) -> status_t {
1982 if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
1983 return getHwComposer().setDisplayContentSamplingEnabled(*displayId, enable,
1984 componentMask, maxFrames);
1985 } else {
1986 ALOGE("%s: Invalid display token %p", whence, displayToken.get());
1987 return NAME_NOT_FOUND;
1988 }
1989 });
1990
1991 return future.get();
1992 }
1993
getDisplayedContentSample(const sp<IBinder> & displayToken,uint64_t maxFrames,uint64_t timestamp,DisplayedFrameStats * outStats) const1994 status_t SurfaceFlinger::getDisplayedContentSample(const sp<IBinder>& displayToken,
1995 uint64_t maxFrames, uint64_t timestamp,
1996 DisplayedFrameStats* outStats) const {
1997 Mutex::Autolock lock(mStateLock);
1998
1999 const auto displayId = getPhysicalDisplayIdLocked(displayToken);
2000 if (!displayId) {
2001 return NAME_NOT_FOUND;
2002 }
2003
2004 return getHwComposer().getDisplayedContentSample(*displayId, maxFrames, timestamp, outStats);
2005 }
2006
getProtectedContentSupport(bool * outSupported) const2007 status_t SurfaceFlinger::getProtectedContentSupport(bool* outSupported) const {
2008 if (!outSupported) {
2009 return BAD_VALUE;
2010 }
2011 *outSupported = getRenderEngine().supportsProtectedContent();
2012 return NO_ERROR;
2013 }
2014
isWideColorDisplay(const sp<IBinder> & displayToken,bool * outIsWideColorDisplay) const2015 status_t SurfaceFlinger::isWideColorDisplay(const sp<IBinder>& displayToken,
2016 bool* outIsWideColorDisplay) const {
2017 if (!displayToken || !outIsWideColorDisplay) {
2018 return BAD_VALUE;
2019 }
2020
2021 Mutex::Autolock lock(mStateLock);
2022 const auto display = getDisplayDeviceLocked(displayToken);
2023 if (!display) {
2024 return NAME_NOT_FOUND;
2025 }
2026
2027 *outIsWideColorDisplay =
2028 display->isPrimary() ? mSupportsWideColor : display->hasWideColorGamut();
2029 return NO_ERROR;
2030 }
2031
getCompositionPreference(Dataspace * outDataspace,ui::PixelFormat * outPixelFormat,Dataspace * outWideColorGamutDataspace,ui::PixelFormat * outWideColorGamutPixelFormat) const2032 status_t SurfaceFlinger::getCompositionPreference(
2033 Dataspace* outDataspace, ui::PixelFormat* outPixelFormat,
2034 Dataspace* outWideColorGamutDataspace,
2035 ui::PixelFormat* outWideColorGamutPixelFormat) const {
2036 *outDataspace = mDefaultCompositionDataspace;
2037 *outPixelFormat = defaultCompositionPixelFormat;
2038 *outWideColorGamutDataspace = mWideColorGamutCompositionDataspace;
2039 *outWideColorGamutPixelFormat = wideColorGamutCompositionPixelFormat;
2040 return NO_ERROR;
2041 }
2042
addRegionSamplingListener(const Rect & samplingArea,const sp<IBinder> & stopLayerHandle,const sp<IRegionSamplingListener> & listener)2043 status_t SurfaceFlinger::addRegionSamplingListener(const Rect& samplingArea,
2044 const sp<IBinder>& stopLayerHandle,
2045 const sp<IRegionSamplingListener>& listener) {
2046 if (!listener || samplingArea == Rect::INVALID_RECT || samplingArea.isEmpty()) {
2047 return BAD_VALUE;
2048 }
2049
2050 // LayerHandle::getLayer promotes the layer object in a binder thread but we will not destroy
2051 // the layer here since the caller has a strong ref to the layer's handle.
2052 const sp<Layer> stopLayer = LayerHandle::getLayer(stopLayerHandle);
2053 mRegionSamplingThread->addListener(samplingArea,
2054 stopLayer ? stopLayer->getSequence() : UNASSIGNED_LAYER_ID,
2055 listener);
2056 return NO_ERROR;
2057 }
2058
removeRegionSamplingListener(const sp<IRegionSamplingListener> & listener)2059 status_t SurfaceFlinger::removeRegionSamplingListener(const sp<IRegionSamplingListener>& listener) {
2060 if (!listener) {
2061 return BAD_VALUE;
2062 }
2063 mRegionSamplingThread->removeListener(listener);
2064 return NO_ERROR;
2065 }
2066
addFpsListener(int32_t taskId,const sp<gui::IFpsListener> & listener)2067 status_t SurfaceFlinger::addFpsListener(int32_t taskId, const sp<gui::IFpsListener>& listener) {
2068 if (!listener) {
2069 return BAD_VALUE;
2070 }
2071
2072 mFpsReporter->addListener(listener, taskId);
2073 return NO_ERROR;
2074 }
2075
removeFpsListener(const sp<gui::IFpsListener> & listener)2076 status_t SurfaceFlinger::removeFpsListener(const sp<gui::IFpsListener>& listener) {
2077 if (!listener) {
2078 return BAD_VALUE;
2079 }
2080 mFpsReporter->removeListener(listener);
2081 return NO_ERROR;
2082 }
2083
addTunnelModeEnabledListener(const sp<gui::ITunnelModeEnabledListener> & listener)2084 status_t SurfaceFlinger::addTunnelModeEnabledListener(
2085 const sp<gui::ITunnelModeEnabledListener>& listener) {
2086 if (!listener) {
2087 return BAD_VALUE;
2088 }
2089
2090 mTunnelModeEnabledReporter->addListener(listener);
2091 return NO_ERROR;
2092 }
2093
removeTunnelModeEnabledListener(const sp<gui::ITunnelModeEnabledListener> & listener)2094 status_t SurfaceFlinger::removeTunnelModeEnabledListener(
2095 const sp<gui::ITunnelModeEnabledListener>& listener) {
2096 if (!listener) {
2097 return BAD_VALUE;
2098 }
2099
2100 mTunnelModeEnabledReporter->removeListener(listener);
2101 return NO_ERROR;
2102 }
2103
getDisplayBrightnessSupport(const sp<IBinder> & displayToken,bool * outSupport) const2104 status_t SurfaceFlinger::getDisplayBrightnessSupport(const sp<IBinder>& displayToken,
2105 bool* outSupport) const {
2106 if (!displayToken || !outSupport) {
2107 return BAD_VALUE;
2108 }
2109
2110 Mutex::Autolock lock(mStateLock);
2111
2112 const auto displayId = getPhysicalDisplayIdLocked(displayToken);
2113 if (!displayId) {
2114 return NAME_NOT_FOUND;
2115 }
2116 *outSupport = getHwComposer().hasDisplayCapability(*displayId, DisplayCapability::BRIGHTNESS);
2117 return NO_ERROR;
2118 }
2119
setDisplayBrightness(const sp<IBinder> & displayToken,const gui::DisplayBrightness & brightness)2120 status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken,
2121 const gui::DisplayBrightness& brightness) {
2122 if (!displayToken) {
2123 return BAD_VALUE;
2124 }
2125
2126 const char* const whence = __func__;
2127 return ftl::Future(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) {
2128 // TODO(b/241285876): Validate that the display is physical instead of failing later.
2129 if (const auto display = getDisplayDeviceLocked(displayToken)) {
2130 const bool supportsDisplayBrightnessCommand =
2131 getHwComposer().getComposer()->isSupported(
2132 Hwc2::Composer::OptionalFeature::DisplayBrightnessCommand);
2133 // If we support applying display brightness as a command, then we also support
2134 // dimming SDR layers.
2135 if (supportsDisplayBrightnessCommand) {
2136 auto compositionDisplay = display->getCompositionDisplay();
2137 float currentDimmingRatio =
2138 compositionDisplay->editState().sdrWhitePointNits /
2139 compositionDisplay->editState().displayBrightnessNits;
2140 static constexpr float kDimmingThreshold = 0.02f;
2141 if (brightness.sdrWhitePointNits == 0.f ||
2142 abs(brightness.sdrWhitePointNits - brightness.displayBrightnessNits) /
2143 brightness.sdrWhitePointNits >=
2144 kDimmingThreshold) {
2145 // to optimize, skip brightness setter if the brightness difference ratio
2146 // is lower than threshold
2147 compositionDisplay
2148 ->setDisplayBrightness(brightness.sdrWhitePointNits,
2149 brightness.displayBrightnessNits);
2150 } else {
2151 compositionDisplay->setDisplayBrightness(brightness.sdrWhitePointNits,
2152 brightness.sdrWhitePointNits);
2153 }
2154
2155 FTL_FAKE_GUARD(kMainThreadContext,
2156 display->stageBrightness(brightness.displayBrightness));
2157 float currentHdrSdrRatio =
2158 compositionDisplay->editState().displayBrightnessNits /
2159 compositionDisplay->editState().sdrWhitePointNits;
2160 FTL_FAKE_GUARD(kMainThreadContext,
2161 display->updateHdrSdrRatioOverlayRatio(currentHdrSdrRatio));
2162
2163 if (brightness.sdrWhitePointNits / brightness.displayBrightnessNits !=
2164 currentDimmingRatio) {
2165 scheduleComposite(FrameHint::kNone);
2166 } else {
2167 scheduleCommit(FrameHint::kNone);
2168 }
2169 return ftl::yield<status_t>(OK);
2170 } else {
2171 return getHwComposer()
2172 .setDisplayBrightness(display->getPhysicalId(),
2173 brightness.displayBrightness,
2174 brightness.displayBrightnessNits,
2175 Hwc2::Composer::DisplayBrightnessOptions{
2176 .applyImmediately = true});
2177 }
2178 } else {
2179 ALOGE("%s: Invalid display token %p", whence, displayToken.get());
2180 return ftl::yield<status_t>(NAME_NOT_FOUND);
2181 }
2182 }))
2183 .then([](ftl::Future<status_t> task) { return task; })
2184 .get();
2185 }
2186
addHdrLayerInfoListener(const sp<IBinder> & displayToken,const sp<gui::IHdrLayerInfoListener> & listener)2187 status_t SurfaceFlinger::addHdrLayerInfoListener(const sp<IBinder>& displayToken,
2188 const sp<gui::IHdrLayerInfoListener>& listener) {
2189 if (!displayToken) {
2190 return BAD_VALUE;
2191 }
2192
2193 Mutex::Autolock lock(mStateLock);
2194
2195 const auto display = getDisplayDeviceLocked(displayToken);
2196 if (!display) {
2197 return NAME_NOT_FOUND;
2198 }
2199 const auto displayId = display->getId();
2200 sp<HdrLayerInfoReporter>& hdrInfoReporter = mHdrLayerInfoListeners[displayId];
2201 if (!hdrInfoReporter) {
2202 hdrInfoReporter = sp<HdrLayerInfoReporter>::make();
2203 }
2204 hdrInfoReporter->addListener(listener);
2205
2206 mAddingHDRLayerInfoListener = true;
2207 return OK;
2208 }
2209
removeHdrLayerInfoListener(const sp<IBinder> & displayToken,const sp<gui::IHdrLayerInfoListener> & listener)2210 status_t SurfaceFlinger::removeHdrLayerInfoListener(
2211 const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener) {
2212 if (!displayToken) {
2213 return BAD_VALUE;
2214 }
2215
2216 Mutex::Autolock lock(mStateLock);
2217
2218 const auto display = getDisplayDeviceLocked(displayToken);
2219 if (!display) {
2220 return NAME_NOT_FOUND;
2221 }
2222 const auto displayId = display->getId();
2223 sp<HdrLayerInfoReporter>& hdrInfoReporter = mHdrLayerInfoListeners[displayId];
2224 if (hdrInfoReporter) {
2225 hdrInfoReporter->removeListener(listener);
2226 }
2227 return OK;
2228 }
2229
notifyPowerBoost(int32_t boostId)2230 status_t SurfaceFlinger::notifyPowerBoost(int32_t boostId) {
2231 using aidl::android::hardware::power::Boost;
2232 Boost powerBoost = static_cast<Boost>(boostId);
2233
2234 if (powerBoost == Boost::INTERACTION) {
2235 mScheduler->onTouchHint();
2236 }
2237
2238 return NO_ERROR;
2239 }
2240
getDisplayDecorationSupport(const sp<IBinder> & displayToken,std::optional<DisplayDecorationSupport> * outSupport) const2241 status_t SurfaceFlinger::getDisplayDecorationSupport(
2242 const sp<IBinder>& displayToken,
2243 std::optional<DisplayDecorationSupport>* outSupport) const {
2244 if (!displayToken || !outSupport) {
2245 return BAD_VALUE;
2246 }
2247
2248 Mutex::Autolock lock(mStateLock);
2249
2250 const auto displayId = getPhysicalDisplayIdLocked(displayToken);
2251 if (!displayId) {
2252 return NAME_NOT_FOUND;
2253 }
2254 getHwComposer().getDisplayDecorationSupport(*displayId, outSupport);
2255 return NO_ERROR;
2256 }
2257
2258 // ----------------------------------------------------------------------------
2259
createDisplayEventConnection(gui::ISurfaceComposer::VsyncSource vsyncSource,EventRegistrationFlags eventRegistration,const sp<IBinder> & layerHandle)2260 sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
2261 gui::ISurfaceComposer::VsyncSource vsyncSource, EventRegistrationFlags eventRegistration,
2262 const sp<IBinder>& layerHandle) {
2263 const auto cycle = [&] {
2264 if (FlagManager::getInstance().deprecate_vsync_sf()) {
2265 ALOGW_IF(vsyncSource == gui::ISurfaceComposer::VsyncSource::eVsyncSourceSurfaceFlinger,
2266 "requested unsupported config eVsyncSourceSurfaceFlinger");
2267 return scheduler::Cycle::Render;
2268 }
2269
2270 return vsyncSource == gui::ISurfaceComposer::VsyncSource::eVsyncSourceSurfaceFlinger
2271 ? scheduler::Cycle::LastComposite
2272 : scheduler::Cycle::Render;
2273 }();
2274 return mScheduler->createDisplayEventConnection(cycle, eventRegistration, layerHandle);
2275 }
2276
scheduleCommit(FrameHint hint,Duration workDurationSlack)2277 void SurfaceFlinger::scheduleCommit(FrameHint hint, Duration workDurationSlack) {
2278 if (hint == FrameHint::kActive) {
2279 mScheduler->resetIdleTimer();
2280 }
2281 mPowerAdvisor->notifyDisplayUpdateImminentAndCpuReset();
2282 mScheduler->scheduleFrame(workDurationSlack);
2283 }
2284
scheduleComposite(FrameHint hint)2285 void SurfaceFlinger::scheduleComposite(FrameHint hint) {
2286 mMustComposite = true;
2287 scheduleCommit(hint);
2288 }
2289
scheduleRepaint()2290 void SurfaceFlinger::scheduleRepaint() {
2291 mGeometryDirty = true;
2292 scheduleComposite(FrameHint::kActive);
2293 }
2294
scheduleSample()2295 void SurfaceFlinger::scheduleSample() {
2296 static_cast<void>(mScheduler->schedule([this] { sample(); }));
2297 }
2298
onComposerHalVsync(hal::HWDisplayId hwcDisplayId,int64_t timestamp,std::optional<hal::VsyncPeriodNanos> vsyncPeriod)2299 void SurfaceFlinger::onComposerHalVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp,
2300 std::optional<hal::VsyncPeriodNanos> vsyncPeriod) {
2301 SFTRACE_NAME(vsyncPeriod
2302 ? ftl::Concat(__func__, ' ', hwcDisplayId, ' ', *vsyncPeriod, "ns").c_str()
2303 : ftl::Concat(__func__, ' ', hwcDisplayId).c_str());
2304
2305 Mutex::Autolock lock(mStateLock);
2306 if (const auto displayIdOpt = getHwComposer().onVsync(hwcDisplayId, timestamp)) {
2307 if (mScheduler->addResyncSample(*displayIdOpt, timestamp, vsyncPeriod)) {
2308 // period flushed
2309 mScheduler->modulateVsync(displayIdOpt, &VsyncModulator::onRefreshRateChangeCompleted);
2310 }
2311 }
2312 }
2313
onComposerHalHotplugEvent(hal::HWDisplayId hwcDisplayId,DisplayHotplugEvent event)2314 void SurfaceFlinger::onComposerHalHotplugEvent(hal::HWDisplayId hwcDisplayId,
2315 DisplayHotplugEvent event) {
2316 if (event == DisplayHotplugEvent::CONNECTED || event == DisplayHotplugEvent::DISCONNECTED) {
2317 const HWComposer::HotplugEvent hotplugEvent = event == DisplayHotplugEvent::CONNECTED
2318 ? HWComposer::HotplugEvent::Connected
2319 : HWComposer::HotplugEvent::Disconnected;
2320 {
2321 std::lock_guard<std::mutex> lock(mHotplugMutex);
2322 mPendingHotplugEvents.push_back(HotplugEvent{hwcDisplayId, hotplugEvent});
2323 }
2324
2325 if (mScheduler) {
2326 mScheduler->scheduleConfigure();
2327 }
2328
2329 return;
2330 }
2331
2332 if (event < DisplayHotplugEvent::ERROR_LINK_UNSTABLE) {
2333 // This needs to be kept in sync with DisplayHotplugEvent to prevent passing new errors.
2334 const auto errorCode = static_cast<int32_t>(event);
2335 ALOGW("%s: Unknown hotplug error %d for hwcDisplayId %" PRIu64, __func__, errorCode,
2336 hwcDisplayId);
2337 return;
2338 }
2339
2340 if (event == DisplayHotplugEvent::ERROR_LINK_UNSTABLE) {
2341 if (!FlagManager::getInstance().display_config_error_hal()) {
2342 return;
2343 }
2344 {
2345 std::lock_guard<std::mutex> lock(mHotplugMutex);
2346 mPendingHotplugEvents.push_back(
2347 HotplugEvent{hwcDisplayId, HWComposer::HotplugEvent::LinkUnstable});
2348 }
2349 if (mScheduler) {
2350 mScheduler->scheduleConfigure();
2351 }
2352 // do not return to also report the error.
2353 }
2354
2355 // TODO(b/311403559): use enum type instead of int
2356 const auto errorCode = static_cast<int32_t>(event);
2357 ALOGD("%s: Hotplug error %d for hwcDisplayId %" PRIu64, __func__, errorCode, hwcDisplayId);
2358 mScheduler->dispatchHotplugError(errorCode);
2359 }
2360
onComposerHalVsyncPeriodTimingChanged(hal::HWDisplayId,const hal::VsyncPeriodChangeTimeline & timeline)2361 void SurfaceFlinger::onComposerHalVsyncPeriodTimingChanged(
2362 hal::HWDisplayId, const hal::VsyncPeriodChangeTimeline& timeline) {
2363 Mutex::Autolock lock(mStateLock);
2364 mScheduler->onNewVsyncPeriodChangeTimeline(timeline);
2365
2366 if (timeline.refreshRequired) {
2367 scheduleComposite(FrameHint::kNone);
2368 }
2369 }
2370
onComposerHalSeamlessPossible(hal::HWDisplayId)2371 void SurfaceFlinger::onComposerHalSeamlessPossible(hal::HWDisplayId) {
2372 // TODO(b/142753666): use constraints when calling to setActiveModeWithConstraints and
2373 // use this callback to know when to retry in case of SEAMLESS_NOT_POSSIBLE.
2374 }
2375
onComposerHalRefresh(hal::HWDisplayId)2376 void SurfaceFlinger::onComposerHalRefresh(hal::HWDisplayId) {
2377 Mutex::Autolock lock(mStateLock);
2378 scheduleComposite(FrameHint::kNone);
2379 }
2380
onComposerHalVsyncIdle(hal::HWDisplayId)2381 void SurfaceFlinger::onComposerHalVsyncIdle(hal::HWDisplayId) {
2382 SFTRACE_CALL();
2383 mScheduler->forceNextResync();
2384 }
2385
onRefreshRateChangedDebug(const RefreshRateChangedDebugData & data)2386 void SurfaceFlinger::onRefreshRateChangedDebug(const RefreshRateChangedDebugData& data) {
2387 SFTRACE_CALL();
2388 const char* const whence = __func__;
2389 static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(
2390 kMainThreadContext) {
2391 if (const auto displayIdOpt = getHwComposer().toPhysicalDisplayId(data.display)) {
2392 if (const auto display = getDisplayDeviceLocked(*displayIdOpt)) {
2393 const Fps refreshRate = Fps::fromPeriodNsecs(
2394 getHwComposer().getComposer()->isVrrSupported() ? data.refreshPeriodNanos
2395 : data.vsyncPeriodNanos);
2396 SFTRACE_FORMAT("%s refresh rate = %d", whence, refreshRate.getIntValue());
2397
2398 const auto renderRate = mDisplayModeController.getActiveMode(*displayIdOpt).fps;
2399 constexpr bool kSetByHwc = true;
2400 display->updateRefreshRateOverlayRate(refreshRate, renderRate, kSetByHwc);
2401 }
2402 }
2403 }));
2404 }
2405
onComposerHalHdcpLevelsChanged(hal::HWDisplayId hwcDisplayId,const HdcpLevels & levels)2406 void SurfaceFlinger::onComposerHalHdcpLevelsChanged(hal::HWDisplayId hwcDisplayId,
2407 const HdcpLevels& levels) {
2408 if (FlagManager::getInstance().hdcp_level_hal()) {
2409 // TODO(b/362270040): propagate enum constants
2410 const int32_t maxLevel = static_cast<int32_t>(levels.maxLevel);
2411 const int32_t connectedLevel = static_cast<int32_t>(levels.connectedLevel);
2412 ALOGD("%s: HDCP levels changed (connected=%d, max=%d) for hwcDisplayId %" PRIu64, __func__,
2413 connectedLevel, maxLevel, hwcDisplayId);
2414 updateHdcpLevels(hwcDisplayId, connectedLevel, maxLevel);
2415 }
2416 }
2417
configure()2418 void SurfaceFlinger::configure() {
2419 Mutex::Autolock lock(mStateLock);
2420 if (configureLocked()) {
2421 setTransactionFlags(eDisplayTransactionNeeded);
2422 }
2423 }
2424
updateLayerHistory(nsecs_t now)2425 void SurfaceFlinger::updateLayerHistory(nsecs_t now) {
2426 for (const auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) {
2427 using Changes = frontend::RequestedLayerState::Changes;
2428 if (snapshot->path.isClone()) {
2429 continue;
2430 }
2431
2432 const bool updateSmallDirty = FlagManager::getInstance().enable_small_area_detection() &&
2433 ((snapshot->clientChanges & layer_state_t::eSurfaceDamageRegionChanged) ||
2434 snapshot->changes.any(Changes::Geometry));
2435
2436 const bool hasChanges =
2437 snapshot->changes.any(Changes::FrameRate | Changes::Buffer | Changes::Animation |
2438 Changes::Geometry | Changes::Visibility) ||
2439 (snapshot->clientChanges & layer_state_t::eDefaultFrameRateCompatibilityChanged) !=
2440 0;
2441
2442 if (!updateSmallDirty && !hasChanges) {
2443 continue;
2444 }
2445
2446 auto it = mLegacyLayers.find(snapshot->sequence);
2447 LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
2448 "Couldn't find layer object for %s",
2449 snapshot->getDebugString().c_str());
2450
2451 if (updateSmallDirty) {
2452 // Update small dirty flag while surface damage region or geometry changed
2453 it->second->setIsSmallDirty(snapshot.get());
2454 }
2455
2456 if (!hasChanges) {
2457 continue;
2458 }
2459
2460 const auto layerProps = scheduler::LayerProps{
2461 .visible = snapshot->isVisible,
2462 .bounds = snapshot->geomLayerBounds,
2463 .transform = snapshot->geomLayerTransform,
2464 .setFrameRateVote = snapshot->frameRate,
2465 .frameRateSelectionPriority = snapshot->frameRateSelectionPriority,
2466 .isSmallDirty = snapshot->isSmallDirty,
2467 .isFrontBuffered = snapshot->isFrontBuffered(),
2468 };
2469
2470 if (snapshot->changes.any(Changes::Geometry | Changes::Visibility)) {
2471 mScheduler->setLayerProperties(snapshot->sequence, layerProps);
2472 }
2473
2474 if (snapshot->clientChanges & layer_state_t::eDefaultFrameRateCompatibilityChanged) {
2475 mScheduler->setDefaultFrameRateCompatibility(snapshot->sequence,
2476 snapshot->defaultFrameRateCompatibility);
2477 }
2478
2479 if (snapshot->changes.test(Changes::Animation)) {
2480 it->second->recordLayerHistoryAnimationTx(layerProps, now);
2481 }
2482
2483 if (snapshot->changes.test(Changes::FrameRate)) {
2484 it->second->setFrameRateForLayerTree(snapshot->frameRate, layerProps, now);
2485 }
2486
2487 if (snapshot->changes.test(Changes::Buffer)) {
2488 it->second->recordLayerHistoryBufferUpdate(layerProps, now);
2489 }
2490 }
2491 }
2492
updateLayerSnapshots(VsyncId vsyncId,nsecs_t frameTimeNs,bool flushTransactions,bool & outTransactionsAreEmpty)2493 bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs,
2494 bool flushTransactions, bool& outTransactionsAreEmpty)
2495 EXCLUDES(mStateLock) {
2496 using Changes = frontend::RequestedLayerState::Changes;
2497 SFTRACE_CALL();
2498 SFTRACE_NAME_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Transaction Handling");
2499 frontend::Update update;
2500 if (flushTransactions) {
2501 SFTRACE_NAME("TransactionHandler:flushTransactions");
2502 // Locking:
2503 // 1. to prevent onHandleDestroyed from being called while the state lock is held,
2504 // we must keep a copy of the transactions (specifically the composer
2505 // states) around outside the scope of the lock.
2506 // 2. Transactions and created layers do not share a lock. To prevent applying
2507 // transactions with layers still in the createdLayer queue, collect the transactions
2508 // before committing the created layers.
2509 // 3. Transactions can only be flushed after adding layers, since the layer can be a newly
2510 // created one
2511 mTransactionHandler.collectTransactions();
2512 {
2513 // TODO(b/238781169) lockless queue this and keep order.
2514 std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
2515 update.legacyLayers = std::move(mCreatedLayers);
2516 mCreatedLayers.clear();
2517 update.newLayers = std::move(mNewLayers);
2518 mNewLayers.clear();
2519 update.layerCreationArgs = std::move(mNewLayerArgs);
2520 mNewLayerArgs.clear();
2521 update.destroyedHandles = std::move(mDestroyedHandles);
2522 mDestroyedHandles.clear();
2523 }
2524
2525 size_t addedLayers = update.newLayers.size();
2526 mLayerLifecycleManager.addLayers(std::move(update.newLayers));
2527 update.transactions = mTransactionHandler.flushTransactions();
2528 ftl::Flags<adpf::Workload> committedWorkload;
2529 for (auto& transaction : update.transactions) {
2530 committedWorkload |= transaction.workloadHint;
2531 }
2532 SFTRACE_INSTANT_FOR_TRACK(WorkloadTracer::TRACK_NAME,
2533 ftl::Concat("Layers: +", addedLayers, " -",
2534 update.destroyedHandles.size(),
2535 " txns:", update.transactions.size())
2536 .c_str());
2537
2538 mPowerAdvisor->setCommittedWorkload(committedWorkload);
2539 if (mTransactionTracing) {
2540 mTransactionTracing->addCommittedTransactions(ftl::to_underlying(vsyncId), frameTimeNs,
2541 update, mFrontEndDisplayInfos,
2542 mFrontEndDisplayInfosChanged);
2543 }
2544 mLayerLifecycleManager.applyTransactions(update.transactions);
2545 mLayerLifecycleManager.onHandlesDestroyed(update.destroyedHandles);
2546 for (auto& legacyLayer : update.legacyLayers) {
2547 mLegacyLayers[legacyLayer->sequence] = legacyLayer;
2548 }
2549 mLayerHierarchyBuilder.update(mLayerLifecycleManager);
2550 }
2551
2552 // Keep a copy of the drawing state (that is going to be overwritten
2553 // by commitTransactionsLocked) outside of mStateLock so that the side
2554 // effects of the State assignment don't happen with mStateLock held,
2555 // which can cause deadlocks.
2556 State drawingState(mDrawingState);
2557 Mutex::Autolock lock(mStateLock);
2558 bool mustComposite = false;
2559 mustComposite |= applyAndCommitDisplayTransactionStatesLocked(update.transactions);
2560
2561 {
2562 SFTRACE_NAME("LayerSnapshotBuilder:update");
2563 frontend::LayerSnapshotBuilder::Args
2564 args{.root = mLayerHierarchyBuilder.getHierarchy(),
2565 .layerLifecycleManager = mLayerLifecycleManager,
2566 .includeMetadata = mCompositionEngine->getFeatureFlags().test(
2567 compositionengine::Feature::kSnapshotLayerMetadata),
2568 .displays = mFrontEndDisplayInfos,
2569 .displayChanges = mFrontEndDisplayInfosChanged,
2570 .globalShadowSettings = mDrawingState.globalShadowSettings,
2571 .supportsBlur = mSupportsBlur,
2572 .forceFullDamage = mForceFullDamage,
2573 .supportedLayerGenericMetadata =
2574 getHwComposer().getSupportedLayerGenericMetadata(),
2575 .genericLayerMetadataKeyMap = getGenericLayerMetadataKeyMap(),
2576 .skipRoundCornersWhenProtected =
2577 !getRenderEngine().supportsProtectedContent()};
2578 mLayerSnapshotBuilder.update(args);
2579 }
2580
2581 if (mLayerLifecycleManager.getGlobalChanges().any(Changes::Geometry | Changes::Input |
2582 Changes::Hierarchy | Changes::Visibility)) {
2583 mUpdateInputInfo = true;
2584 }
2585 if (mLayerLifecycleManager.getGlobalChanges().any(Changes::VisibleRegion | Changes::Hierarchy |
2586 Changes::Visibility | Changes::Geometry)) {
2587 mVisibleRegionsDirty = true;
2588 }
2589 if (mLayerLifecycleManager.getGlobalChanges().any(Changes::Hierarchy | Changes::FrameRate)) {
2590 // The frame rate of attached choreographers can only change as a result of a
2591 // FrameRate change (including when Hierarchy changes).
2592 mUpdateAttachedChoreographer = true;
2593 }
2594 outTransactionsAreEmpty = mLayerLifecycleManager.getGlobalChanges().get() == 0;
2595 if (FlagManager::getInstance().vrr_bugfix_24q4()) {
2596 mustComposite |= mLayerLifecycleManager.getGlobalChanges().any(
2597 frontend::RequestedLayerState::kMustComposite);
2598 } else {
2599 mustComposite |= mLayerLifecycleManager.getGlobalChanges().get() != 0;
2600 }
2601
2602 bool newDataLatched = false;
2603 SFTRACE_NAME("DisplayCallbackAndStatsUpdates");
2604 mustComposite |= applyTransactionsLocked(update.transactions);
2605 traverseLegacyLayers([&](Layer* layer) { layer->commitTransaction(); });
2606 const nsecs_t latchTime = systemTime();
2607 bool unused = false;
2608
2609 for (auto& layer : mLayerLifecycleManager.getLayers()) {
2610 if (layer->changes.test(frontend::RequestedLayerState::Changes::Created) &&
2611 layer->bgColorLayer) {
2612 sp<Layer> bgColorLayer = getFactory().createEffectLayer(
2613 LayerCreationArgs(this, nullptr, layer->name,
2614 ISurfaceComposerClient::eFXSurfaceEffect, LayerMetadata(),
2615 std::make_optional(layer->id), true));
2616 mLegacyLayers[bgColorLayer->sequence] = bgColorLayer;
2617 }
2618 const bool willReleaseBufferOnLatch = layer->willReleaseBufferOnLatch();
2619
2620 auto it = mLegacyLayers.find(layer->id);
2621 if (it == mLegacyLayers.end() &&
2622 layer->changes.test(frontend::RequestedLayerState::Changes::Destroyed)) {
2623 // Layer handle was created and immediately destroyed. It was destroyed before it
2624 // was added to the map.
2625 continue;
2626 }
2627
2628 LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
2629 "Couldnt find layer object for %s",
2630 layer->getDebugString().c_str());
2631 if (!layer->hasReadyFrame() && !willReleaseBufferOnLatch) {
2632 if (!it->second->hasBuffer()) {
2633 // The last latch time is used to classify a missed frame as buffer stuffing
2634 // instead of a missed frame. This is used to identify scenarios where we
2635 // could not latch a buffer or apply a transaction due to backpressure.
2636 // We only update the latch time for buffer less layers here, the latch time
2637 // is updated for buffer layers when the buffer is latched.
2638 it->second->updateLastLatchTime(latchTime);
2639 }
2640 continue;
2641 }
2642
2643 const bool bgColorOnly =
2644 !layer->externalTexture && (layer->bgColorLayerId != UNASSIGNED_LAYER_ID);
2645 if (willReleaseBufferOnLatch) {
2646 mLayersWithBuffersRemoved.emplace(it->second);
2647 }
2648 it->second->latchBufferImpl(unused, latchTime, bgColorOnly);
2649 newDataLatched = true;
2650
2651 frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(it->second->sequence);
2652 gui::GameMode gameMode = (snapshot) ? snapshot->gameMode : gui::GameMode::Unsupported;
2653 mLayersWithQueuedFrames.emplace(it->second, gameMode);
2654 }
2655
2656 updateLayerHistory(latchTime);
2657 mLayerSnapshotBuilder.forEachSnapshot([&](const frontend::LayerSnapshot& snapshot) {
2658 // update output's dirty region if a snapshot is visible and its
2659 // content is dirty or if a snapshot recently became invisible
2660 if ((snapshot.isVisible && snapshot.contentDirty) ||
2661 (!snapshot.isVisible && snapshot.changes.test(Changes::Visibility))) {
2662 Region visibleReg;
2663 visibleReg.set(snapshot.transformedBoundsWithoutTransparentRegion);
2664 invalidateLayerStack(snapshot.outputFilter, visibleReg);
2665 }
2666 });
2667
2668 for (auto& destroyedLayer : mLayerLifecycleManager.getDestroyedLayers()) {
2669 mLegacyLayers.erase(destroyedLayer->id);
2670 }
2671
2672 {
2673 SFTRACE_NAME("LayerLifecycleManager:commitChanges");
2674 mLayerLifecycleManager.commitChanges();
2675 }
2676
2677 // enter boot animation on first buffer latch
2678 if (CC_UNLIKELY(mBootStage == BootStage::BOOTLOADER && newDataLatched)) {
2679 ALOGI("Enter boot animation");
2680 mBootStage = BootStage::BOOTANIMATION;
2681 }
2682
2683 mustComposite |= (getTransactionFlags() & ~eTransactionFlushNeeded) || newDataLatched;
2684 if (mustComposite) {
2685 commitTransactions();
2686 }
2687
2688 return mustComposite;
2689 }
2690
commit(PhysicalDisplayId pacesetterId,const scheduler::FrameTargets & frameTargets)2691 bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId,
2692 const scheduler::FrameTargets& frameTargets) EXCLUDES(mStateLock) {
2693 const scheduler::FrameTarget& pacesetterFrameTarget = *frameTargets.get(pacesetterId)->get();
2694
2695 const VsyncId vsyncId = pacesetterFrameTarget.vsyncId();
2696 SFTRACE_NAME(ftl::Concat(__func__, ' ', ftl::to_underlying(vsyncId)).c_str());
2697
2698 if (pacesetterFrameTarget.didMissFrame()) {
2699 mTimeStats->incrementMissedFrames();
2700 }
2701
2702 // If a mode set is pending and the fence hasn't fired yet, wait for the next commit.
2703 if (std::any_of(frameTargets.begin(), frameTargets.end(),
2704 [this](const auto& pair) FTL_FAKE_GUARD(kMainThreadContext) {
2705 const auto [displayId, target] = pair;
2706 return target->isFramePending() &&
2707 mDisplayModeController.isModeSetPending(displayId);
2708 })) {
2709 mScheduler->scheduleFrame();
2710 return false;
2711 }
2712
2713 {
2714 Mutex::Autolock lock(mStateLock);
2715
2716 for (const auto [displayId, _] : frameTargets) {
2717 if (mDisplayModeController.isModeSetPending(displayId)) {
2718 if (!finalizeDisplayModeChange(displayId)) {
2719 mScheduler->scheduleFrame();
2720 return false;
2721 }
2722 }
2723 }
2724 }
2725
2726 if (pacesetterFrameTarget.wouldBackpressureHwc()) {
2727 if (mBackpressureGpuComposition || pacesetterFrameTarget.didMissHwcFrame()) {
2728 if (FlagManager::getInstance().vrr_config()) {
2729 mScheduler->getVsyncSchedule()->getTracker().onFrameMissed(
2730 pacesetterFrameTarget.expectedPresentTime());
2731 }
2732 const Duration slack = FlagManager::getInstance().allow_n_vsyncs_in_targeter()
2733 ? TimePoint::now() - pacesetterFrameTarget.frameBeginTime()
2734 : Duration::fromNs(0);
2735 scheduleCommit(FrameHint::kNone, slack);
2736 return false;
2737 }
2738 }
2739 SFTRACE_NAME_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Commit");
2740 const Period vsyncPeriod = mScheduler->getVsyncSchedule()->period();
2741
2742 // Save this once per commit + composite to ensure consistency
2743 // TODO (b/240619471): consider removing active display check once AOD is fixed
2744 const auto activeDisplay = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(mActiveDisplayId));
2745 mPowerHintSessionEnabled = mPowerAdvisor->usePowerHintSession() && activeDisplay &&
2746 activeDisplay->getPowerMode() == hal::PowerMode::ON;
2747 if (mPowerHintSessionEnabled) {
2748 mPowerAdvisor->setCommitStart(pacesetterFrameTarget.frameBeginTime());
2749 mPowerAdvisor->setExpectedPresentTime(pacesetterFrameTarget.expectedPresentTime());
2750
2751 // Frame delay is how long we should have minus how long we actually have.
2752 const Duration idealSfWorkDuration =
2753 mScheduler->vsyncModulator().getVsyncConfig().sfWorkDuration;
2754 const Duration frameDelay =
2755 idealSfWorkDuration - pacesetterFrameTarget.expectedFrameDuration();
2756
2757 mPowerAdvisor->setFrameDelay(frameDelay);
2758 mPowerAdvisor->setTotalFrameTargetWorkDuration(idealSfWorkDuration);
2759
2760 const Period idealVsyncPeriod =
2761 mDisplayModeController.getActiveMode(pacesetterId).fps.getPeriod();
2762 mPowerAdvisor->updateTargetWorkDuration(idealVsyncPeriod);
2763 }
2764
2765 if (mRefreshRateOverlaySpinner || mHdrSdrRatioOverlay) {
2766 Mutex::Autolock lock(mStateLock);
2767 if (const auto display = getDefaultDisplayDeviceLocked()) {
2768 display->animateOverlay();
2769 }
2770 }
2771
2772 // Composite if transactions were committed, or if requested by HWC.
2773 bool mustComposite = mMustComposite.exchange(false);
2774 {
2775 mFrameTimeline->setSfWakeUp(ftl::to_underlying(vsyncId),
2776 pacesetterFrameTarget.frameBeginTime().ns(),
2777 Fps::fromPeriodNsecs(vsyncPeriod.ns()),
2778 mScheduler->getPacesetterRefreshRate());
2779
2780 const bool flushTransactions = clearTransactionFlags(eTransactionFlushNeeded);
2781 bool transactionsAreEmpty = false;
2782 mustComposite |= updateLayerSnapshots(vsyncId, pacesetterFrameTarget.frameBeginTime().ns(),
2783 flushTransactions, transactionsAreEmpty);
2784
2785 // Tell VsyncTracker that we are going to present this frame before scheduling
2786 // setTransactionFlags which will schedule another SF frame. This was if the tracker
2787 // needs to adjust the vsync timeline, it will be done before the next frame.
2788 if (FlagManager::getInstance().vrr_config() && mustComposite) {
2789 mScheduler->getVsyncSchedule()
2790 ->getTracker()
2791 .onFrameBegin(pacesetterFrameTarget.expectedPresentTime(),
2792 pacesetterFrameTarget.lastSignaledFrameTime());
2793 }
2794 if (transactionFlushNeeded()) {
2795 setTransactionFlags(eTransactionFlushNeeded);
2796 }
2797
2798 // This has to be called after latchBuffers because we want to include the layers that have
2799 // been latched in the commit callback
2800 if (transactionsAreEmpty) {
2801 // Invoke empty transaction callbacks early.
2802 mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
2803 } else {
2804 // Invoke OnCommit callbacks.
2805 mTransactionCallbackInvoker.sendCallbacks(true /* onCommitOnly */);
2806 }
2807 }
2808
2809 // Layers need to get updated (in the previous line) before we can use them for
2810 // choosing the refresh rate.
2811 // Hold mStateLock as chooseRefreshRateForContent promotes wp<Layer> to sp<Layer>
2812 // and may eventually call to ~Layer() if it holds the last reference
2813 {
2814 SFTRACE_NAME_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Refresh Rate Selection");
2815 bool updateAttachedChoreographer = mUpdateAttachedChoreographer;
2816 mUpdateAttachedChoreographer = false;
2817
2818 Mutex::Autolock lock(mStateLock);
2819 mScheduler->chooseRefreshRateForContent(&mLayerHierarchyBuilder.getHierarchy(),
2820 updateAttachedChoreographer);
2821
2822 initiateDisplayModeChanges();
2823 }
2824
2825 updateCursorAsync();
2826 if (!mustComposite) {
2827 updateInputFlinger(vsyncId, pacesetterFrameTarget.frameBeginTime());
2828 }
2829 doActiveLayersTracingIfNeeded(false, mVisibleRegionsDirty,
2830 pacesetterFrameTarget.frameBeginTime(), vsyncId);
2831
2832 mLastCommittedVsyncId = vsyncId;
2833
2834 persistDisplayBrightness(mustComposite);
2835
2836 return mustComposite && CC_LIKELY(mBootStage != BootStage::BOOTLOADER);
2837 }
2838
composite(PhysicalDisplayId pacesetterId,const scheduler::FrameTargeters & frameTargeters)2839 CompositeResultsPerDisplay SurfaceFlinger::composite(
2840 PhysicalDisplayId pacesetterId, const scheduler::FrameTargeters& frameTargeters) {
2841 SFTRACE_ASYNC_FOR_TRACK_BEGIN(WorkloadTracer::TRACK_NAME, "Composition",
2842 WorkloadTracer::COMPOSITION_TRACE_COOKIE);
2843 const scheduler::FrameTarget& pacesetterTarget =
2844 frameTargeters.get(pacesetterId)->get()->target();
2845
2846 const VsyncId vsyncId = pacesetterTarget.vsyncId();
2847 SFTRACE_NAME(ftl::Concat(__func__, ' ', ftl::to_underlying(vsyncId)).c_str());
2848
2849 compositionengine::CompositionRefreshArgs refreshArgs;
2850 refreshArgs.powerCallback = this;
2851 const auto& displays = FTL_FAKE_GUARD(mStateLock, mDisplays);
2852 refreshArgs.outputs.reserve(displays.size());
2853
2854 // Track layer stacks of physical displays that might be added to CompositionEngine
2855 // output. Layer stacks are not tracked in Display when we iterate through
2856 // frameTargeters. Cross-referencing layer stacks allows us to filter out displays
2857 // by ID with duplicate layer stacks before adding them to CompositionEngine output.
2858 ui::DisplayMap<PhysicalDisplayId, ui::LayerStack> physicalDisplayLayerStacks;
2859 for (auto& [_, display] : displays) {
2860 const auto id = asPhysicalDisplayId(display->getDisplayIdVariant());
2861 if (id && frameTargeters.contains(*id)) {
2862 physicalDisplayLayerStacks.try_emplace(*id, display->getLayerStack());
2863 }
2864 }
2865
2866 // Tracks layer stacks of displays that are added to CompositionEngine output.
2867 ui::DisplayMap<ui::LayerStack, ftl::Unit> outputLayerStacks;
2868 auto isUniqueOutputLayerStack = [&outputLayerStacks](DisplayId id, ui::LayerStack layerStack) {
2869 if (FlagManager::getInstance().reject_dupe_layerstacks()) {
2870 if (layerStack != ui::INVALID_LAYER_STACK && outputLayerStacks.contains(layerStack)) {
2871 // TODO: remove log and DisplayId from params once reject_dupe_layerstacks flag is
2872 // removed
2873 ALOGD("Existing layer stack ID %d output to another display %" PRIu64
2874 ", dropping display from outputs",
2875 layerStack.id, id.value);
2876 return false;
2877 }
2878 }
2879
2880 outputLayerStacks.try_emplace(layerStack);
2881 return true;
2882 };
2883
2884 // Add outputs for physical displays.
2885 for (const auto& [id, targeter] : frameTargeters) {
2886 ftl::FakeGuard guard(mStateLock);
2887
2888 if (const auto display = getCompositionDisplayLocked(id)) {
2889 const auto layerStack = physicalDisplayLayerStacks.get(id)->get();
2890 if (isUniqueOutputLayerStack(display->getId(), layerStack)) {
2891 refreshArgs.outputs.push_back(display);
2892 }
2893 }
2894
2895 refreshArgs.frameTargets.try_emplace(id, &targeter->target());
2896 }
2897
2898 std::vector<DisplayId> displayIds;
2899 for (const auto& [_, display] : displays) {
2900 displayIds.push_back(display->getId());
2901 display->tracePowerMode();
2902
2903 // Add outputs for virtual displays.
2904 if (display->isVirtual()) {
2905 const Fps refreshRate = display->getAdjustedRefreshRate();
2906
2907 if (!refreshRate.isValid() ||
2908 mScheduler->isVsyncInPhase(pacesetterTarget.frameBeginTime(), refreshRate)) {
2909 if (isUniqueOutputLayerStack(display->getId(), display->getLayerStack())) {
2910 refreshArgs.outputs.push_back(display->getCompositionDisplay());
2911 }
2912 }
2913 }
2914 }
2915 mPowerAdvisor->setDisplays(displayIds);
2916
2917 const bool updateTaskMetadata = mCompositionEngine->getFeatureFlags().test(
2918 compositionengine::Feature::kSnapshotLayerMetadata);
2919
2920 refreshArgs.bufferIdsToUncache = std::move(mBufferIdsToUncache);
2921 refreshArgs.outputColorSetting = mDisplayColorSetting;
2922 refreshArgs.forceOutputColorMode = mForceColorMode;
2923
2924 refreshArgs.updatingOutputGeometryThisFrame = mVisibleRegionsDirty;
2925 refreshArgs.updatingGeometryThisFrame = mGeometryDirty.exchange(false) ||
2926 mVisibleRegionsDirty || mDrawingState.colorMatrixChanged;
2927 refreshArgs.internalDisplayRotationFlags = getActiveDisplayRotationFlags();
2928
2929 if (CC_UNLIKELY(mDrawingState.colorMatrixChanged)) {
2930 refreshArgs.colorTransformMatrix = mDrawingState.colorMatrix;
2931 mDrawingState.colorMatrixChanged = false;
2932 }
2933
2934 refreshArgs.devOptForceClientComposition = mDebugDisableHWC;
2935
2936 if (mDebugFlashDelay != 0) {
2937 refreshArgs.devOptForceClientComposition = true;
2938 refreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::milliseconds(mDebugFlashDelay);
2939 }
2940
2941 // TODO(b/255601557) Update frameInterval per display
2942 refreshArgs.frameInterval =
2943 mScheduler->getNextFrameInterval(pacesetterId, pacesetterTarget.expectedPresentTime());
2944 const auto scheduledFrameResultOpt = mScheduler->getScheduledFrameResult();
2945 const auto scheduledFrameTimeOpt = scheduledFrameResultOpt
2946 ? std::optional{scheduledFrameResultOpt->callbackTime}
2947 : std::nullopt;
2948 refreshArgs.scheduledFrameTime = scheduledFrameTimeOpt;
2949 refreshArgs.hasTrustedPresentationListener = mNumTrustedPresentationListeners > 0;
2950 // Store the present time just before calling to the composition engine so we could notify
2951 // the scheduler.
2952 const auto presentTime = systemTime();
2953
2954 constexpr bool kCursorOnly = false;
2955 const auto layers = moveSnapshotsToCompositionArgs(refreshArgs, kCursorOnly);
2956
2957 if (!mVisibleRegionsDirty) {
2958 for (const auto& [token, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
2959 auto compositionDisplay = display->getCompositionDisplay();
2960 if (!compositionDisplay->getState().isEnabled) continue;
2961 for (const auto* outputLayer : compositionDisplay->getOutputLayersOrderedByZ()) {
2962 if (outputLayer->getLayerFE().getCompositionState() == nullptr) {
2963 // This is unexpected but instead of crashing, capture traces to disk
2964 // and recover gracefully by forcing CE to rebuild layer stack.
2965 ALOGE("Output layer %s for display %s %" PRIu64 " has a null "
2966 "snapshot. Forcing mVisibleRegionsDirty",
2967 outputLayer->getLayerFE().getDebugName(),
2968 compositionDisplay->getName().c_str(), compositionDisplay->getId().value);
2969
2970 TransactionTraceWriter::getInstance().invoke(__func__, /* overwrite= */ false);
2971 mVisibleRegionsDirty = true;
2972 refreshArgs.updatingOutputGeometryThisFrame = mVisibleRegionsDirty;
2973 refreshArgs.updatingGeometryThisFrame = mVisibleRegionsDirty;
2974 }
2975 }
2976 }
2977 }
2978
2979 refreshArgs.refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
2980 for (auto& [layer, layerFE] : layers) {
2981 layer->onPreComposition(refreshArgs.refreshStartTime);
2982 }
2983
2984 for (auto& [layer, layerFE] : layers) {
2985 attachReleaseFenceFutureToLayer(layer, layerFE,
2986 layerFE->mSnapshot->outputFilter.layerStack);
2987 }
2988
2989 refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
2990 for (auto& [layer, _] : mLayersWithQueuedFrames) {
2991 if (const auto& layerFE =
2992 layer->getCompositionEngineLayerFE({static_cast<uint32_t>(layer->sequence)})) {
2993 refreshArgs.layersWithQueuedFrames.push_back(layerFE);
2994 // Some layers are not displayed and do not yet have a future release fence
2995 if (layerFE->getReleaseFencePromiseStatus() ==
2996 LayerFE::ReleaseFencePromiseStatus::UNINITIALIZED ||
2997 layerFE->getReleaseFencePromiseStatus() ==
2998 LayerFE::ReleaseFencePromiseStatus::FULFILLED) {
2999 // layerStack is invalid because layer is not on a display
3000 attachReleaseFenceFutureToLayer(layer.get(), layerFE.get(),
3001 ui::INVALID_LAYER_STACK);
3002 }
3003 }
3004 }
3005
3006 mCompositionEngine->present(refreshArgs);
3007 ftl::Flags<adpf::Workload> compositedWorkload;
3008 if (refreshArgs.updatingGeometryThisFrame || refreshArgs.updatingOutputGeometryThisFrame) {
3009 compositedWorkload |= adpf::Workload::VISIBLE_REGION;
3010 }
3011 if (mFrontEndDisplayInfosChanged) {
3012 compositedWorkload |= adpf::Workload::DISPLAY_CHANGES;
3013 SFTRACE_INSTANT_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Display Changes");
3014 }
3015
3016 int index = 0;
3017 ftl::StaticVector<char, WorkloadTracer::COMPOSITION_SUMMARY_SIZE> compositionSummary;
3018 auto lastLayerStack = ui::INVALID_LAYER_STACK;
3019
3020 uint64_t prevOverrideBufferId = 0;
3021 for (auto& [layer, layerFE] : layers) {
3022 CompositionResult compositionResult{layerFE->stealCompositionResult()};
3023 if (lastLayerStack != layerFE->mSnapshot->outputFilter.layerStack) {
3024 if (lastLayerStack != ui::INVALID_LAYER_STACK) {
3025 // add a space to separate displays
3026 compositionSummary.push_back(' ');
3027 }
3028 lastLayerStack = layerFE->mSnapshot->outputFilter.layerStack;
3029 }
3030
3031 // If there are N layers in a cached set they should all share the same buffer id.
3032 // The first layer in the cached set will be not skipped and layers 1..N-1 will be skipped.
3033 // We expect all layers in the cached set to be marked as composited by HWC.
3034 // Here is a made up example of how it is visualized
3035 //
3036 // [b:rrc][s:cc]
3037 //
3038 // This should be interpreted to mean that there are 2 cached sets.
3039 // So there are only 2 non skipped layers -- b and s.
3040 // The layers rrc and cc are flattened into layers b and s respectively.
3041 const LayerFE::HwcLayerDebugState& hwcState = layerFE->getLastHwcState();
3042 if (hwcState.overrideBufferId != prevOverrideBufferId) {
3043 // End the existing run.
3044 if (prevOverrideBufferId) {
3045 compositionSummary.push_back(']');
3046 }
3047 // Start a new run.
3048 if (hwcState.overrideBufferId) {
3049 compositionSummary.push_back('[');
3050 }
3051 }
3052
3053 compositionSummary.push_back(layerFE->mSnapshot->classifyCompositionForDebug(hwcState));
3054
3055 if (hwcState.overrideBufferId && !hwcState.wasSkipped) {
3056 compositionSummary.push_back(':');
3057 }
3058 prevOverrideBufferId = hwcState.overrideBufferId;
3059
3060 if (layerFE->mSnapshot->hasEffect()) {
3061 compositedWorkload |= adpf::Workload::EFFECTS;
3062 }
3063
3064 if (compositionResult.lastClientCompositionFence) {
3065 layer->setWasClientComposed(compositionResult.lastClientCompositionFence);
3066 }
3067 if (com_android_graphics_libgui_flags_apply_picture_profiles()) {
3068 mActivePictureTracker.onLayerComposed(*layer, *layerFE, compositionResult);
3069 }
3070 }
3071 // End the last run.
3072 if (prevOverrideBufferId) {
3073 compositionSummary.push_back(']');
3074 }
3075
3076 // Concisely describe the layers composited this frame using single chars. GPU composited layers
3077 // are uppercase, DPU composited are lowercase. Special chars denote effects (blur, shadow,
3078 // etc.). This provides a snapshot of the compositing workload.
3079 SFTRACE_INSTANT_FOR_TRACK(WorkloadTracer::TRACK_NAME,
3080 ftl::Concat("Layers: ", layers.size(), " ",
3081 ftl::truncated<WorkloadTracer::COMPOSITION_SUMMARY_SIZE>(
3082 std::string_view(compositionSummary.begin(),
3083 compositionSummary.size())))
3084 .c_str());
3085
3086 mPowerAdvisor->setCompositedWorkload(compositedWorkload);
3087 SFTRACE_ASYNC_FOR_TRACK_END(WorkloadTracer::TRACK_NAME,
3088 WorkloadTracer::COMPOSITION_TRACE_COOKIE);
3089 SFTRACE_NAME_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Post Composition");
3090 SFTRACE_NAME("postComposition");
3091
3092 if (mDisplayModeController.supportsHdcp()) {
3093 for (const auto& [id, _] : frameTargeters) {
3094 ftl::FakeGuard guard(mStateLock);
3095 if (const auto display = getCompositionDisplayLocked(id)) {
3096 if (!display->isSecure() && display->hasSecureLayers()) {
3097 mDisplayModeController.startHdcpNegotiation(id);
3098 }
3099 }
3100 }
3101 }
3102
3103 moveSnapshotsFromCompositionArgs(refreshArgs, layers);
3104 mTimeStats->recordFrameDuration(pacesetterTarget.frameBeginTime().ns(), systemTime());
3105
3106 // Send a power hint after presentation is finished.
3107 if (mPowerHintSessionEnabled) {
3108 // Now that the current frame has been presented above, PowerAdvisor needs the present time
3109 // of the previous frame (whose fence is signaled by now) to determine how long the HWC had
3110 // waited on that fence to retire before presenting.
3111 // TODO(b/355238809) `presentFenceForPreviousFrame` might not always be signaled (e.g. on
3112 // devices
3113 // where HWC does not block on the previous present fence). Revise this assumtion.
3114 const auto& previousPresentFence = pacesetterTarget.presentFenceForPreviousFrame();
3115
3116 mPowerAdvisor->setSfPresentTiming(TimePoint::fromNs(previousPresentFence->getSignalTime()),
3117 TimePoint::now());
3118 mPowerAdvisor->reportActualWorkDuration();
3119 }
3120
3121 if (mScheduler->onCompositionPresented(presentTime)) {
3122 scheduleComposite(FrameHint::kNone);
3123 }
3124
3125 mNotifyExpectedPresentMap[pacesetterId].hintStatus = NotifyExpectedPresentHintStatus::Start;
3126 onCompositionPresented(pacesetterId, frameTargeters, presentTime);
3127
3128 const bool hadGpuComposited =
3129 multiDisplayUnion(mCompositionCoverage).test(CompositionCoverage::Gpu);
3130 mCompositionCoverage.clear();
3131
3132 TimeStats::ClientCompositionRecord clientCompositionRecord;
3133
3134 for (const auto& [_, display] : displays) {
3135 const auto& state = display->getCompositionDisplay()->getState();
3136 CompositionCoverageFlags& flags =
3137 mCompositionCoverage.try_emplace(display->getDisplayIdVariant()).first->second;
3138
3139 if (state.usesDeviceComposition) {
3140 flags |= CompositionCoverage::Hwc;
3141 }
3142
3143 if (state.reusedClientComposition) {
3144 flags |= CompositionCoverage::GpuReuse;
3145 } else if (state.usesClientComposition) {
3146 flags |= CompositionCoverage::Gpu;
3147 }
3148
3149 clientCompositionRecord.predicted |=
3150 (state.strategyPrediction != CompositionStrategyPredictionState::DISABLED);
3151 clientCompositionRecord.predictionSucceeded |=
3152 (state.strategyPrediction == CompositionStrategyPredictionState::SUCCESS);
3153 }
3154
3155 const auto coverage = multiDisplayUnion(mCompositionCoverage);
3156 const bool hasGpuComposited = coverage.test(CompositionCoverage::Gpu);
3157
3158 clientCompositionRecord.hadClientComposition = hasGpuComposited;
3159 clientCompositionRecord.reused = coverage.test(CompositionCoverage::GpuReuse);
3160 clientCompositionRecord.changed = hadGpuComposited != hasGpuComposited;
3161
3162 mTimeStats->pushCompositionStrategyState(clientCompositionRecord);
3163
3164 using namespace ftl::flag_operators;
3165
3166 // TODO(b/160583065): Enable skip validation when SF caches all client composition layers.
3167 const bool hasGpuUseOrReuse =
3168 coverage.any(CompositionCoverage::Gpu | CompositionCoverage::GpuReuse);
3169 mScheduler->modulateVsync({}, &VsyncModulator::onDisplayRefresh, hasGpuUseOrReuse);
3170
3171 mLayersWithQueuedFrames.clear();
3172 doActiveLayersTracingIfNeeded(true, mVisibleRegionsDirty, pacesetterTarget.frameBeginTime(),
3173 vsyncId);
3174
3175 updateInputFlinger(vsyncId, pacesetterTarget.frameBeginTime());
3176
3177 if (mVisibleRegionsDirty) mHdrLayerInfoChanged = true;
3178 mVisibleRegionsDirty = false;
3179
3180 if (mCompositionEngine->needsAnotherUpdate()) {
3181 scheduleCommit(FrameHint::kNone);
3182 }
3183
3184 if (mPowerHintSessionEnabled) {
3185 mPowerAdvisor->setCompositeEnd(TimePoint::now());
3186 }
3187
3188 CompositeResultsPerDisplay resultsPerDisplay;
3189
3190 // Filter out virtual displays.
3191 for (const auto& [idVar, coverage] : mCompositionCoverage) {
3192 if (const auto idOpt = asPhysicalDisplayId(idVar)) {
3193 resultsPerDisplay.try_emplace(*idOpt, CompositeResult{coverage});
3194 }
3195 }
3196
3197 return resultsPerDisplay;
3198 }
3199
isHdrLayer(const frontend::LayerSnapshot & snapshot) const3200 bool SurfaceFlinger::isHdrLayer(const frontend::LayerSnapshot& snapshot) const {
3201 // Even though the camera layer may be using an HDR transfer function or otherwise be "HDR"
3202 // the device may need to avoid boosting the brightness as a result of these layers to
3203 // reduce power consumption during camera recording
3204 if (mIgnoreHdrCameraLayers) {
3205 if (snapshot.externalTexture &&
3206 (snapshot.externalTexture->getUsage() & GRALLOC_USAGE_HW_CAMERA_WRITE) != 0) {
3207 return false;
3208 }
3209 }
3210 // RANGE_EXTENDED layer may identify themselves as being "HDR"
3211 // via a desired hdr/sdr ratio
3212 auto pixelFormat = snapshot.buffer
3213 ? std::make_optional(static_cast<ui::PixelFormat>(snapshot.buffer->getPixelFormat()))
3214 : std::nullopt;
3215
3216 if (getHdrRenderType(snapshot.dataspace, pixelFormat, snapshot.desiredHdrSdrRatio) !=
3217 HdrRenderType::SDR) {
3218 return true;
3219 }
3220 // If the layer is not allowed to be dimmed, treat it as HDR. WindowManager may disable
3221 // dimming in order to keep animations invoking SDR screenshots of HDR layers seamless.
3222 // Treat such tagged layers as HDR so that DisplayManagerService does not try to change
3223 // the screen brightness
3224 if (!snapshot.dimmingEnabled) {
3225 return true;
3226 }
3227 return false;
3228 }
3229
getPhysicalDisplayOrientation(PhysicalDisplayId displayId,bool isPrimary) const3230 ui::Rotation SurfaceFlinger::getPhysicalDisplayOrientation(PhysicalDisplayId displayId,
3231 bool isPrimary) const {
3232 if (!mIgnoreHwcPhysicalDisplayOrientation &&
3233 getHwComposer().getComposer()->isSupported(
3234 Hwc2::Composer::OptionalFeature::PhysicalDisplayOrientation)) {
3235 switch (getHwComposer().getPhysicalDisplayOrientation(displayId)) {
3236 case Hwc2::AidlTransform::ROT_90:
3237 return ui::ROTATION_90;
3238 case Hwc2::AidlTransform::ROT_180:
3239 return ui::ROTATION_180;
3240 case Hwc2::AidlTransform::ROT_270:
3241 return ui::ROTATION_270;
3242 default:
3243 return ui::ROTATION_0;
3244 }
3245 }
3246
3247 if (isPrimary) {
3248 using Values = SurfaceFlingerProperties::primary_display_orientation_values;
3249 switch (primary_display_orientation(Values::ORIENTATION_0)) {
3250 case Values::ORIENTATION_90:
3251 return ui::ROTATION_90;
3252 case Values::ORIENTATION_180:
3253 return ui::ROTATION_180;
3254 case Values::ORIENTATION_270:
3255 return ui::ROTATION_270;
3256 default:
3257 break;
3258 }
3259 }
3260 return ui::ROTATION_0;
3261 }
3262
onCompositionPresented(PhysicalDisplayId pacesetterId,const scheduler::FrameTargeters & frameTargeters,nsecs_t presentStartTime)3263 void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId,
3264 const scheduler::FrameTargeters& frameTargeters,
3265 nsecs_t presentStartTime) {
3266 SFTRACE_CALL();
3267
3268 ui::PhysicalDisplayMap<PhysicalDisplayId, std::shared_ptr<FenceTime>> presentFences;
3269 ui::PhysicalDisplayMap<PhysicalDisplayId, const sp<Fence>> gpuCompositionDoneFences;
3270
3271 for (const auto& [id, targeter] : frameTargeters) {
3272 auto presentFence = getHwComposer().getPresentFence(id);
3273
3274 if (id == pacesetterId) {
3275 mTransactionCallbackInvoker.addPresentFence(presentFence);
3276 }
3277
3278 if (auto fenceTime = targeter->setPresentFence(std::move(presentFence));
3279 fenceTime->isValid()) {
3280 presentFences.try_emplace(id, std::move(fenceTime));
3281 }
3282
3283 ftl::FakeGuard guard(mStateLock);
3284 if (const auto display = getCompositionDisplayLocked(id);
3285 display && display->getState().usesClientComposition) {
3286 gpuCompositionDoneFences
3287 .try_emplace(id, display->getRenderSurface()->getClientTargetAcquireFence());
3288 }
3289 }
3290
3291 const auto pacesetterDisplay = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(pacesetterId));
3292
3293 std::shared_ptr<FenceTime> pacesetterPresentFenceTime =
3294 presentFences.get(pacesetterId)
3295 .transform([](const FenceTimePtr& ptr) { return ptr; })
3296 .value_or(FenceTime::NO_FENCE);
3297
3298 std::shared_ptr<FenceTime> pacesetterGpuCompositionDoneFenceTime =
3299 gpuCompositionDoneFences.get(pacesetterId)
3300 .transform([](sp<Fence> fence) {
3301 return std::make_shared<FenceTime>(std::move(fence));
3302 })
3303 .value_or(FenceTime::NO_FENCE);
3304
3305 const TimePoint presentTime = TimePoint::now();
3306
3307 // Set presentation information before calling Layer::releasePendingBuffer, such that jank
3308 // information from previous' frame classification is already available when sending jank info
3309 // to clients, so they get jank classification as early as possible.
3310 mFrameTimeline->setSfPresent(presentTime.ns(), pacesetterPresentFenceTime,
3311 pacesetterGpuCompositionDoneFenceTime);
3312
3313 // We use the CompositionEngine::getLastFrameRefreshTimestamp() which might
3314 // be sampled a little later than when we started doing work for this frame,
3315 // but that should be okay since CompositorTiming has snapping logic.
3316 const TimePoint compositeTime =
3317 TimePoint::fromNs(mCompositionEngine->getLastFrameRefreshTimestamp());
3318 const Duration presentLatency = mHasReliablePresentFences
3319 ? mPresentLatencyTracker.trackPendingFrame(compositeTime, pacesetterPresentFenceTime)
3320 : Duration::zero();
3321
3322 const auto schedule = mScheduler->getVsyncSchedule();
3323 const TimePoint vsyncDeadline = schedule->vsyncDeadlineAfter(presentTime);
3324 const Fps renderRate = pacesetterDisplay->refreshRateSelector().getActiveMode().fps;
3325 const nsecs_t vsyncPhase = mScheduler->getCurrentVsyncConfigs().late.sfOffset;
3326
3327 const CompositorTiming compositorTiming(vsyncDeadline.ns(), renderRate.getPeriodNsecs(),
3328 vsyncPhase, presentLatency.ns());
3329
3330 ui::DisplayMap<ui::LayerStack, const DisplayDevice*> layerStackToDisplay;
3331 {
3332 if (!mLayersWithBuffersRemoved.empty() || mNumTrustedPresentationListeners > 0) {
3333 Mutex::Autolock lock(mStateLock);
3334 for (const auto& [token, display] : mDisplays) {
3335 layerStackToDisplay.emplace_or_replace(display->getLayerStack(), display.get());
3336 }
3337 }
3338 }
3339
3340 for (auto layer : mLayersWithBuffersRemoved) {
3341 std::vector<ui::LayerStack> previouslyPresentedLayerStacks =
3342 std::move(layer->mPreviouslyPresentedLayerStacks);
3343 layer->mPreviouslyPresentedLayerStacks.clear();
3344 for (auto layerStack : previouslyPresentedLayerStacks) {
3345 auto optDisplay = layerStackToDisplay.get(layerStack);
3346 if (optDisplay && !optDisplay->get()->isVirtual()) {
3347 auto fence = getHwComposer().getPresentFence(optDisplay->get()->getPhysicalId());
3348 layer->prepareReleaseCallbacks(ftl::yield<FenceResult>(fence),
3349 ui::INVALID_LAYER_STACK);
3350 }
3351 }
3352 layer->releasePendingBuffer(presentTime.ns());
3353 }
3354 mLayersWithBuffersRemoved.clear();
3355
3356 for (const auto& [layer, gameMode] : mLayersWithQueuedFrames) {
3357 layer->onCompositionPresented(pacesetterDisplay.get(),
3358 pacesetterGpuCompositionDoneFenceTime,
3359 pacesetterPresentFenceTime, compositorTiming, gameMode);
3360 layer->releasePendingBuffer(presentTime.ns());
3361 }
3362
3363 for (const auto& layerEvent : mLayerEvents) {
3364 auto result =
3365 stats::stats_write(stats::SURFACE_CONTROL_EVENT,
3366 static_cast<int32_t>(layerEvent.uid),
3367 static_cast<int64_t>(layerEvent.timeSinceLastEvent.count()),
3368 static_cast<int32_t>(layerEvent.dataspace));
3369 if (result < 0) {
3370 ALOGW("Failed to report layer event with error: %d", result);
3371 }
3372 }
3373 mLayerEvents.clear();
3374
3375 std::vector<std::pair<std::shared_ptr<compositionengine::Display>, sp<HdrLayerInfoReporter>>>
3376 hdrInfoListeners;
3377 bool haveNewHdrInfoListeners = false;
3378 ActivePictureTracker::Listeners activePictureListenersToAdd;
3379 ActivePictureTracker::Listeners activePictureListenersToRemove;
3380 {
3381 Mutex::Autolock lock(mStateLock);
3382 if (mFpsReporter) {
3383 mFpsReporter->dispatchLayerFps(mLayerHierarchyBuilder.getHierarchy());
3384 }
3385
3386 if (mTunnelModeEnabledReporter) {
3387 mTunnelModeEnabledReporter->updateTunnelModeStatus();
3388 }
3389
3390 hdrInfoListeners.reserve(mHdrLayerInfoListeners.size());
3391 for (const auto& [displayId, reporter] : mHdrLayerInfoListeners) {
3392 if (reporter && reporter->hasListeners()) {
3393 if (const auto display = getDisplayDeviceLocked(displayId)) {
3394 hdrInfoListeners.emplace_back(display->getCompositionDisplay(), reporter);
3395 }
3396 }
3397 }
3398 haveNewHdrInfoListeners = mAddingHDRLayerInfoListener; // grab this with state lock
3399 mAddingHDRLayerInfoListener = false;
3400
3401 std::swap(activePictureListenersToAdd, mActivePictureListenersToAdd);
3402 std::swap(activePictureListenersToRemove, mActivePictureListenersToRemove);
3403 }
3404
3405 if (haveNewHdrInfoListeners || mHdrLayerInfoChanged) {
3406 for (auto& [compositionDisplay, listener] : hdrInfoListeners) {
3407 HdrLayerInfoReporter::HdrLayerInfo info;
3408 int32_t maxArea = 0;
3409
3410 auto updateInfoFn =
3411 [&](const std::shared_ptr<compositionengine::Display>& compositionDisplay,
3412 const frontend::LayerSnapshot& snapshot, const sp<LayerFE>& layerFe) {
3413 if (snapshot.isVisible &&
3414 compositionDisplay->includesLayer(snapshot.outputFilter)) {
3415 if (isHdrLayer(snapshot)) {
3416 const auto* outputLayer =
3417 compositionDisplay->getOutputLayerForLayer(layerFe);
3418 if (outputLayer) {
3419 const float desiredHdrSdrRatio =
3420 snapshot.desiredHdrSdrRatio < 1.f
3421 ? std::numeric_limits<float>::infinity()
3422 : snapshot.desiredHdrSdrRatio;
3423
3424 float desiredRatio = desiredHdrSdrRatio;
3425 if (FlagManager::getInstance().begone_bright_hlg() &&
3426 desiredHdrSdrRatio ==
3427 std::numeric_limits<float>::infinity()) {
3428 desiredRatio = getIdealizedMaxHeadroom(snapshot.dataspace);
3429 }
3430
3431 info.mergeDesiredRatio(desiredRatio);
3432 info.numberOfHdrLayers++;
3433 const auto displayFrame = outputLayer->getState().displayFrame;
3434 const int32_t area =
3435 displayFrame.width() * displayFrame.height();
3436 if (area > maxArea) {
3437 maxArea = area;
3438 info.maxW = displayFrame.width();
3439 info.maxH = displayFrame.height();
3440 }
3441 }
3442 }
3443 }
3444 };
3445
3446 mLayerSnapshotBuilder.forEachVisibleSnapshot(
3447 [&, compositionDisplay = compositionDisplay](
3448 std::unique_ptr<frontend::LayerSnapshot>& snapshot)
3449 FTL_FAKE_GUARD(kMainThreadContext) {
3450 auto it = mLegacyLayers.find(snapshot->sequence);
3451 LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
3452 "Couldnt find layer object for %s",
3453 snapshot->getDebugString().c_str());
3454 auto& legacyLayer = it->second;
3455 sp<LayerFE> layerFe =
3456 legacyLayer->getCompositionEngineLayerFE(snapshot->path);
3457
3458 updateInfoFn(compositionDisplay, *snapshot, layerFe);
3459 });
3460 listener->dispatchHdrLayerInfo(info);
3461 }
3462 }
3463 mHdrLayerInfoChanged = false;
3464
3465 if (com_android_graphics_libgui_flags_apply_picture_profiles()) {
3466 // Track, update and notify changes to active pictures - layers that are undergoing
3467 // picture processing
3468 mActivePictureTracker.updateAndNotifyListeners(activePictureListenersToAdd,
3469 activePictureListenersToRemove);
3470 }
3471
3472 mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
3473 mTransactionCallbackInvoker.clearCompletedTransactions();
3474
3475 mTimeStats->incrementTotalFrames();
3476 mTimeStats->setPresentFenceGlobal(pacesetterPresentFenceTime);
3477
3478 for (auto&& [id, presentFence] : presentFences) {
3479 mScheduler->addPresentFence(id, std::move(presentFence));
3480 }
3481
3482 const bool hasPacesetterDisplay =
3483 pacesetterDisplay && getHwComposer().isConnected(pacesetterId);
3484
3485 if (!hasSyncFramework) {
3486 if (hasPacesetterDisplay && pacesetterDisplay->isPoweredOn()) {
3487 mScheduler->enableHardwareVsync(pacesetterId);
3488 }
3489 }
3490
3491 if (hasPacesetterDisplay && !pacesetterDisplay->isPoweredOn()) {
3492 getRenderEngine().cleanupPostRender();
3493 return;
3494 }
3495
3496 // Cleanup any outstanding resources due to rendering a prior frame.
3497 getRenderEngine().cleanupPostRender();
3498
3499 if (mNumTrustedPresentationListeners > 0) {
3500 // We avoid any reverse traversal upwards so this shouldn't be too expensive
3501 traverseLegacyLayers([&](Layer* layer) FTL_FAKE_GUARD(kMainThreadContext) {
3502 if (!layer->hasTrustedPresentationListener()) {
3503 return;
3504 }
3505 const frontend::LayerSnapshot* snapshot =
3506 mLayerSnapshotBuilder.getSnapshot(layer->sequence);
3507 std::optional<const DisplayDevice*> displayOpt = std::nullopt;
3508 if (snapshot) {
3509 displayOpt = layerStackToDisplay.get(snapshot->outputFilter.layerStack);
3510 }
3511 const DisplayDevice* display = displayOpt.value_or(nullptr);
3512 layer->updateTrustedPresentationState(display, snapshot,
3513 nanoseconds_to_milliseconds(presentStartTime),
3514 false);
3515 });
3516 }
3517
3518 // Even though SFTRACE_INT64 already checks if tracing is enabled, it doesn't prevent the
3519 // side-effect of getTotalSize(), so we check that again here
3520 if (SFTRACE_ENABLED()) {
3521 // getTotalSize returns the total number of buffers that were allocated by SurfaceFlinger
3522 SFTRACE_INT64("Total Buffer Size", GraphicBufferAllocator::get().getTotalSize());
3523 }
3524 }
3525
commitTransactions()3526 void SurfaceFlinger::commitTransactions() {
3527 SFTRACE_CALL();
3528 mDebugInTransaction = systemTime();
3529
3530 // Here we're guaranteed that some transaction flags are set
3531 // so we can call commitTransactionsLocked unconditionally.
3532 // We clear the flags with mStateLock held to guarantee that
3533 // mCurrentState won't change until the transaction is committed.
3534 mScheduler->modulateVsync({}, &VsyncModulator::onTransactionCommit);
3535 commitTransactionsLocked(clearTransactionFlags(eTransactionMask));
3536 mDebugInTransaction = 0;
3537 }
3538
loadDisplayModes(PhysicalDisplayId displayId) const3539 std::pair<DisplayModes, DisplayModePtr> SurfaceFlinger::loadDisplayModes(
3540 PhysicalDisplayId displayId) const {
3541 std::vector<HWComposer::HWCDisplayMode> hwcModes;
3542 std::optional<hal::HWConfigId> activeModeHwcIdOpt;
3543
3544 const bool isExternalDisplay = getHwComposer().getDisplayConnectionType(displayId) ==
3545 ui::DisplayConnectionType::External;
3546
3547 int attempt = 0;
3548 constexpr int kMaxAttempts = 3;
3549 do {
3550 hwcModes = getHwComposer().getModes(displayId,
3551 scheduler::RefreshRateSelector::kMinSupportedFrameRate
3552 .getPeriodNsecs());
3553 const auto activeModeHwcIdExp = getHwComposer().getActiveMode(displayId);
3554 activeModeHwcIdOpt = activeModeHwcIdExp.value_opt();
3555
3556 if (isExternalDisplay &&
3557 activeModeHwcIdExp.has_error([](status_t error) { return error == NO_INIT; })) {
3558 constexpr nsecs_t k59HzVsyncPeriod = 16949153;
3559 constexpr nsecs_t k60HzVsyncPeriod = 16666667;
3560
3561 // DM sets the initial mode for an external display to 1080p@60, but
3562 // this comes after SF creates its own state (including the
3563 // DisplayDevice). For now, pick the same mode in order to avoid
3564 // inconsistent state and unnecessary mode switching.
3565 // TODO (b/318534874): Let DM decide the initial mode.
3566 //
3567 // Try to find 1920x1080 @ 60 Hz
3568 if (const auto iter = std::find_if(hwcModes.begin(), hwcModes.end(),
3569 [](const auto& mode) {
3570 return mode.width == 1920 &&
3571 mode.height == 1080 &&
3572 mode.vsyncPeriod == k60HzVsyncPeriod;
3573 });
3574 iter != hwcModes.end()) {
3575 activeModeHwcIdOpt = iter->hwcId;
3576 break;
3577 }
3578
3579 // Try to find 1920x1080 @ 59-60 Hz
3580 if (const auto iter = std::find_if(hwcModes.begin(), hwcModes.end(),
3581 [](const auto& mode) {
3582 return mode.width == 1920 &&
3583 mode.height == 1080 &&
3584 mode.vsyncPeriod >= k60HzVsyncPeriod &&
3585 mode.vsyncPeriod <= k59HzVsyncPeriod;
3586 });
3587 iter != hwcModes.end()) {
3588 activeModeHwcIdOpt = iter->hwcId;
3589 break;
3590 }
3591
3592 // The display does not support 1080p@60, and this is the last attempt to pick a display
3593 // mode. Prefer 60 Hz if available, with the closest resolution to 1080p.
3594 if (attempt + 1 == kMaxAttempts) {
3595 std::vector<HWComposer::HWCDisplayMode> hwcModeOpts;
3596
3597 for (const auto& mode : hwcModes) {
3598 if (mode.width <= 1920 && mode.height <= 1080 &&
3599 mode.vsyncPeriod >= k60HzVsyncPeriod &&
3600 mode.vsyncPeriod <= k59HzVsyncPeriod) {
3601 hwcModeOpts.push_back(mode);
3602 }
3603 }
3604
3605 if (const auto iter = std::max_element(hwcModeOpts.begin(), hwcModeOpts.end(),
3606 [](const auto& a, const auto& b) {
3607 const auto aSize = a.width * a.height;
3608 const auto bSize = b.width * b.height;
3609 if (aSize < bSize)
3610 return true;
3611 else if (aSize == bSize)
3612 return a.vsyncPeriod > b.vsyncPeriod;
3613 else
3614 return false;
3615 });
3616 iter != hwcModeOpts.end()) {
3617 activeModeHwcIdOpt = iter->hwcId;
3618 break;
3619 }
3620
3621 // hwcModeOpts was empty, use hwcModes[0] as the last resort
3622 activeModeHwcIdOpt = hwcModes[0].hwcId;
3623 }
3624 }
3625
3626 const auto isActiveMode = [activeModeHwcIdOpt](const HWComposer::HWCDisplayMode& mode) {
3627 return mode.hwcId == activeModeHwcIdOpt;
3628 };
3629
3630 if (std::any_of(hwcModes.begin(), hwcModes.end(), isActiveMode)) {
3631 break;
3632 }
3633 } while (++attempt < kMaxAttempts);
3634
3635 if (attempt == kMaxAttempts) {
3636 const std::string activeMode =
3637 activeModeHwcIdOpt ? std::to_string(*activeModeHwcIdOpt) : "unknown"s;
3638 ALOGE("HWC failed to report an active mode that is supported: activeModeHwcId=%s, "
3639 "hwcModes={%s}",
3640 activeMode.c_str(), base::Join(hwcModes, ", ").c_str());
3641 return {};
3642 }
3643
3644 const DisplayModes oldModes = mPhysicalDisplays.get(displayId)
3645 .transform([](const PhysicalDisplay& display) {
3646 return display.snapshot().displayModes();
3647 })
3648 .value_or(DisplayModes{});
3649
3650 DisplayModeId nextModeId = std::accumulate(oldModes.begin(), oldModes.end(), DisplayModeId(-1),
3651 [](DisplayModeId max, const auto& pair) {
3652 return std::max(max, pair.first);
3653 });
3654 ++nextModeId;
3655
3656 DisplayModes newModes;
3657 for (const auto& hwcMode : hwcModes) {
3658 const auto id = nextModeId++;
3659 OutputType hdrOutputType = FlagManager::getInstance().connected_display_hdr()
3660 ? hwcMode.hdrOutputType
3661 : OutputType::INVALID;
3662 newModes.try_emplace(id,
3663 DisplayMode::Builder(hwcMode.hwcId)
3664 .setId(id)
3665 .setPhysicalDisplayId(displayId)
3666 .setResolution({hwcMode.width, hwcMode.height})
3667 .setVsyncPeriod(hwcMode.vsyncPeriod)
3668 .setVrrConfig(hwcMode.vrrConfig)
3669 .setDpiX(hwcMode.dpiX)
3670 .setDpiY(hwcMode.dpiY)
3671 .setGroup(hwcMode.configGroup)
3672 .setHdrOutputType(hdrOutputType)
3673 .build());
3674 }
3675
3676 const bool sameModes =
3677 std::equal(newModes.begin(), newModes.end(), oldModes.begin(), oldModes.end(),
3678 [](const auto& lhs, const auto& rhs) {
3679 return equalsExceptDisplayModeId(*lhs.second, *rhs.second);
3680 });
3681
3682 // Keep IDs if modes have not changed.
3683 const auto& modes = sameModes ? oldModes : newModes;
3684 const DisplayModePtr activeMode =
3685 std::find_if(modes.begin(), modes.end(), [activeModeHwcIdOpt](const auto& pair) {
3686 return pair.second->getHwcId() == activeModeHwcIdOpt;
3687 })->second;
3688
3689 if (isExternalDisplay) {
3690 ALOGI("External display %s initial mode: {%s}", to_string(displayId).c_str(),
3691 to_string(*activeMode).c_str());
3692 }
3693 return {modes, activeMode};
3694 }
3695
configureLocked()3696 bool SurfaceFlinger::configureLocked() {
3697 std::vector<HotplugEvent> events;
3698 {
3699 std::lock_guard<std::mutex> lock(mHotplugMutex);
3700 events = std::move(mPendingHotplugEvents);
3701 }
3702
3703 for (const auto [hwcDisplayId, event] : events) {
3704 if (auto info = getHwComposer().onHotplug(hwcDisplayId, event)) {
3705 const auto displayId = info->id;
3706 const ftl::Concat displayString("display ", displayId.value, "(HAL ID ", hwcDisplayId,
3707 ')');
3708 // TODO: b/393126541 - replace if with switch as all cases are handled.
3709 if (event == HWComposer::HotplugEvent::Connected ||
3710 event == HWComposer::HotplugEvent::LinkUnstable) {
3711 const auto activeModeIdOpt =
3712 processHotplugConnect(displayId, hwcDisplayId, std::move(*info),
3713 displayString.c_str(), event);
3714 if (!activeModeIdOpt) {
3715 mScheduler->dispatchHotplugError(
3716 static_cast<int32_t>(DisplayHotplugEvent::ERROR_UNKNOWN));
3717 getHwComposer().disconnectDisplay(displayId);
3718 continue;
3719 }
3720
3721 const auto [kernelIdleTimerController, idleTimerTimeoutMs] =
3722 getKernelIdleTimerProperties(displayId);
3723
3724 using Config = scheduler::RefreshRateSelector::Config;
3725 const Config config =
3726 {.enableFrameRateOverride = sysprop::enable_frame_rate_override(true)
3727 ? Config::FrameRateOverride::Enabled
3728 : Config::FrameRateOverride::Disabled,
3729 .frameRateMultipleThreshold =
3730 base::GetIntProperty("debug.sf.frame_rate_multiple_threshold"s, 0),
3731 .legacyIdleTimerTimeout = idleTimerTimeoutMs,
3732 .kernelIdleTimerController = kernelIdleTimerController};
3733
3734 const auto snapshotOpt =
3735 mPhysicalDisplays.get(displayId).transform(&PhysicalDisplay::snapshotRef);
3736 LOG_ALWAYS_FATAL_IF(!snapshotOpt);
3737
3738 mDisplayModeController.registerDisplay(*snapshotOpt, *activeModeIdOpt, config);
3739 } else { // event == HWComposer::HotplugEvent::Disconnected
3740 // Unregister before destroying the DisplaySnapshot below.
3741 mDisplayModeController.unregisterDisplay(displayId);
3742
3743 processHotplugDisconnect(displayId, displayString.c_str());
3744 }
3745 }
3746 }
3747
3748 return !events.empty();
3749 }
3750
processHotplugConnect(PhysicalDisplayId displayId,hal::HWDisplayId hwcDisplayId,DisplayIdentificationInfo && info,const char * displayString,HWComposer::HotplugEvent event)3751 std::optional<DisplayModeId> SurfaceFlinger::processHotplugConnect(PhysicalDisplayId displayId,
3752 hal::HWDisplayId hwcDisplayId,
3753 DisplayIdentificationInfo&& info,
3754 const char* displayString,
3755 HWComposer::HotplugEvent event) {
3756 auto [displayModes, activeMode] = loadDisplayModes(displayId);
3757 if (!activeMode) {
3758 ALOGE("Failed to hotplug %s", displayString);
3759 return std::nullopt;
3760 }
3761
3762 const DisplayModeId activeModeId = activeMode->getId();
3763 ui::ColorModes colorModes = getHwComposer().getColorModes(displayId);
3764
3765 if (const auto displayOpt = mPhysicalDisplays.get(displayId)) {
3766 const auto& display = displayOpt->get();
3767 const auto& snapshot = display.snapshot();
3768 const uint8_t port = snapshot.port();
3769
3770 std::optional<DeviceProductInfo> deviceProductInfo;
3771 if (getHwComposer().updatesDeviceProductInfoOnHotplugReconnect()) {
3772 deviceProductInfo = std::move(info.deviceProductInfo);
3773 } else {
3774 deviceProductInfo = snapshot.deviceProductInfo();
3775 }
3776
3777 // Use the cached port via snapshot because we are updating an existing
3778 // display on reconnect.
3779 const auto it =
3780 mPhysicalDisplays.try_replace(displayId, display.token(), displayId, port,
3781 snapshot.connectionType(), std::move(displayModes),
3782 std::move(colorModes), std::move(deviceProductInfo));
3783
3784 auto& state = mCurrentState.displays.editValueFor(it->second.token());
3785 state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId.
3786 state.physical->activeMode = std::move(activeMode);
3787 state.physical->port = port;
3788 ALOGI("Reconnecting %s", displayString);
3789 return activeModeId;
3790 } else if (event == HWComposer::HotplugEvent::LinkUnstable) {
3791 ALOGE("Failed to reconnect unknown %s", displayString);
3792 return std::nullopt;
3793 }
3794
3795 const sp<IBinder> token = sp<BBinder>::make();
3796 const ui::DisplayConnectionType connectionType =
3797 getHwComposer().getDisplayConnectionType(displayId);
3798
3799 mPhysicalDisplays.try_emplace(displayId, token, displayId, info.port, connectionType,
3800 std::move(displayModes), std::move(colorModes),
3801 std::move(info.deviceProductInfo));
3802
3803 DisplayDeviceState state;
3804 state.physical = {.id = displayId,
3805 .hwcDisplayId = hwcDisplayId,
3806 .port = info.port,
3807 .activeMode = std::move(activeMode)};
3808 // TODO: b/349703362 - Remove first condition when HDCP aidl APIs are enforced
3809 state.isSecure = !mDisplayModeController.supportsHdcp() ||
3810 connectionType == ui::DisplayConnectionType::Internal;
3811 state.isProtected = true;
3812 state.displayName = std::move(info.name);
3813 state.maxLayerPictureProfiles = getHwComposer().getMaxLayerPictureProfiles(displayId);
3814 state.hasPictureProcessing =
3815 getHwComposer().hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING);
3816 mCurrentState.displays.add(token, state);
3817 ALOGI("Connecting %s", displayString);
3818 return activeModeId;
3819 }
3820
processHotplugDisconnect(PhysicalDisplayId displayId,const char * displayString)3821 void SurfaceFlinger::processHotplugDisconnect(PhysicalDisplayId displayId,
3822 const char* displayString) {
3823 ALOGI("Disconnecting %s", displayString);
3824
3825 const auto displayOpt = mPhysicalDisplays.get(displayId);
3826 LOG_ALWAYS_FATAL_IF(!displayOpt);
3827 const auto& display = displayOpt->get();
3828
3829 if (const ssize_t index = mCurrentState.displays.indexOfKey(display.token()); index >= 0) {
3830 mCurrentState.displays.removeItemsAt(index);
3831 }
3832
3833 mPhysicalDisplays.erase(displayId);
3834 }
3835
setupNewDisplayDeviceInternal(const wp<IBinder> & displayToken,std::shared_ptr<compositionengine::Display> compositionDisplay,const DisplayDeviceState & state,const sp<compositionengine::DisplaySurface> & displaySurface,const sp<IGraphicBufferProducer> & producer)3836 sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
3837 const wp<IBinder>& displayToken,
3838 std::shared_ptr<compositionengine::Display> compositionDisplay,
3839 const DisplayDeviceState& state,
3840 const sp<compositionengine::DisplaySurface>& displaySurface,
3841 const sp<IGraphicBufferProducer>& producer) {
3842 DisplayDeviceCreationArgs creationArgs(sp<SurfaceFlinger>::fromExisting(this), getHwComposer(),
3843 displayToken, compositionDisplay);
3844 creationArgs.sequenceId = state.sequenceId;
3845 creationArgs.isSecure = state.isSecure;
3846 creationArgs.isProtected = state.isProtected;
3847 creationArgs.displaySurface = displaySurface;
3848 creationArgs.hasWideColorGamut = false;
3849 creationArgs.supportedPerFrameMetadata = 0;
3850
3851 if (const auto physicalIdOpt =
3852 compositionDisplay->getDisplayIdVariant().and_then(asPhysicalDisplayId)) {
3853 const auto physicalId = *physicalIdOpt;
3854
3855 creationArgs.isPrimary = physicalId == getPrimaryDisplayIdLocked();
3856 creationArgs.refreshRateSelector =
3857 FTL_FAKE_GUARD(kMainThreadContext,
3858 mDisplayModeController.selectorPtrFor(physicalId));
3859 creationArgs.physicalOrientation =
3860 getPhysicalDisplayOrientation(physicalId, creationArgs.isPrimary);
3861 ALOGV("Display Orientation: %s", toCString(creationArgs.physicalOrientation));
3862
3863 mPhysicalDisplays.get(physicalId)
3864 .transform(&PhysicalDisplay::snapshotRef)
3865 .transform(ftl::unit_fn([&](const display::DisplaySnapshot& snapshot) {
3866 for (const auto mode : snapshot.colorModes()) {
3867 creationArgs.hasWideColorGamut |= ui::isWideColorMode(mode);
3868 creationArgs.hwcColorModes
3869 .emplace(mode, getHwComposer().getRenderIntents(physicalId, mode));
3870 }
3871 }));
3872 }
3873
3874 if (const auto id = compositionDisplay->getDisplayIdVariant().and_then(
3875 asHalDisplayId<DisplayIdVariant>)) {
3876 getHwComposer().getHdrCapabilities(*id, &creationArgs.hdrCapabilities);
3877 creationArgs.supportedPerFrameMetadata = getHwComposer().getSupportedPerFrameMetadata(*id);
3878 }
3879
3880 auto nativeWindowSurface = getFactory().createNativeWindowSurface(producer);
3881 auto nativeWindow = nativeWindowSurface->getNativeWindow();
3882 creationArgs.nativeWindow = nativeWindow;
3883
3884 // Make sure that composition can never be stalled by a virtual display
3885 // consumer that isn't processing buffers fast enough. We have to do this
3886 // here, in case the display is composed entirely by HWC.
3887 if (state.isVirtual()) {
3888 nativeWindow->setSwapInterval(nativeWindow.get(), 0);
3889 }
3890
3891 if (FlagManager::getInstance().correct_virtual_display_power_state()) {
3892 creationArgs.initialPowerMode = state.initialPowerMode;
3893 } else {
3894 creationArgs.initialPowerMode =
3895 state.isVirtual() ? hal::PowerMode::ON : hal::PowerMode::OFF;
3896 }
3897
3898 creationArgs.requestedRefreshRate = state.requestedRefreshRate;
3899
3900 sp<DisplayDevice> display = getFactory().createDisplayDevice(creationArgs);
3901
3902 nativeWindowSurface->preallocateBuffers();
3903
3904 ui::ColorMode defaultColorMode = ui::ColorMode::NATIVE;
3905 Dataspace defaultDataSpace = Dataspace::UNKNOWN;
3906 if (display->hasWideColorGamut()) {
3907 defaultColorMode = ui::ColorMode::SRGB;
3908 defaultDataSpace = Dataspace::V0_SRGB;
3909 }
3910 display->getCompositionDisplay()->setColorProfile(
3911 compositionengine::Output::ColorProfile{defaultColorMode, defaultDataSpace,
3912 RenderIntent::COLORIMETRIC});
3913
3914 if (const auto& physical = state.physical) {
3915 const auto& mode = *physical->activeMode;
3916 mDisplayModeController.setActiveMode(physical->id, mode.getId(), mode.getVsyncRate(),
3917 mode.getPeakFps());
3918 }
3919
3920 display->setLayerFilter(
3921 makeLayerFilterForDisplay(display->getDisplayIdVariant(), state.layerStack));
3922 display->setProjection(state.orientation, state.layerStackSpaceRect,
3923 state.orientedDisplaySpaceRect);
3924 display->setDisplayName(state.displayName);
3925 display->setOptimizationPolicy(state.optimizationPolicy);
3926 display->setFlags(state.flags);
3927
3928 return display;
3929 }
3930
incRefreshableDisplays()3931 void SurfaceFlinger::incRefreshableDisplays() {
3932 if (FlagManager::getInstance().no_vsyncs_on_screen_off()) {
3933 mRefreshableDisplays++;
3934 if (mRefreshableDisplays == 1) {
3935 ftl::FakeGuard guard(kMainThreadContext);
3936 mScheduler->omitVsyncDispatching(false);
3937 }
3938 }
3939 }
3940
decRefreshableDisplays()3941 void SurfaceFlinger::decRefreshableDisplays() {
3942 if (FlagManager::getInstance().no_vsyncs_on_screen_off()) {
3943 mRefreshableDisplays--;
3944 if (mRefreshableDisplays == 0) {
3945 ftl::FakeGuard guard(kMainThreadContext);
3946 mScheduler->omitVsyncDispatching(true);
3947 }
3948 }
3949 }
3950
processDisplayAdded(const wp<IBinder> & displayToken,const DisplayDeviceState & state)3951 void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
3952 const DisplayDeviceState& state) {
3953 ui::Size resolution(0, 0);
3954 ui::PixelFormat pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_UNKNOWN);
3955 if (state.physical) {
3956 resolution = state.physical->activeMode->getResolution();
3957 pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888);
3958 } else if (state.surface != nullptr) {
3959 int status = state.surface->query(NATIVE_WINDOW_WIDTH, &resolution.width);
3960 ALOGE_IF(status != NO_ERROR, "Unable to query width (%d)", status);
3961 status = state.surface->query(NATIVE_WINDOW_HEIGHT, &resolution.height);
3962 ALOGE_IF(status != NO_ERROR, "Unable to query height (%d)", status);
3963 int format;
3964 status = state.surface->query(NATIVE_WINDOW_FORMAT, &format);
3965 ALOGE_IF(status != NO_ERROR, "Unable to query format (%d)", status);
3966 pixelFormat = static_cast<ui::PixelFormat>(format);
3967 } else {
3968 // Virtual displays without a surface are dormant:
3969 // they have external state (layer stack, projection,
3970 // etc.) but no internal state (i.e. a DisplayDevice).
3971 ALOGD("Not adding dormant virtual display with token %p: %s", displayToken.unsafe_get(),
3972 state.displayName.c_str());
3973 return;
3974 }
3975
3976 compositionengine::DisplayCreationArgsBuilder builder;
3977 std::optional<VirtualDisplayIdVariant> virtualDisplayIdVariantOpt;
3978 if (const auto& physical = state.physical) {
3979 builder.setId(physical->id);
3980 } else {
3981 virtualDisplayIdVariantOpt =
3982 acquireVirtualDisplay(resolution, pixelFormat, state.uniqueId, builder);
3983 }
3984
3985 builder.setPixels(resolution);
3986 builder.setIsSecure(state.isSecure);
3987 builder.setIsProtected(state.isProtected);
3988 builder.setHasPictureProcessing(state.hasPictureProcessing);
3989 builder.setMaxLayerPictureProfiles(state.maxLayerPictureProfiles);
3990 builder.setPowerAdvisor(mPowerAdvisor.get());
3991 builder.setName(state.displayName);
3992 auto compositionDisplay = getCompositionEngine().createDisplay(builder.build());
3993 compositionDisplay->setLayerCachingEnabled(mLayerCachingEnabled);
3994
3995 sp<compositionengine::DisplaySurface> displaySurface;
3996 sp<IGraphicBufferProducer> producer;
3997 sp<IGraphicBufferProducer> bqProducer;
3998 sp<IGraphicBufferConsumer> bqConsumer;
3999 getFactory().createBufferQueue(&bqProducer, &bqConsumer, /*consumerIsSurfaceFlinger =*/false);
4000
4001 if (state.isVirtual()) {
4002 LOG_FATAL_IF(!virtualDisplayIdVariantOpt);
4003 auto surface = sp<VirtualDisplaySurface>::make(getHwComposer(), *virtualDisplayIdVariantOpt,
4004 state.surface, bqProducer, bqConsumer,
4005 state.displayName);
4006 displaySurface = surface;
4007 producer = std::move(surface);
4008 } else {
4009 ALOGE_IF(state.surface != nullptr,
4010 "adding a supported display, but rendering "
4011 "surface is provided (%p), ignoring it",
4012 state.surface.get());
4013 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
4014 const auto frameBufferSurface =
4015 sp<FramebufferSurface>::make(getHwComposer(), state.physical->id, bqProducer,
4016 bqConsumer,
4017 state.physical->activeMode->getResolution(),
4018 ui::Size(maxGraphicsWidth, maxGraphicsHeight));
4019 displaySurface = frameBufferSurface;
4020 producer = frameBufferSurface->getSurface()->getIGraphicBufferProducer();
4021 #else
4022 displaySurface =
4023 sp<FramebufferSurface>::make(getHwComposer(), state.physical->id, bqConsumer,
4024 state.physical->activeMode->getResolution(),
4025 ui::Size(maxGraphicsWidth, maxGraphicsHeight));
4026 producer = bqProducer;
4027 #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
4028 }
4029
4030 LOG_FATAL_IF(!displaySurface);
4031 auto display = setupNewDisplayDeviceInternal(displayToken, std::move(compositionDisplay), state,
4032 displaySurface, producer);
4033
4034 if (mScheduler && !display->isVirtual()) {
4035 // For hotplug reconnect, renew the registration since display modes have been reloaded.
4036 mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector(),
4037 mActiveDisplayId);
4038 }
4039
4040 if (display->isVirtual()) {
4041 display->adjustRefreshRate(mScheduler->getPacesetterRefreshRate());
4042 }
4043
4044 if (display->isRefreshable()) {
4045 incRefreshableDisplays();
4046 }
4047
4048 if (FlagManager::getInstance().correct_virtual_display_power_state()) {
4049 applyOptimizationPolicy(__func__);
4050 }
4051
4052 mDisplays.try_emplace(displayToken, std::move(display));
4053
4054 // For an external display, loadDisplayModes already attempted to select the same mode
4055 // as DM, but SF still needs to be updated to match.
4056 // TODO (b/318534874): Let DM decide the initial mode.
4057 if (const auto& physical = state.physical; mScheduler && physical) {
4058 const bool isInternalDisplay = mPhysicalDisplays.get(physical->id)
4059 .transform(&PhysicalDisplay::isInternal)
4060 .value_or(false);
4061
4062 if (!isInternalDisplay) {
4063 auto activeModePtr = physical->activeMode;
4064 const auto fps = activeModePtr->getPeakFps();
4065
4066 setDesiredMode(
4067 {.mode = scheduler::FrameRateMode{fps,
4068 ftl::as_non_null(std::move(activeModePtr))},
4069 .emitEvent = false,
4070 .force = true});
4071 }
4072 }
4073 }
4074
processDisplayRemoved(const wp<IBinder> & displayToken)4075 void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
4076 auto display = getDisplayDeviceLocked(displayToken);
4077 if (display) {
4078 display->disconnect();
4079
4080 if (const auto virtualDisplayIdVariant = display->getVirtualDisplayIdVariant()) {
4081 releaseVirtualDisplay(*virtualDisplayIdVariant);
4082 } else {
4083 mScheduler->unregisterDisplay(display->getPhysicalId(), mActiveDisplayId);
4084 }
4085
4086 if (display->isRefreshable()) {
4087 decRefreshableDisplays();
4088 }
4089 }
4090
4091 mDisplays.erase(displayToken);
4092
4093 if (display && display->isVirtual()) {
4094 static_cast<void>(mScheduler->schedule([display = std::move(display)] {
4095 // Destroy the display without holding the mStateLock.
4096 // This is a temporary solution until we can manage transaction queues without
4097 // holding the mStateLock.
4098 // With blast, the IGBP that is passed to the VirtualDisplaySurface is owned by the
4099 // client. When the IGBP is disconnected, its buffer cache in SF will be cleared
4100 // via SurfaceComposerClient::doUncacheBufferTransaction. This call from the client
4101 // ends up running on the main thread causing a deadlock since setTransactionstate
4102 // will try to acquire the mStateLock. Instead we extend the lifetime of
4103 // DisplayDevice and destroy it in the main thread without holding the mStateLock.
4104 // The display will be disconnected and removed from the mDisplays list so it will
4105 // not be accessible.
4106 }));
4107 }
4108
4109 if (FlagManager::getInstance().correct_virtual_display_power_state()) {
4110 applyOptimizationPolicy(__func__);
4111 }
4112 }
4113
processDisplayChanged(const wp<IBinder> & displayToken,const DisplayDeviceState & currentState,const DisplayDeviceState & drawingState)4114 void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken,
4115 const DisplayDeviceState& currentState,
4116 const DisplayDeviceState& drawingState) {
4117 const sp<IBinder> currentBinder = IInterface::asBinder(currentState.surface);
4118 const sp<IBinder> drawingBinder = IInterface::asBinder(drawingState.surface);
4119
4120 // Recreate the DisplayDevice if the surface or sequence ID changed.
4121 if (currentBinder != drawingBinder || currentState.sequenceId != drawingState.sequenceId) {
4122 if (const auto display = getDisplayDeviceLocked(displayToken)) {
4123 display->disconnect();
4124 if (const auto virtualDisplayIdVariant = display->getVirtualDisplayIdVariant()) {
4125 releaseVirtualDisplay(*virtualDisplayIdVariant);
4126 }
4127
4128 if (display->isRefreshable()) {
4129 decRefreshableDisplays();
4130 }
4131 }
4132
4133 mDisplays.erase(displayToken);
4134
4135 if (const auto& physical = currentState.physical) {
4136 getHwComposer().allocatePhysicalDisplay(physical->hwcDisplayId, physical->id,
4137 physical->port, /*physicalSize=*/std::nullopt);
4138 }
4139
4140 processDisplayAdded(displayToken, currentState);
4141
4142 if (currentState.physical) {
4143 const auto display = getDisplayDeviceLocked(displayToken);
4144 if (!mSkipPowerOnForQuiescent) {
4145 setPhysicalDisplayPowerMode(display, hal::PowerMode::ON);
4146 }
4147
4148 if (display->getPhysicalId() == mActiveDisplayId) {
4149 onActiveDisplayChangedLocked(nullptr, *display);
4150 }
4151 }
4152 return;
4153 }
4154
4155 if (const auto display = getDisplayDeviceLocked(displayToken)) {
4156 if (currentState.layerStack != drawingState.layerStack) {
4157 display->setLayerFilter(makeLayerFilterForDisplay(display->getDisplayIdVariant(),
4158 currentState.layerStack));
4159 }
4160 if (currentState.flags != drawingState.flags) {
4161 display->setFlags(currentState.flags);
4162 }
4163
4164 const auto updateDisplaySize = [&]() {
4165 if (currentState.width != drawingState.width ||
4166 currentState.height != drawingState.height) {
4167 const ui::Size resolution = ui::Size(currentState.width, currentState.height);
4168
4169 // Resize the framebuffer. For a virtual display, always do so. For a physical
4170 // display, only do so if it has a pending modeset for the matching resolution.
4171 if (!currentState.physical ||
4172 (FlagManager::getInstance().synced_resolution_switch() &&
4173 mDisplayModeController.getDesiredMode(display->getPhysicalId())
4174 .transform([resolution](const auto& request) {
4175 return resolution == request.mode.modePtr->getResolution();
4176 })
4177 .value_or(false))) {
4178 display->setDisplaySize(resolution);
4179 }
4180
4181 if (display->getId() == mActiveDisplayId) {
4182 onActiveDisplaySizeChanged(*display);
4183 }
4184 }
4185 };
4186
4187 if (FlagManager::getInstance().synced_resolution_switch()) {
4188 // Update display size first, as display projection below depends on it.
4189 updateDisplaySize();
4190 }
4191
4192 if ((currentState.orientation != drawingState.orientation) ||
4193 (currentState.layerStackSpaceRect != drawingState.layerStackSpaceRect) ||
4194 (currentState.orientedDisplaySpaceRect != drawingState.orientedDisplaySpaceRect)) {
4195 display->setProjection(currentState.orientation, currentState.layerStackSpaceRect,
4196 currentState.orientedDisplaySpaceRect);
4197 if (display->getId() == mActiveDisplayId) {
4198 mActiveDisplayTransformHint = display->getTransformHint();
4199 sActiveDisplayRotationFlags =
4200 ui::Transform::toRotationFlags(display->getOrientation());
4201 }
4202 }
4203
4204 if (!FlagManager::getInstance().synced_resolution_switch()) {
4205 updateDisplaySize();
4206 }
4207 }
4208 }
4209
processDisplayChangesLocked()4210 void SurfaceFlinger::processDisplayChangesLocked() {
4211 // here we take advantage of Vector's copy-on-write semantics to
4212 // improve performance by skipping the transaction entirely when
4213 // know that the lists are identical
4214 const KeyedVector<wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
4215 const KeyedVector<wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
4216 if (!curr.isIdenticalTo(draw)) {
4217 mVisibleRegionsDirty = true;
4218 mUpdateInputInfo = true;
4219
4220 // Apply the current color matrix to any added or changed display.
4221 mCurrentState.colorMatrixChanged = true;
4222
4223 // find the displays that were removed
4224 // (ie: in drawing state but not in current state)
4225 // also handle displays that changed
4226 // (ie: displays that are in both lists)
4227 for (size_t i = 0; i < draw.size(); i++) {
4228 const wp<IBinder>& displayToken = draw.keyAt(i);
4229 const ssize_t j = curr.indexOfKey(displayToken);
4230 if (j < 0) {
4231 // in drawing state but not in current state
4232 processDisplayRemoved(displayToken);
4233 } else {
4234 // this display is in both lists. see if something changed.
4235 const DisplayDeviceState& currentState = curr[j];
4236 const DisplayDeviceState& drawingState = draw[i];
4237 processDisplayChanged(displayToken, currentState, drawingState);
4238 }
4239 }
4240
4241 // find displays that were added
4242 // (ie: in current state but not in drawing state)
4243 for (size_t i = 0; i < curr.size(); i++) {
4244 const wp<IBinder>& displayToken = curr.keyAt(i);
4245 if (draw.indexOfKey(displayToken) < 0) {
4246 processDisplayAdded(displayToken, curr[i]);
4247 }
4248 }
4249 }
4250
4251 mDrawingState.displays = mCurrentState.displays;
4252 }
4253
commitTransactionsLocked(uint32_t transactionFlags)4254 void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) {
4255 // Commit display transactions.
4256 const bool displayTransactionNeeded = transactionFlags & eDisplayTransactionNeeded;
4257 mFrontEndDisplayInfosChanged = displayTransactionNeeded;
4258
4259 if (mSomeChildrenChanged) {
4260 mVisibleRegionsDirty = true;
4261 mSomeChildrenChanged = false;
4262 mUpdateInputInfo = true;
4263 }
4264
4265 if (mLayersAdded) {
4266 mLayersAdded = false;
4267 // Layers have been added.
4268 mVisibleRegionsDirty = true;
4269 mUpdateInputInfo = true;
4270 }
4271
4272 // some layers might have been removed, so
4273 // we need to update the regions they're exposing.
4274 if (mLayersRemoved) {
4275 mLayersRemoved = false;
4276 mVisibleRegionsDirty = true;
4277 mUpdateInputInfo = true;
4278 }
4279
4280 if (transactionFlags & eInputInfoUpdateNeeded) {
4281 mUpdateInputInfo = true;
4282 }
4283
4284 doCommitTransactions();
4285 }
4286
updateInputFlinger(VsyncId vsyncId,TimePoint frameTime)4287 void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId, TimePoint frameTime) {
4288 if (!mInputFlinger || (!mUpdateInputInfo && mInputWindowCommands.empty())) {
4289 return;
4290 }
4291 SFTRACE_CALL();
4292
4293 std::vector<WindowInfo> windowInfos;
4294 std::vector<DisplayInfo> displayInfos;
4295 bool updateWindowInfo = false;
4296 if (mUpdateInputInfo) {
4297 mUpdateInputInfo = false;
4298 updateWindowInfo = true;
4299 buildWindowInfos(windowInfos, displayInfos);
4300 }
4301
4302 std::unordered_set<int32_t> visibleWindowIds;
4303 for (WindowInfo& windowInfo : windowInfos) {
4304 if (!windowInfo.inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
4305 visibleWindowIds.insert(windowInfo.id);
4306 }
4307 }
4308 bool visibleWindowsChanged = false;
4309 if (visibleWindowIds != mVisibleWindowIds) {
4310 visibleWindowsChanged = true;
4311 mVisibleWindowIds = std::move(visibleWindowIds);
4312 }
4313
4314 BackgroundExecutor::getInstance().sendCallbacks(
4315 {[updateWindowInfo, windowInfos = std::move(windowInfos),
4316 displayInfos = std::move(displayInfos),
4317 inputWindowCommands = std::move(mInputWindowCommands), inputFlinger = mInputFlinger,
4318 this, visibleWindowsChanged, vsyncId, frameTime]() mutable {
4319 SFTRACE_NAME("BackgroundExecutor::updateInputFlinger");
4320 if (updateWindowInfo) {
4321 mWindowInfosListenerInvoker
4322 ->windowInfosChanged(gui::WindowInfosUpdate{std::move(windowInfos),
4323 std::move(displayInfos),
4324 ftl::to_underlying(vsyncId),
4325 frameTime.ns()},
4326 inputWindowCommands.releaseListeners(),
4327 /* forceImmediateCall= */ visibleWindowsChanged ||
4328 !inputWindowCommands.getFocusRequests()
4329 .empty());
4330 } else {
4331 // If there are listeners but no changes to input windows, call the listeners
4332 // immediately.
4333 for (const auto& listener : inputWindowCommands.getListeners()) {
4334 if (IInterface::asBinder(listener)->isBinderAlive()) {
4335 listener->onWindowInfosReported();
4336 }
4337 }
4338 }
4339 for (const auto& focusRequest : inputWindowCommands.getFocusRequests()) {
4340 inputFlinger->setFocusedWindow(focusRequest);
4341 }
4342 }});
4343
4344 mInputWindowCommands.clear();
4345 }
4346
persistDisplayBrightness(bool needsComposite)4347 void SurfaceFlinger::persistDisplayBrightness(bool needsComposite) {
4348 const bool supportsDisplayBrightnessCommand = getHwComposer().getComposer()->isSupported(
4349 Hwc2::Composer::OptionalFeature::DisplayBrightnessCommand);
4350 if (!supportsDisplayBrightnessCommand) {
4351 return;
4352 }
4353
4354 for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
4355 if (const auto brightness = display->getStagedBrightness(); brightness) {
4356 if (!needsComposite) {
4357 const status_t error =
4358 getHwComposer()
4359 .setDisplayBrightness(display->getPhysicalId(), *brightness,
4360 display->getCompositionDisplay()
4361 ->getState()
4362 .displayBrightnessNits,
4363 Hwc2::Composer::DisplayBrightnessOptions{
4364 .applyImmediately = true})
4365 .get();
4366
4367 ALOGE_IF(error != NO_ERROR,
4368 "Error setting display brightness for display %s: %d (%s)",
4369 to_string(display->getId()).c_str(), error, strerror(error));
4370 }
4371 display->persistBrightness(needsComposite);
4372 }
4373 }
4374 }
4375
buildWindowInfos(std::vector<WindowInfo> & outWindowInfos,std::vector<DisplayInfo> & outDisplayInfos)4376 void SurfaceFlinger::buildWindowInfos(std::vector<WindowInfo>& outWindowInfos,
4377 std::vector<DisplayInfo>& outDisplayInfos) {
4378 static size_t sNumWindowInfos = 0;
4379 outWindowInfos.reserve(sNumWindowInfos);
4380 sNumWindowInfos = 0;
4381
4382 mLayerSnapshotBuilder.forEachInputSnapshot(
4383 [&outWindowInfos](const frontend::LayerSnapshot& snapshot) {
4384 outWindowInfos.push_back(snapshot.inputInfo);
4385 });
4386
4387 sNumWindowInfos = outWindowInfos.size();
4388
4389 outDisplayInfos.reserve(mFrontEndDisplayInfos.size());
4390 for (const auto& [_, info] : mFrontEndDisplayInfos) {
4391 outDisplayInfos.push_back(info.info);
4392 }
4393 }
4394
updateCursorAsync()4395 void SurfaceFlinger::updateCursorAsync() {
4396 compositionengine::CompositionRefreshArgs refreshArgs;
4397 for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
4398 if (asHalDisplayId(display->getDisplayIdVariant())) {
4399 refreshArgs.outputs.push_back(display->getCompositionDisplay());
4400 }
4401 }
4402
4403 constexpr bool kCursorOnly = true;
4404 const auto layers = moveSnapshotsToCompositionArgs(refreshArgs, kCursorOnly);
4405 mCompositionEngine->updateCursorAsync(refreshArgs);
4406 moveSnapshotsFromCompositionArgs(refreshArgs, layers);
4407 }
4408
requestHardwareVsync(PhysicalDisplayId displayId,bool enable)4409 void SurfaceFlinger::requestHardwareVsync(PhysicalDisplayId displayId, bool enable) {
4410 getHwComposer().setVsyncEnabled(displayId, enable ? hal::Vsync::ENABLE : hal::Vsync::DISABLE);
4411 }
4412
requestDisplayModes(std::vector<display::DisplayModeRequest> modeRequests)4413 void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest> modeRequests) {
4414 if (mBootStage != BootStage::FINISHED) {
4415 ALOGV("Currently in the boot stage, skipping display mode changes");
4416 return;
4417 }
4418
4419 SFTRACE_CALL();
4420
4421 // If this is called from the main thread mStateLock must be locked before
4422 // Currently the only way to call this function from the main thread is from
4423 // Scheduler::chooseRefreshRateForContent
4424
4425 ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId);
4426
4427 for (auto& request : modeRequests) {
4428 const auto& modePtr = request.mode.modePtr;
4429
4430 const auto displayId = modePtr->getPhysicalDisplayId();
4431 const auto display = getDisplayDeviceLocked(displayId);
4432
4433 if (!display) continue;
4434
4435 if (display->refreshRateSelector().isModeAllowed(request.mode)) {
4436 setDesiredMode(std::move(request));
4437 } else {
4438 ALOGV("%s: Mode %d is disallowed for display %s", __func__,
4439 ftl::to_underlying(modePtr->getId()), to_string(displayId).c_str());
4440 }
4441 }
4442 }
4443
notifyCpuLoadUp()4444 void SurfaceFlinger::notifyCpuLoadUp() {
4445 mPowerAdvisor->notifyCpuLoadUp();
4446 }
4447
onChoreographerAttached()4448 void SurfaceFlinger::onChoreographerAttached() {
4449 SFTRACE_CALL();
4450 mUpdateAttachedChoreographer = true;
4451 scheduleCommit(FrameHint::kNone);
4452 }
4453
onExpectedPresentTimePosted(TimePoint expectedPresentTime,ftl::NonNull<DisplayModePtr> modePtr,Fps renderRate)4454 void SurfaceFlinger::onExpectedPresentTimePosted(TimePoint expectedPresentTime,
4455 ftl::NonNull<DisplayModePtr> modePtr,
4456 Fps renderRate) {
4457 const auto vsyncPeriod = modePtr->getVsyncRate().getPeriod();
4458 const auto timeoutOpt = [&]() -> std::optional<Period> {
4459 const auto vrrConfig = modePtr->getVrrConfig();
4460 if (!vrrConfig) return std::nullopt;
4461
4462 const auto notifyExpectedPresentConfig =
4463 modePtr->getVrrConfig()->notifyExpectedPresentConfig;
4464 if (!notifyExpectedPresentConfig) return std::nullopt;
4465 return Period::fromNs(notifyExpectedPresentConfig->timeoutNs);
4466 }();
4467
4468 notifyExpectedPresentIfRequired(modePtr->getPhysicalDisplayId(), vsyncPeriod,
4469 expectedPresentTime, renderRate, timeoutOpt);
4470 }
4471
notifyExpectedPresentIfRequired(PhysicalDisplayId displayId,Period vsyncPeriod,TimePoint expectedPresentTime,Fps frameInterval,std::optional<Period> timeoutOpt)4472 void SurfaceFlinger::notifyExpectedPresentIfRequired(PhysicalDisplayId displayId,
4473 Period vsyncPeriod,
4474 TimePoint expectedPresentTime,
4475 Fps frameInterval,
4476 std::optional<Period> timeoutOpt) {
4477 auto& data = mNotifyExpectedPresentMap[displayId];
4478 const auto lastExpectedPresentTimestamp = data.lastExpectedPresentTimestamp;
4479 const auto lastFrameInterval = data.lastFrameInterval;
4480 data.lastFrameInterval = frameInterval;
4481 data.lastExpectedPresentTimestamp = expectedPresentTime;
4482 const auto threshold = Duration::fromNs(vsyncPeriod.ns() / 2);
4483
4484 const constexpr nsecs_t kOneSecondNs =
4485 std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
4486 const auto timeout =
4487 Period::fromNs(timeoutOpt && timeoutOpt->ns() > 0 ? timeoutOpt->ns() : kOneSecondNs);
4488 const bool frameIntervalIsOnCadence =
4489 isFrameIntervalOnCadence(expectedPresentTime, lastExpectedPresentTimestamp,
4490 lastFrameInterval, timeout, threshold);
4491
4492 const bool expectedPresentWithinTimeout =
4493 isExpectedPresentWithinTimeout(expectedPresentTime, lastExpectedPresentTimestamp,
4494 timeoutOpt, threshold);
4495 if (expectedPresentWithinTimeout && frameIntervalIsOnCadence) {
4496 return;
4497 }
4498
4499 auto hintStatus = data.hintStatus.load();
4500 if (!expectedPresentWithinTimeout) {
4501 if ((hintStatus != NotifyExpectedPresentHintStatus::Sent &&
4502 hintStatus != NotifyExpectedPresentHintStatus::ScheduleOnTx) ||
4503 (timeoutOpt && timeoutOpt->ns() == 0)) {
4504 // Send the hint immediately if timeout, as the hint gets
4505 // delayed otherwise, as the frame is scheduled close
4506 // to the actual present.
4507 if (data.hintStatus
4508 .compare_exchange_strong(hintStatus,
4509 NotifyExpectedPresentHintStatus::ScheduleOnTx)) {
4510 scheduleNotifyExpectedPresentHint(displayId);
4511 return;
4512 }
4513 }
4514 }
4515
4516 if (hintStatus == NotifyExpectedPresentHintStatus::Sent &&
4517 data.hintStatus.compare_exchange_strong(hintStatus,
4518 NotifyExpectedPresentHintStatus::ScheduleOnTx)) {
4519 return;
4520 }
4521 if (hintStatus != NotifyExpectedPresentHintStatus::Start) {
4522 return;
4523 }
4524 data.hintStatus.store(NotifyExpectedPresentHintStatus::ScheduleOnPresent);
4525 mScheduler->scheduleFrame();
4526 }
4527
scheduleNotifyExpectedPresentHint(PhysicalDisplayId displayId,VsyncId vsyncId)4528 void SurfaceFlinger::scheduleNotifyExpectedPresentHint(PhysicalDisplayId displayId,
4529 VsyncId vsyncId) {
4530 auto itr = mNotifyExpectedPresentMap.find(displayId);
4531 if (itr == mNotifyExpectedPresentMap.end()) {
4532 return;
4533 }
4534
4535 const char* const whence = __func__;
4536 const auto sendHint = [=, this]() {
4537 auto& data = mNotifyExpectedPresentMap.at(displayId);
4538 TimePoint expectedPresentTime = data.lastExpectedPresentTimestamp;
4539 if (ftl::to_underlying(vsyncId) != FrameTimelineInfo::INVALID_VSYNC_ID) {
4540 const auto predictionOpt = mFrameTimeline->getTokenManager()->getPredictionsForToken(
4541 ftl::to_underlying(vsyncId));
4542 const auto expectedPresentTimeOnPredictor = TimePoint::fromNs(
4543 predictionOpt ? predictionOpt->presentTime : expectedPresentTime.ns());
4544 const auto scheduledFrameResultOpt = mScheduler->getScheduledFrameResult();
4545 const auto expectedPresentTimeOnScheduler = scheduledFrameResultOpt.has_value()
4546 ? scheduledFrameResultOpt->vsyncTime
4547 : TimePoint::fromNs(0);
4548 expectedPresentTime =
4549 std::max(expectedPresentTimeOnPredictor, expectedPresentTimeOnScheduler);
4550 }
4551
4552 if (expectedPresentTime < TimePoint::now()) {
4553 expectedPresentTime =
4554 mScheduler->getVsyncSchedule()->vsyncDeadlineAfter(TimePoint::now());
4555 if (mScheduler->vsyncModulator().getVsyncConfig().sfWorkDuration >
4556 mScheduler->getVsyncSchedule(displayId)->period()) {
4557 expectedPresentTime += mScheduler->getVsyncSchedule(displayId)->period();
4558 }
4559 }
4560 const auto status = getHwComposer().notifyExpectedPresent(displayId, expectedPresentTime,
4561 data.lastFrameInterval);
4562 if (status != NO_ERROR) {
4563 ALOGE("%s failed to notifyExpectedPresentHint for display %" PRId64, whence,
4564 displayId.value);
4565 }
4566 };
4567
4568 if (itr->second.hintStatus == NotifyExpectedPresentHintStatus::ScheduleOnTx) {
4569 return static_cast<void>(mScheduler->schedule([=,
4570 this]() FTL_FAKE_GUARD(kMainThreadContext) {
4571 auto& data = mNotifyExpectedPresentMap.at(displayId);
4572 auto scheduleHintOnTx = NotifyExpectedPresentHintStatus::ScheduleOnTx;
4573 if (data.hintStatus.compare_exchange_strong(scheduleHintOnTx,
4574 NotifyExpectedPresentHintStatus::Sent)) {
4575 sendHint();
4576 constexpr bool kAllowToEnable = true;
4577 mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable);
4578 }
4579 }));
4580 }
4581 auto scheduleHintOnPresent = NotifyExpectedPresentHintStatus::ScheduleOnPresent;
4582 if (itr->second.hintStatus.compare_exchange_strong(scheduleHintOnPresent,
4583 NotifyExpectedPresentHintStatus::Sent)) {
4584 sendHint();
4585 }
4586 }
4587
sendNotifyExpectedPresentHint(PhysicalDisplayId displayId)4588 void SurfaceFlinger::sendNotifyExpectedPresentHint(PhysicalDisplayId displayId) {
4589 if (auto itr = mNotifyExpectedPresentMap.find(displayId);
4590 itr == mNotifyExpectedPresentMap.end() ||
4591 itr->second.hintStatus != NotifyExpectedPresentHintStatus::ScheduleOnPresent) {
4592 return;
4593 }
4594 scheduleNotifyExpectedPresentHint(displayId);
4595 }
4596
onCommitNotComposited()4597 void SurfaceFlinger::onCommitNotComposited() {
4598 if (FlagManager::getInstance().commit_not_composited()) {
4599 mFrameTimeline->onCommitNotComposited();
4600 }
4601 }
4602
initScheduler(const sp<const DisplayDevice> & display)4603 void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {
4604 using namespace scheduler;
4605
4606 LOG_ALWAYS_FATAL_IF(mScheduler);
4607
4608 const auto activeMode = display->refreshRateSelector().getActiveMode();
4609 const Fps activeRefreshRate = activeMode.fps;
4610
4611 FeatureFlags features;
4612
4613 const auto defaultContentDetectionValue =
4614 FlagManager::getInstance().enable_fro_dependent_features() &&
4615 sysprop::enable_frame_rate_override(true);
4616 if (sysprop::use_content_detection_for_refresh_rate(defaultContentDetectionValue)) {
4617 features |= Feature::kContentDetection;
4618 if (FlagManager::getInstance().enable_small_area_detection()) {
4619 features |= Feature::kSmallDirtyContentDetection;
4620 }
4621 }
4622 if (base::GetBoolProperty("debug.sf.show_predicted_vsync"s, false)) {
4623 features |= Feature::kTracePredictedVsync;
4624 }
4625 if (!base::GetBoolProperty("debug.sf.vsync_reactor_ignore_present_fences"s, false) &&
4626 mHasReliablePresentFences) {
4627 features |= Feature::kPresentFences;
4628 }
4629 if (display->refreshRateSelector().kernelIdleTimerController()) {
4630 features |= Feature::kKernelIdleTimer;
4631 }
4632 if (mBackpressureGpuComposition) {
4633 features |= Feature::kBackpressureGpuComposition;
4634 }
4635 if (getHwComposer().getComposer()->isSupported(
4636 Hwc2::Composer::OptionalFeature::ExpectedPresentTime)) {
4637 features |= Feature::kExpectedPresentTime;
4638 }
4639
4640 mScheduler = std::make_unique<Scheduler>(static_cast<ICompositor&>(*this),
4641 static_cast<ISchedulerCallback&>(*this), features,
4642 getFactory(), activeRefreshRate, *mTimeStats);
4643
4644 // The pacesetter must be registered before EventThread creation below.
4645 mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector(),
4646 mActiveDisplayId);
4647 if (FlagManager::getInstance().vrr_config()) {
4648 mScheduler->setRenderRate(display->getPhysicalId(), activeMode.fps,
4649 /*applyImmediately*/ true);
4650 }
4651
4652 const auto configs = mScheduler->getCurrentVsyncConfigs();
4653
4654 mScheduler->createEventThread(scheduler::Cycle::Render, mFrameTimeline->getTokenManager(),
4655 /* workDuration */ configs.late.appWorkDuration,
4656 /* readyDuration */ configs.late.sfWorkDuration);
4657 mScheduler->createEventThread(scheduler::Cycle::LastComposite,
4658 mFrameTimeline->getTokenManager(),
4659 /* workDuration */ activeRefreshRate.getPeriod(),
4660 /* readyDuration */ configs.late.sfWorkDuration);
4661
4662 // Dispatch after EventThread creation, since registerDisplay above skipped dispatch.
4663 mScheduler->dispatchHotplug(display->getPhysicalId(), scheduler::Scheduler::Hotplug::Connected);
4664
4665 mScheduler->initVsync(*mFrameTimeline->getTokenManager(), configs.late.sfWorkDuration);
4666
4667 mRegionSamplingThread =
4668 sp<RegionSamplingThread>::make(*this,
4669 RegionSamplingThread::EnvironmentTimingTunables());
4670 mFpsReporter = sp<FpsReporter>::make(*mFrameTimeline);
4671
4672 // Timer callbacks may fire, so do this last.
4673 mScheduler->startTimers();
4674 }
4675
doCommitTransactions()4676 void SurfaceFlinger::doCommitTransactions() {
4677 SFTRACE_CALL();
4678 mDrawingState = mCurrentState;
4679 mCurrentState.colorMatrixChanged = false;
4680 }
4681
invalidateLayerStack(const ui::LayerFilter & layerFilter,const Region & dirty)4682 void SurfaceFlinger::invalidateLayerStack(const ui::LayerFilter& layerFilter, const Region& dirty) {
4683 for (const auto& [token, displayDevice] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
4684 auto display = displayDevice->getCompositionDisplay();
4685 if (display->includesLayer(layerFilter)) {
4686 display->editState().dirtyRegion.orSelf(dirty);
4687 }
4688 }
4689 }
4690
addClientLayer(LayerCreationArgs & args,const sp<IBinder> & handle,const sp<Layer> & layer,const wp<Layer> & parent,uint32_t * outTransformHint)4691 status_t SurfaceFlinger::addClientLayer(LayerCreationArgs& args, const sp<IBinder>& handle,
4692 const sp<Layer>& layer, const wp<Layer>& parent,
4693 uint32_t* outTransformHint) {
4694 if (outTransformHint) {
4695 *outTransformHint = mActiveDisplayTransformHint;
4696 }
4697 args.parentId = LayerHandle::getLayerId(args.parentHandle.promote());
4698 args.layerIdToMirror = LayerHandle::getLayerId(args.mirrorLayerHandle.promote());
4699 {
4700 std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
4701 mCreatedLayers.emplace_back(layer);
4702 mNewLayers.emplace_back(std::make_unique<frontend::RequestedLayerState>(args));
4703 args.mirrorLayerHandle.clear();
4704 args.parentHandle.clear();
4705 mNewLayerArgs.emplace_back(std::move(args));
4706 }
4707
4708 setTransactionFlags(eTransactionNeeded);
4709 return NO_ERROR;
4710 }
4711
getTransactionFlags() const4712 uint32_t SurfaceFlinger::getTransactionFlags() const {
4713 return mTransactionFlags;
4714 }
4715
clearTransactionFlags(uint32_t mask)4716 uint32_t SurfaceFlinger::clearTransactionFlags(uint32_t mask) {
4717 uint32_t transactionFlags = mTransactionFlags.fetch_and(~mask);
4718 SFTRACE_INT("mTransactionFlags", transactionFlags);
4719 return transactionFlags & mask;
4720 }
4721
setTransactionFlags(uint32_t mask,TransactionSchedule schedule,const sp<IBinder> & applyToken,FrameHint frameHint)4722 void SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule schedule,
4723 const sp<IBinder>& applyToken, FrameHint frameHint) {
4724 mScheduler->modulateVsync({}, &VsyncModulator::setTransactionSchedule, schedule, applyToken);
4725 uint32_t transactionFlags = mTransactionFlags.fetch_or(mask);
4726 SFTRACE_INT("mTransactionFlags", transactionFlags);
4727
4728 if (const bool scheduled = transactionFlags & mask; !scheduled) {
4729 scheduleCommit(frameHint);
4730 } else if (frameHint == FrameHint::kActive) {
4731 // Even if the next frame is already scheduled, we should reset the idle timer
4732 // as a new activity just happened.
4733 mScheduler->resetIdleTimer();
4734 }
4735 }
4736
transactionReadyTimelineCheck(const TransactionHandler::TransactionFlushState & flushState)4737 TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyTimelineCheck(
4738 const TransactionHandler::TransactionFlushState& flushState) {
4739 const auto& transaction = *flushState.transaction;
4740
4741 const TimePoint desiredPresentTime = TimePoint::fromNs(transaction.desiredPresentTime);
4742 const TimePoint expectedPresentTime = mScheduler->expectedPresentTimeForPacesetter();
4743
4744 using TransactionReadiness = TransactionHandler::TransactionReadiness;
4745
4746 // Do not present if the desiredPresentTime has not passed unless it is more than
4747 // one second in the future. We ignore timestamps more than 1 second in the future
4748 // for stability reasons.
4749 if (!transaction.isAutoTimestamp && desiredPresentTime >= expectedPresentTime &&
4750 desiredPresentTime < expectedPresentTime + 1s) {
4751 SFTRACE_FORMAT("not current desiredPresentTime: %" PRId64 " expectedPresentTime: %" PRId64,
4752 desiredPresentTime, expectedPresentTime);
4753 return TransactionReadiness::NotReady;
4754 }
4755
4756 const auto vsyncId = VsyncId{transaction.frameTimelineInfo.vsyncId};
4757
4758 // Transactions with VsyncId are already throttled by the vsyncId (i.e. Choreographer issued
4759 // the vsyncId according to the frame rate override cadence) so we shouldn't throttle again
4760 // when applying the transaction. Otherwise we might throttle older transactions
4761 // incorrectly as the frame rate of SF changed before it drained the older transactions.
4762 if (ftl::to_underlying(vsyncId) == FrameTimelineInfo::INVALID_VSYNC_ID &&
4763 !mScheduler->isVsyncValid(expectedPresentTime, transaction.originUid)) {
4764 SFTRACE_FORMAT("!isVsyncValid expectedPresentTime: %" PRId64 " uid: %d",
4765 expectedPresentTime, transaction.originUid);
4766 return TransactionReadiness::NotReady;
4767 }
4768
4769 // If the client didn't specify desiredPresentTime, use the vsyncId to determine the
4770 // expected present time of this transaction.
4771 if (transaction.isAutoTimestamp && frameIsEarly(expectedPresentTime, vsyncId)) {
4772 SFTRACE_FORMAT("frameIsEarly vsyncId: %" PRId64 " expectedPresentTime: %" PRId64,
4773 transaction.frameTimelineInfo.vsyncId, expectedPresentTime);
4774 return TransactionReadiness::NotReady;
4775 }
4776
4777 return TransactionReadiness::Ready;
4778 }
4779
transactionReadyBufferCheck(const TransactionHandler::TransactionFlushState & flushState)4780 TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferCheck(
4781 const TransactionHandler::TransactionFlushState& flushState) {
4782 using TransactionReadiness = TransactionHandler::TransactionReadiness;
4783 auto ready = TransactionReadiness::Ready;
4784 flushState.transaction->traverseStatesWithBuffersWhileTrue(
4785 [&](const ResolvedComposerState& resolvedState) FTL_FAKE_GUARD(
4786 kMainThreadContext) -> bool {
4787 const frontend::RequestedLayerState* layer =
4788 mLayerLifecycleManager.getLayerFromId(resolvedState.layerId);
4789 const auto& transaction = *flushState.transaction;
4790 const auto& s = resolvedState.state;
4791 // check for barrier frames
4792 if (s.bufferData->hasBarrier) {
4793 // The current producerId is already a newer producer than the buffer that has a
4794 // barrier. This means the incoming buffer is older and we can release it here.
4795 // We don't wait on the barrier since we know that's stale information.
4796 if (layer->barrierProducerId > s.bufferData->producerId) {
4797 if (s.bufferData->releaseBufferListener) {
4798 uint32_t currentMaxAcquiredBufferCount =
4799 getMaxAcquiredBufferCountForCurrentRefreshRate(
4800 layer->ownerUid.val());
4801 SFTRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64,
4802 layer->name.c_str(), s.bufferData->frameNumber);
4803 s.bufferData->releaseBufferListener
4804 ->onReleaseBuffer({resolvedState.externalTexture->getBuffer()
4805 ->getId(),
4806 s.bufferData->frameNumber},
4807 s.bufferData->acquireFence
4808 ? s.bufferData->acquireFence
4809 : Fence::NO_FENCE,
4810 currentMaxAcquiredBufferCount);
4811 }
4812
4813 // Delete the entire state at this point and not just release the buffer
4814 // because everything associated with the Layer in this Transaction is now
4815 // out of date.
4816 SFTRACE_FORMAT("DeleteStaleBuffer %s barrierProducerId:%d > %d",
4817 layer->name.c_str(), layer->barrierProducerId,
4818 s.bufferData->producerId);
4819 return TraverseBuffersReturnValues::DELETE_AND_CONTINUE_TRAVERSAL;
4820 }
4821
4822 if (layer->barrierFrameNumber < s.bufferData->barrierFrameNumber) {
4823 const bool willApplyBarrierFrame =
4824 flushState.bufferLayersReadyToPresent.contains(s.surface.get()) &&
4825 ((flushState.bufferLayersReadyToPresent.get(s.surface.get()) >=
4826 s.bufferData->barrierFrameNumber));
4827 if (!willApplyBarrierFrame) {
4828 SFTRACE_FORMAT("NotReadyBarrier %s barrierFrameNumber:%" PRId64
4829 " > %" PRId64,
4830 layer->name.c_str(), layer->barrierFrameNumber,
4831 s.bufferData->barrierFrameNumber);
4832 ready = TransactionReadiness::NotReadyBarrier;
4833 return TraverseBuffersReturnValues::STOP_TRAVERSAL;
4834 }
4835 }
4836 }
4837
4838 // If backpressure is enabled and we already have a buffer to commit, keep
4839 // the transaction in the queue.
4840 const bool hasPendingBuffer =
4841 flushState.bufferLayersReadyToPresent.contains(s.surface.get());
4842 if (layer->backpressureEnabled() && hasPendingBuffer &&
4843 transaction.isAutoTimestamp) {
4844 SFTRACE_FORMAT("hasPendingBuffer %s", layer->name.c_str());
4845 ready = TransactionReadiness::NotReady;
4846 return TraverseBuffersReturnValues::STOP_TRAVERSAL;
4847 }
4848
4849 const bool acquireFenceAvailable = s.bufferData &&
4850 s.bufferData->flags.test(BufferData::BufferDataChange::fenceChanged) &&
4851 s.bufferData->acquireFence;
4852 const bool fenceSignaled = !acquireFenceAvailable ||
4853 s.bufferData->acquireFence->getStatus() != Fence::Status::Unsignaled;
4854 if (!fenceSignaled) {
4855 // check fence status
4856 const bool allowLatchUnsignaled =
4857 shouldLatchUnsignaled(s, transaction.states.size(),
4858 flushState.firstTransaction) &&
4859 layer->isSimpleBufferUpdate(s);
4860 if (allowLatchUnsignaled) {
4861 SFTRACE_FORMAT("fence unsignaled try allowLatchUnsignaled %s",
4862 layer->name.c_str());
4863 ready = TransactionReadiness::NotReadyUnsignaled;
4864 } else {
4865 ready = TransactionReadiness::NotReady;
4866 auto& listener = s.bufferData->releaseBufferListener;
4867 if (listener &&
4868 (flushState.queueProcessTime - transaction.postTime) >
4869 std::chrono::nanoseconds(4s).count()) {
4870 mTransactionHandler
4871 .onTransactionQueueStalled(transaction.id,
4872 {.pid = layer->ownerPid.val(),
4873 .layerId = layer->id,
4874 .layerName = layer->name,
4875 .bufferId = s.bufferData->getId(),
4876 .frameNumber =
4877 s.bufferData->frameNumber});
4878 }
4879 SFTRACE_FORMAT("fence unsignaled %s", layer->name.c_str());
4880 return TraverseBuffersReturnValues::STOP_TRAVERSAL;
4881 }
4882 }
4883 return TraverseBuffersReturnValues::CONTINUE_TRAVERSAL;
4884 });
4885 return ready;
4886 }
4887
addTransactionReadyFilters()4888 void SurfaceFlinger::addTransactionReadyFilters() {
4889 mTransactionHandler.addTransactionReadyFilter(
4890 std::bind(&SurfaceFlinger::transactionReadyTimelineCheck, this, std::placeholders::_1));
4891 mTransactionHandler.addTransactionReadyFilter(
4892 std::bind(&SurfaceFlinger::transactionReadyBufferCheck, this, std::placeholders::_1));
4893 }
4894
4895 // For tests only
flushTransactionQueues()4896 bool SurfaceFlinger::flushTransactionQueues() {
4897 mTransactionHandler.collectTransactions();
4898 std::vector<QueuedTransactionState> transactions = mTransactionHandler.flushTransactions();
4899 return applyTransactions(transactions);
4900 }
4901
applyTransactions(std::vector<QueuedTransactionState> & transactions)4902 bool SurfaceFlinger::applyTransactions(std::vector<QueuedTransactionState>& transactions)
4903 EXCLUDES(mStateLock) {
4904 Mutex::Autolock lock(mStateLock);
4905 return applyTransactionsLocked(transactions);
4906 }
4907
applyTransactionsLocked(std::vector<QueuedTransactionState> & transactions)4908 bool SurfaceFlinger::applyTransactionsLocked(std::vector<QueuedTransactionState>& transactions)
4909 REQUIRES(mStateLock) {
4910 bool needsTraversal = false;
4911 // Now apply all transactions.
4912 for (auto& transaction : transactions) {
4913 needsTraversal |=
4914 applyTransactionState(transaction.frameTimelineInfo, transaction.states,
4915 transaction.displays, transaction.flags,
4916 transaction.inputWindowCommands,
4917 transaction.desiredPresentTime, transaction.isAutoTimestamp,
4918 std::move(transaction.uncacheBufferIds), transaction.postTime,
4919 transaction.hasListenerCallbacks,
4920 transaction.listenerCallbacks, transaction.originPid,
4921 transaction.originUid, transaction.id);
4922 }
4923 return needsTraversal;
4924 }
4925
transactionFlushNeeded()4926 bool SurfaceFlinger::transactionFlushNeeded() {
4927 return mTransactionHandler.hasPendingTransactions();
4928 }
4929
frameIsEarly(TimePoint expectedPresentTime,VsyncId vsyncId) const4930 bool SurfaceFlinger::frameIsEarly(TimePoint expectedPresentTime, VsyncId vsyncId) const {
4931 const auto prediction =
4932 mFrameTimeline->getTokenManager()->getPredictionsForToken(ftl::to_underlying(vsyncId));
4933 if (!prediction) {
4934 return false;
4935 }
4936
4937 const auto predictedPresentTime = TimePoint::fromNs(prediction->presentTime);
4938
4939 if (std::chrono::abs(predictedPresentTime - expectedPresentTime) >=
4940 scheduler::VsyncConfig::kEarlyLatchMaxThreshold) {
4941 return false;
4942 }
4943
4944 const Duration earlyLatchVsyncThreshold = mScheduler->getVsyncSchedule()->minFramePeriod() / 2;
4945
4946 return predictedPresentTime >= expectedPresentTime &&
4947 predictedPresentTime - expectedPresentTime >= earlyLatchVsyncThreshold;
4948 }
4949
shouldLatchUnsignaled(const layer_state_t & state,size_t numStates,bool firstTransaction) const4950 bool SurfaceFlinger::shouldLatchUnsignaled(const layer_state_t& state, size_t numStates,
4951 bool firstTransaction) const {
4952 if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::Disabled) {
4953 SFTRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::Disabled)", __func__);
4954 return false;
4955 }
4956
4957 // We only want to latch unsignaled when a single layer is updated in this
4958 // transaction (i.e. not a blast sync transaction).
4959 if (numStates != 1) {
4960 SFTRACE_FORMAT_INSTANT("%s: false (numStates=%zu)", __func__, numStates);
4961 return false;
4962 }
4963
4964 if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::AutoSingleLayer) {
4965 if (!firstTransaction) {
4966 SFTRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::AutoSingleLayer; not first "
4967 "transaction)",
4968 __func__);
4969 return false;
4970 }
4971
4972 // We don't want to latch unsignaled if are in early / client composition
4973 // as it leads to jank due to RenderEngine waiting for unsignaled buffer
4974 // or window animations being slow.
4975 if (mScheduler->vsyncModulator().isVsyncConfigEarly()) {
4976 SFTRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::AutoSingleLayer; "
4977 "isVsyncConfigEarly)",
4978 __func__);
4979 return false;
4980 }
4981 }
4982
4983 return true;
4984 }
4985
setTransactionState(TransactionState && transactionState)4986 status_t SurfaceFlinger::setTransactionState(TransactionState&& transactionState) {
4987 SFTRACE_CALL();
4988
4989 IPCThreadState* ipc = IPCThreadState::self();
4990 const int originPid = ipc->getCallingPid();
4991 const int originUid = ipc->getCallingUid();
4992 uint32_t permissions = LayerStatePermissions::getTransactionPermissions(originPid, originUid);
4993 ftl::Flags<adpf::Workload> queuedWorkload;
4994 for (auto& composerState : transactionState.mComposerStates) {
4995 composerState.state.sanitize(permissions);
4996 if (composerState.state.what & layer_state_t::COMPOSITION_EFFECTS) {
4997 queuedWorkload |= adpf::Workload::EFFECTS;
4998 }
4999 if (composerState.state.what & layer_state_t::VISIBLE_REGION_CHANGES) {
5000 queuedWorkload |= adpf::Workload::VISIBLE_REGION;
5001 }
5002 }
5003
5004 for (DisplayState& display : transactionState.mDisplayStates) {
5005 display.sanitize(permissions);
5006 }
5007
5008 if (!transactionState.mInputWindowCommands.empty() &&
5009 (permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) == 0) {
5010 ALOGE("Only privileged callers are allowed to send input commands.");
5011 transactionState.mInputWindowCommands.clear();
5012 }
5013
5014 if (transactionState.mFlags & (eEarlyWakeupStart | eEarlyWakeupEnd)) {
5015 const bool hasPermission =
5016 (permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) ||
5017 callingThreadHasPermission(sWakeupSurfaceFlinger);
5018 if (!hasPermission) {
5019 ALOGE("Caller needs permission android.permission.WAKEUP_SURFACE_FLINGER to use "
5020 "eEarlyWakeup[Start|End] flags");
5021 transactionState.mFlags &= ~(eEarlyWakeupStart | eEarlyWakeupEnd);
5022 }
5023 }
5024 if (transactionState.mFlags & eEarlyWakeupStart) {
5025 queuedWorkload |= adpf::Workload::WAKEUP;
5026 }
5027 mPowerAdvisor->setQueuedWorkload(queuedWorkload);
5028
5029 const int64_t postTime = systemTime();
5030
5031 std::vector<uint64_t> uncacheBufferIds;
5032 uncacheBufferIds.reserve(transactionState.mUncacheBuffers.size());
5033 for (const auto& uncacheBuffer : transactionState.mUncacheBuffers) {
5034 sp<GraphicBuffer> buffer = ClientCache::getInstance().erase(uncacheBuffer);
5035 if (buffer != nullptr) {
5036 uncacheBufferIds.push_back(buffer->getId());
5037 }
5038 }
5039
5040 std::vector<ResolvedComposerState> resolvedStates;
5041 resolvedStates.reserve(transactionState.mComposerStates.size());
5042 for (auto& state : transactionState.mComposerStates) {
5043 resolvedStates.emplace_back(std::move(state));
5044 auto& resolvedState = resolvedStates.back();
5045 resolvedState.layerId = LayerHandle::getLayerId(resolvedState.state.surface);
5046 if (resolvedState.state.hasBufferChanges() && resolvedState.state.hasValidBuffer() &&
5047 resolvedState.state.surface) {
5048 sp<Layer> layer = LayerHandle::getLayer(resolvedState.state.surface);
5049 std::string layerName =
5050 (layer) ? layer->getDebugName() : std::to_string(resolvedState.state.layerId);
5051 resolvedState.externalTexture =
5052 getExternalTextureFromBufferData(*resolvedState.state.bufferData,
5053 layerName.c_str(), transactionState.getId());
5054 if (resolvedState.externalTexture) {
5055 resolvedState.state.bufferData->buffer = resolvedState.externalTexture->getBuffer();
5056 if (FlagManager::getInstance().monitor_buffer_fences()) {
5057 resolvedState.state.bufferData->buffer->getDependencyMonitor()
5058 .addIngress(FenceTime::makeValid(
5059 resolvedState.state.bufferData->acquireFence),
5060 "Incoming txn");
5061 }
5062 }
5063 mBufferCountTracker.increment(resolvedState.layerId);
5064 }
5065 if (resolvedState.state.what & layer_state_t::eReparent) {
5066 resolvedState.parentId = getLayerIdFromSurfaceControl(
5067 resolvedState.state.getParentSurfaceControlForChild());
5068 }
5069 if (resolvedState.state.what & layer_state_t::eRelativeLayerChanged) {
5070 resolvedState.relativeParentId = getLayerIdFromSurfaceControl(
5071 resolvedState.state.getRelativeLayerSurfaceControl());
5072 }
5073 if (resolvedState.state.what & layer_state_t::eInputInfoChanged) {
5074 wp<IBinder>& touchableRegionCropHandle =
5075 resolvedState.state.editWindowInfo()->touchableRegionCropHandle;
5076 resolvedState.touchCropId =
5077 LayerHandle::getLayerId(touchableRegionCropHandle.promote());
5078 }
5079 }
5080
5081 QueuedTransactionState state{std::move(transactionState),
5082 std::move(resolvedStates),
5083 std::move(uncacheBufferIds),
5084 postTime,
5085 originPid,
5086 originUid};
5087 state.workloadHint = queuedWorkload;
5088
5089 if (mTransactionTracing) {
5090 mTransactionTracing->addQueuedTransaction(state);
5091 }
5092
5093 const auto schedule = [](uint32_t flags) {
5094 if (flags & eEarlyWakeupEnd) return TransactionSchedule::EarlyEnd;
5095 if (flags & eEarlyWakeupStart) return TransactionSchedule::EarlyStart;
5096 return TransactionSchedule::Late;
5097 }(state.flags);
5098
5099 const auto frameHint = state.isFrameActive() ? FrameHint::kActive : FrameHint::kNone;
5100 // Copy fields of |state| needed after it is moved into queueTransaction
5101 VsyncId vsyncId{state.frameTimelineInfo.vsyncId};
5102 auto applyToken = state.applyToken;
5103 {
5104 // Transactions are added via a lockless queue and does not need to be added from the main
5105 // thread.
5106 ftl::FakeGuard guard(kMainThreadContext);
5107 mTransactionHandler.queueTransaction(std::move(state));
5108 }
5109
5110 for (const auto& [displayId, data] : mNotifyExpectedPresentMap) {
5111 if (data.hintStatus.load() == NotifyExpectedPresentHintStatus::ScheduleOnTx) {
5112 scheduleNotifyExpectedPresentHint(displayId, vsyncId);
5113 }
5114 }
5115 setTransactionFlags(eTransactionFlushNeeded, schedule, applyToken, frameHint);
5116 return NO_ERROR;
5117 }
5118
applyTransactionState(const FrameTimelineInfo & frameTimelineInfo,std::vector<ResolvedComposerState> & states,std::span<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)5119 bool SurfaceFlinger::applyTransactionState(
5120 const FrameTimelineInfo& frameTimelineInfo, std::vector<ResolvedComposerState>& states,
5121 std::span<DisplayState> displays, uint32_t flags,
5122 const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime,
5123 bool isAutoTimestamp, const std::vector<uint64_t>& uncacheBufferIds, const int64_t postTime,
5124 bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
5125 int originPid, int originUid, uint64_t transactionId) REQUIRES(mStateLock) {
5126 uint32_t transactionFlags = 0;
5127
5128 // start and end registration for listeners w/ no surface so they can get their callback. Note
5129 // that listeners with SurfaceControls will start registration during setClientStateLocked
5130 // below.
5131 for (const auto& listener : listenerCallbacks) {
5132 mTransactionCallbackInvoker.addEmptyTransaction(listener);
5133 }
5134 uint32_t clientStateFlags = 0;
5135 for (auto& resolvedState : states) {
5136 clientStateFlags |=
5137 updateLayerCallbacksAndStats(frameTimelineInfo, resolvedState, desiredPresentTime,
5138 isAutoTimestamp, postTime, transactionId);
5139 }
5140
5141 transactionFlags |= clientStateFlags;
5142 transactionFlags |= addInputWindowCommands(inputWindowCommands);
5143
5144 for (uint64_t uncacheBufferId : uncacheBufferIds) {
5145 mBufferIdsToUncache.push_back(uncacheBufferId);
5146 }
5147
5148 // If a synchronous transaction is explicitly requested without any changes, force a transaction
5149 // anyway. This can be used as a flush mechanism for previous async transactions.
5150 // Empty animation transaction can be used to simulate back-pressure, so also force a
5151 // transaction for empty animation transactions.
5152 if (transactionFlags == 0 && (flags & eAnimation)) {
5153 transactionFlags = eTransactionNeeded;
5154 }
5155
5156 bool needsTraversal = false;
5157 if (transactionFlags) {
5158 // We are on the main thread, we are about to perform a traversal. Clear the traversal bit
5159 // so we don't have to wake up again next frame to perform an unnecessary traversal.
5160 if (transactionFlags & eTraversalNeeded) {
5161 transactionFlags = transactionFlags & (~eTraversalNeeded);
5162 needsTraversal = true;
5163 }
5164 if (transactionFlags) {
5165 setTransactionFlags(transactionFlags);
5166 }
5167 }
5168
5169 return needsTraversal;
5170 }
5171
applyAndCommitDisplayTransactionStatesLocked(std::vector<QueuedTransactionState> & transactions)5172 bool SurfaceFlinger::applyAndCommitDisplayTransactionStatesLocked(
5173 std::vector<QueuedTransactionState>& transactions) {
5174 bool needsTraversal = false;
5175 uint32_t transactionFlags = 0;
5176 for (auto& transaction : transactions) {
5177 for (DisplayState& display : transaction.displays) {
5178 transactionFlags |= setDisplayStateLocked(display);
5179 }
5180 }
5181
5182 if (transactionFlags) {
5183 // We are on the main thread, we are about to perform a traversal. Clear the traversal bit
5184 // so we don't have to wake up again next frame to perform an unnecessary traversal.
5185 if (transactionFlags & eTraversalNeeded) {
5186 transactionFlags = transactionFlags & (~eTraversalNeeded);
5187 needsTraversal = true;
5188 }
5189 if (transactionFlags) {
5190 setTransactionFlags(transactionFlags);
5191 }
5192 }
5193
5194 mFrontEndDisplayInfosChanged = mTransactionFlags & eDisplayTransactionNeeded;
5195 if (mFrontEndDisplayInfosChanged) {
5196 processDisplayChangesLocked();
5197 mFrontEndDisplayInfos.clear();
5198 for (const auto& [_, display] : mDisplays) {
5199 mFrontEndDisplayInfos.try_emplace(display->getLayerStack(), display->getFrontEndInfo());
5200 }
5201 needsTraversal = true;
5202 }
5203
5204 return needsTraversal;
5205 }
5206
setDisplayStateLocked(const DisplayState & s)5207 uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) {
5208 const ssize_t index = mCurrentState.displays.indexOfKey(s.token);
5209 if (index < 0) return 0;
5210
5211 uint32_t flags = 0;
5212 DisplayDeviceState& state = mCurrentState.displays.editValueAt(index);
5213
5214 const uint32_t what = s.what;
5215 if (what & DisplayState::eSurfaceChanged) {
5216 if (IInterface::asBinder(state.surface) != IInterface::asBinder(s.surface)) {
5217 state.surface = s.surface;
5218 flags |= eDisplayTransactionNeeded;
5219 }
5220 }
5221 if (what & DisplayState::eLayerStackChanged) {
5222 if (state.layerStack != s.layerStack) {
5223 state.layerStack = s.layerStack;
5224 flags |= eDisplayTransactionNeeded;
5225 }
5226 }
5227 if (what & DisplayState::eFlagsChanged) {
5228 if (state.flags != s.flags) {
5229 state.flags = s.flags;
5230 flags |= eDisplayTransactionNeeded;
5231 }
5232 }
5233 if (what & DisplayState::eDisplayProjectionChanged) {
5234 if (state.orientation != s.orientation) {
5235 state.orientation = s.orientation;
5236 flags |= eDisplayTransactionNeeded;
5237 }
5238 if (state.orientedDisplaySpaceRect != s.orientedDisplaySpaceRect) {
5239 state.orientedDisplaySpaceRect = s.orientedDisplaySpaceRect;
5240 flags |= eDisplayTransactionNeeded;
5241 }
5242 if (state.layerStackSpaceRect != s.layerStackSpaceRect) {
5243 state.layerStackSpaceRect = s.layerStackSpaceRect;
5244 flags |= eDisplayTransactionNeeded;
5245 }
5246 }
5247 if (what & DisplayState::eDisplaySizeChanged) {
5248 if (state.width != s.width) {
5249 state.width = s.width;
5250 flags |= eDisplayTransactionNeeded;
5251 }
5252 if (state.height != s.height) {
5253 state.height = s.height;
5254 flags |= eDisplayTransactionNeeded;
5255 }
5256 }
5257
5258 return flags;
5259 }
5260
callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermissionCache)5261 bool SurfaceFlinger::callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermissionCache) {
5262 IPCThreadState* ipc = IPCThreadState::self();
5263 const int pid = ipc->getCallingPid();
5264 const int uid = ipc->getCallingUid();
5265 if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) &&
5266 (usePermissionCache ? !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)
5267 : !checkPermission(sAccessSurfaceFlinger, pid, uid))) {
5268 return false;
5269 }
5270 return true;
5271 }
5272
updateLayerCallbacksAndStats(const FrameTimelineInfo & frameTimelineInfo,ResolvedComposerState & composerState,int64_t desiredPresentTime,bool isAutoTimestamp,int64_t postTime,uint64_t transactionId)5273 uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& frameTimelineInfo,
5274 ResolvedComposerState& composerState,
5275 int64_t desiredPresentTime,
5276 bool isAutoTimestamp, int64_t postTime,
5277 uint64_t transactionId) REQUIRES(mStateLock) {
5278 layer_state_t& s = composerState.state;
5279
5280 std::vector<ListenerCallbacks> filteredListeners;
5281 for (auto& listener : s.listeners) {
5282 // Starts a registration but separates the callback ids according to callback type. This
5283 // allows the callback invoker to send on latch callbacks earlier.
5284 // note that startRegistration will not re-register if the listener has
5285 // already be registered for a prior surface control
5286
5287 ListenerCallbacks onCommitCallbacks = listener.filter(CallbackId::Type::ON_COMMIT);
5288 if (!onCommitCallbacks.callbackIds.empty()) {
5289 filteredListeners.push_back(onCommitCallbacks);
5290 }
5291
5292 ListenerCallbacks onCompleteCallbacks = listener.filter(CallbackId::Type::ON_COMPLETE);
5293 if (!onCompleteCallbacks.callbackIds.empty()) {
5294 filteredListeners.push_back(onCompleteCallbacks);
5295 }
5296 }
5297
5298 const uint64_t what = s.what;
5299 uint32_t flags = 0;
5300 sp<Layer> layer = nullptr;
5301 if (s.surface) {
5302 layer = LayerHandle::getLayer(s.surface);
5303 } else {
5304 // The client may provide us a null handle. Treat it as if the layer was removed.
5305 ALOGW("Attempt to set client state with a null layer handle");
5306 }
5307 if (layer == nullptr) {
5308 for (auto& [listener, callbackIds] : s.listeners) {
5309 mTransactionCallbackInvoker.addCallbackHandle(
5310 sp<CallbackHandle>::make(listener, callbackIds, s.surface));
5311 }
5312 return 0;
5313 }
5314 if (what & layer_state_t::eProducerDisconnect) {
5315 layer->onDisconnect();
5316 }
5317
5318 std::vector<sp<CallbackHandle>> callbackHandles;
5319 if ((what & layer_state_t::eHasListenerCallbacksChanged) && (!filteredListeners.empty())) {
5320 for (auto& [listener, callbackIds] : filteredListeners) {
5321 callbackHandles.emplace_back(
5322 sp<CallbackHandle>::make(listener, callbackIds, s.surface));
5323 }
5324 }
5325
5326 frontend::LayerSnapshot* snapshot = nullptr;
5327 gui::GameMode gameMode = gui::GameMode::Unsupported;
5328 if (what & (layer_state_t::eSidebandStreamChanged | layer_state_t::eBufferChanged) ||
5329 frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
5330 snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence);
5331 if (snapshot) {
5332 gameMode = snapshot->gameMode;
5333 }
5334 }
5335
5336 // TODO(b/238781169) remove after screenshot refactor, currently screenshots
5337 // requires to read drawing state from binder thread. So we need to fix that
5338 // before removing this.
5339 if (what & layer_state_t::eBufferTransformChanged) {
5340 if (layer->setTransform(s.bufferTransform)) flags |= eTraversalNeeded;
5341 }
5342 if (what & layer_state_t::eTransformToDisplayInverseChanged) {
5343 if (layer->setTransformToDisplayInverse(s.transformToDisplayInverse))
5344 flags |= eTraversalNeeded;
5345 }
5346 if (what & layer_state_t::eCropChanged) {
5347 if (layer->setCrop(s.crop)) flags |= eTraversalNeeded;
5348 }
5349 if (what & layer_state_t::eSidebandStreamChanged) {
5350 if (layer->setSidebandStream(s.sidebandStream, frameTimelineInfo, postTime, gameMode))
5351 flags |= eTraversalNeeded;
5352 }
5353 if (what & layer_state_t::eDataspaceChanged) {
5354 if (layer->setDataspace(s.dataspace)) flags |= eTraversalNeeded;
5355 }
5356 if (what & layer_state_t::eExtendedRangeBrightnessChanged) {
5357 if (layer->setExtendedRangeBrightness(s.currentHdrSdrRatio, s.desiredHdrSdrRatio)) {
5358 flags |= eTraversalNeeded;
5359 }
5360 }
5361 if (what & layer_state_t::eDesiredHdrHeadroomChanged) {
5362 if (layer->setDesiredHdrHeadroom(s.desiredHdrSdrRatio)) {
5363 flags |= eTraversalNeeded;
5364 }
5365 }
5366 if (what & layer_state_t::eBufferChanged) {
5367 std::optional<ui::Transform::RotationFlags> transformHint = std::nullopt;
5368 if (snapshot) {
5369 transformHint = snapshot->transformHint;
5370 }
5371 layer->setTransformHint(transformHint);
5372 if (layer->setBuffer(composerState.externalTexture, *s.bufferData, postTime,
5373 desiredPresentTime, isAutoTimestamp, frameTimelineInfo, gameMode)) {
5374 flags |= eTraversalNeeded;
5375 }
5376 mLayersWithQueuedFrames.emplace(layer, gameMode);
5377 } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
5378 layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime, gameMode);
5379 }
5380
5381 if ((what & layer_state_t::eBufferChanged) == 0) {
5382 layer->setDesiredPresentTime(desiredPresentTime, isAutoTimestamp);
5383 }
5384
5385 if (what & layer_state_t::eTrustedPresentationInfoChanged) {
5386 if (layer->setTrustedPresentationInfo(s.trustedPresentationThresholds,
5387 s.trustedPresentationListener)) {
5388 flags |= eTraversalNeeded;
5389 }
5390 }
5391
5392 if (what & layer_state_t::eBufferReleaseChannelChanged) {
5393 layer->setBufferReleaseChannel(s.bufferReleaseChannel);
5394 }
5395
5396 const auto& requestedLayerState = mLayerLifecycleManager.getLayerFromId(layer->getSequence());
5397 bool willPresentCurrentTransaction = requestedLayerState &&
5398 (requestedLayerState->hasReadyFrame() ||
5399 requestedLayerState->willReleaseBufferOnLatch());
5400 if (layer->setTransactionCompletedListeners(callbackHandles, willPresentCurrentTransaction))
5401 flags |= eTraversalNeeded;
5402
5403 return flags;
5404 }
5405
addInputWindowCommands(const InputWindowCommands & inputWindowCommands)5406 uint32_t SurfaceFlinger::addInputWindowCommands(const InputWindowCommands& inputWindowCommands) {
5407 bool hasChanges = mInputWindowCommands.merge(inputWindowCommands);
5408 return hasChanges ? eTraversalNeeded : 0;
5409 }
5410
mirrorLayer(const LayerCreationArgs & args,const sp<IBinder> & mirrorFromHandle,gui::CreateSurfaceResult & outResult)5411 status_t SurfaceFlinger::mirrorLayer(const LayerCreationArgs& args,
5412 const sp<IBinder>& mirrorFromHandle,
5413 gui::CreateSurfaceResult& outResult) {
5414 if (!mirrorFromHandle) {
5415 return NAME_NOT_FOUND;
5416 }
5417
5418 sp<Layer> mirrorLayer;
5419 sp<Layer> mirrorFrom;
5420 LayerCreationArgs mirrorArgs = LayerCreationArgs::fromOtherArgs(args);
5421 {
5422 Mutex::Autolock _l(mStateLock);
5423 mirrorFrom = LayerHandle::getLayer(mirrorFromHandle);
5424 if (!mirrorFrom) {
5425 return NAME_NOT_FOUND;
5426 }
5427 mirrorArgs.flags |= ISurfaceComposerClient::eNoColorFill;
5428 mirrorArgs.mirrorLayerHandle = mirrorFromHandle;
5429 mirrorArgs.addToRoot = false;
5430 status_t result = createEffectLayer(mirrorArgs, &outResult.handle, &mirrorLayer);
5431 if (result != NO_ERROR) {
5432 return result;
5433 }
5434 }
5435
5436 outResult.layerId = mirrorLayer->sequence;
5437 outResult.layerName = String16(mirrorLayer->getDebugName());
5438 return addClientLayer(mirrorArgs, outResult.handle, mirrorLayer /* layer */,
5439 nullptr /* parent */, nullptr /* outTransformHint */);
5440 }
5441
mirrorDisplay(DisplayId displayId,const LayerCreationArgs & args,gui::CreateSurfaceResult & outResult)5442 status_t SurfaceFlinger::mirrorDisplay(DisplayId displayId, const LayerCreationArgs& args,
5443 gui::CreateSurfaceResult& outResult) {
5444 IPCThreadState* ipc = IPCThreadState::self();
5445 const int uid = ipc->getCallingUid();
5446 if (uid != AID_ROOT && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != AID_SHELL) {
5447 ALOGE("Permission denied when trying to mirror display");
5448 return PERMISSION_DENIED;
5449 }
5450
5451 ui::LayerStack layerStack;
5452 sp<Layer> rootMirrorLayer;
5453 status_t result = 0;
5454
5455 {
5456 Mutex::Autolock lock(mStateLock);
5457
5458 const auto display = getDisplayDeviceLocked(displayId);
5459 if (!display) {
5460 return NAME_NOT_FOUND;
5461 }
5462
5463 layerStack = display->getLayerStack();
5464 LayerCreationArgs mirrorArgs = LayerCreationArgs::fromOtherArgs(args);
5465 mirrorArgs.flags |= ISurfaceComposerClient::eNoColorFill;
5466 mirrorArgs.addToRoot = true;
5467 mirrorArgs.layerStackToMirror = layerStack;
5468 result = createEffectLayer(mirrorArgs, &outResult.handle, &rootMirrorLayer);
5469 if (result != NO_ERROR) {
5470 return result;
5471 }
5472 outResult.layerId = rootMirrorLayer->sequence;
5473 outResult.layerName = String16(rootMirrorLayer->getDebugName());
5474 addClientLayer(mirrorArgs, outResult.handle, rootMirrorLayer /* layer */,
5475 nullptr /* parent */, nullptr /* outTransformHint */);
5476 }
5477
5478 setTransactionFlags(eTransactionFlushNeeded);
5479 return NO_ERROR;
5480 }
5481
createLayer(LayerCreationArgs & args,gui::CreateSurfaceResult & outResult)5482 status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, gui::CreateSurfaceResult& outResult) {
5483 status_t result = NO_ERROR;
5484
5485 sp<Layer> layer;
5486
5487 switch (args.flags & ISurfaceComposerClient::eFXSurfaceMask) {
5488 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
5489 case ISurfaceComposerClient::eFXSurfaceContainer:
5490 case ISurfaceComposerClient::eFXSurfaceBufferState:
5491 args.flags |= ISurfaceComposerClient::eNoColorFill;
5492 [[fallthrough]];
5493 case ISurfaceComposerClient::eFXSurfaceEffect: {
5494 result = createBufferStateLayer(args, &outResult.handle, &layer);
5495 if (result != NO_ERROR) {
5496 return result;
5497 }
5498 std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter();
5499 if (pendingBufferCounter) {
5500 std::string counterName = layer->getPendingBufferCounterName();
5501 mBufferCountTracker.add(LayerHandle::getLayerId(outResult.handle), counterName,
5502 pendingBufferCounter);
5503 args.pendingBuffers = pendingBufferCounter;
5504 }
5505 } break;
5506 default:
5507 result = BAD_VALUE;
5508 break;
5509 }
5510
5511 if (result != NO_ERROR) {
5512 return result;
5513 }
5514
5515 args.addToRoot = args.addToRoot && callingThreadHasUnscopedSurfaceFlingerAccess();
5516 // We can safely promote the parent layer in binder thread because we have a strong reference
5517 // to the layer's handle inside this scope.
5518 sp<Layer> parent = LayerHandle::getLayer(args.parentHandle.promote());
5519 if (args.parentHandle != nullptr && parent == nullptr) {
5520 ALOGE("Invalid parent handle %p", args.parentHandle.promote().get());
5521 args.addToRoot = false;
5522 }
5523
5524 uint32_t outTransformHint;
5525 result = addClientLayer(args, outResult.handle, layer, parent, &outTransformHint);
5526 if (result != NO_ERROR) {
5527 return result;
5528 }
5529
5530 outResult.transformHint = static_cast<int32_t>(outTransformHint);
5531 outResult.layerId = layer->sequence;
5532 outResult.layerName = String16(layer->getDebugName());
5533 return result;
5534 }
5535
createBufferStateLayer(LayerCreationArgs & args,sp<IBinder> * handle,sp<Layer> * outLayer)5536 status_t SurfaceFlinger::createBufferStateLayer(LayerCreationArgs& args, sp<IBinder>* handle,
5537 sp<Layer>* outLayer) {
5538 if (checkLayerLeaks() != NO_ERROR) {
5539 return NO_MEMORY;
5540 }
5541 *outLayer = getFactory().createBufferStateLayer(args);
5542 *handle = (*outLayer)->getHandle();
5543 return NO_ERROR;
5544 }
5545
createEffectLayer(const LayerCreationArgs & args,sp<IBinder> * handle,sp<Layer> * outLayer)5546 status_t SurfaceFlinger::createEffectLayer(const LayerCreationArgs& args, sp<IBinder>* handle,
5547 sp<Layer>* outLayer) {
5548 if (checkLayerLeaks() != NO_ERROR) {
5549 return NO_MEMORY;
5550 }
5551 *outLayer = getFactory().createEffectLayer(args);
5552 *handle = (*outLayer)->getHandle();
5553 return NO_ERROR;
5554 }
5555
checkLayerLeaks()5556 status_t SurfaceFlinger::checkLayerLeaks() {
5557 if (mNumLayers >= MAX_LAYERS) {
5558 static std::atomic<nsecs_t> lasttime{0};
5559 nsecs_t now = systemTime();
5560 if (lasttime != 0 && ns2s(now - lasttime.load()) < 10) {
5561 ALOGE("CreateLayer already dumped 10s before");
5562 return NO_MEMORY;
5563 } else {
5564 lasttime = now;
5565 }
5566
5567 ALOGE("CreateLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(),
5568 MAX_LAYERS);
5569 static_cast<void>(mScheduler->schedule([&]() FTL_FAKE_GUARD(kMainThreadContext) {
5570 ALOGE("Dumping on-screen layers.");
5571 mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getHierarchy());
5572 ALOGE("Dumping off-screen layers.");
5573 mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getOffscreenHierarchy());
5574 }));
5575 return NO_MEMORY;
5576 }
5577 return NO_ERROR;
5578 }
5579
onHandleDestroyed(sp<Layer> & layer,uint32_t layerId)5580 void SurfaceFlinger::onHandleDestroyed(sp<Layer>& layer, uint32_t layerId) {
5581 {
5582 // Used to remove stalled transactions which uses an internal lock.
5583 ftl::FakeGuard guard(kMainThreadContext);
5584 mTransactionHandler.onLayerDestroyed(layerId);
5585 }
5586 JankTracker::flushJankData(layerId);
5587
5588 std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
5589 mDestroyedHandles.emplace_back(layerId, layer->getDebugName());
5590
5591 Mutex::Autolock stateLock(mStateLock);
5592 layer->onHandleDestroyed();
5593 mBufferCountTracker.remove(layerId);
5594 layer.clear();
5595 setTransactionFlags(eTransactionFlushNeeded | eTransactionNeeded);
5596 }
5597
initializeDisplays()5598 void SurfaceFlinger::initializeDisplays() {
5599 QueuedTransactionState state;
5600 state.inputWindowCommands = mInputWindowCommands;
5601 const nsecs_t now = systemTime();
5602 state.desiredPresentTime = now;
5603 state.postTime = now;
5604 state.originPid = mPid;
5605 state.originUid = static_cast<int>(getuid());
5606 const uint64_t transactionId = (static_cast<uint64_t>(mPid) << 32) | mUniqueTransactionId++;
5607 state.id = transactionId;
5608
5609 auto layerStack = ui::DEFAULT_LAYER_STACK.id;
5610 for (const auto& [id, display] : FTL_FAKE_GUARD(mStateLock, mPhysicalDisplays)) {
5611 state.displays.emplace_back(
5612 DisplayState(display.token(), ui::LayerStack::fromValue(layerStack++)));
5613 }
5614
5615 std::vector<QueuedTransactionState> transactions;
5616 transactions.emplace_back(state);
5617
5618 {
5619 Mutex::Autolock lock(mStateLock);
5620 applyAndCommitDisplayTransactionStatesLocked(transactions);
5621 }
5622
5623 {
5624 ftl::FakeGuard guard(mStateLock);
5625
5626 // In case of a restart, ensure all displays are off.
5627 for (const auto& [id, display] : mPhysicalDisplays) {
5628 setPhysicalDisplayPowerMode(getDisplayDeviceLocked(id), hal::PowerMode::OFF);
5629 }
5630
5631 // Power on all displays. The primary display is first, so becomes the active display. Also,
5632 // the DisplayCapability set of a display is populated on its first powering on. Do this now
5633 // before responding to any Binder query from DisplayManager about display capabilities.
5634 // Additionally, do not turn on displays if the boot should be quiescent.
5635 if (!mSkipPowerOnForQuiescent) {
5636 for (const auto& [id, display] : mPhysicalDisplays) {
5637 setPhysicalDisplayPowerMode(getDisplayDeviceLocked(id), hal::PowerMode::ON);
5638 }
5639 }
5640 }
5641 }
5642
setPhysicalDisplayPowerMode(const sp<DisplayDevice> & display,hal::PowerMode mode)5643 void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& display,
5644 hal::PowerMode mode) {
5645 if (display->isVirtual()) {
5646 // TODO(b/241285876): This code path should not be reachable, so enforce this at compile
5647 // time.
5648 ALOGE("%s: Invalid operation on virtual display", __func__);
5649 return;
5650 }
5651
5652 const auto displayId = display->getPhysicalId();
5653 ALOGD("Setting power mode %d on physical display %s", mode, to_string(displayId).c_str());
5654
5655 const auto currentMode = display->getPowerMode();
5656 if (currentMode == mode) {
5657 return;
5658 }
5659
5660 const bool isInternalDisplay = mPhysicalDisplays.get(displayId)
5661 .transform(&PhysicalDisplay::isInternal)
5662 .value_or(false);
5663
5664 const auto activeDisplay = getDisplayDeviceLocked(mActiveDisplayId);
5665
5666 ALOGW_IF(display != activeDisplay && isInternalDisplay && activeDisplay &&
5667 activeDisplay->isPoweredOn(),
5668 "Trying to change power mode on inactive display without powering off active display");
5669
5670 const bool couldRefresh = display->isRefreshable();
5671 display->setPowerMode(mode);
5672 const bool canRefresh = display->isRefreshable();
5673
5674 if (couldRefresh && !canRefresh) {
5675 decRefreshableDisplays();
5676 } else if (!couldRefresh && canRefresh) {
5677 incRefreshableDisplays();
5678 }
5679
5680 const auto activeMode = display->refreshRateSelector().getActiveMode().modePtr;
5681 if (currentMode == hal::PowerMode::OFF) {
5682 // Turn on the display
5683
5684 // Activate the display (which involves a modeset to the active mode) when the inner or
5685 // outer display of a foldable is powered on. This condition relies on the above
5686 // DisplayDevice::setPowerMode. If `display` and `activeDisplay` are the same display,
5687 // then the `activeDisplay->isPoweredOn()` below is true, such that the display is not
5688 // activated every time it is powered on.
5689 //
5690 // TODO(b/255635821): Remove the concept of active display.
5691 if (isInternalDisplay && (!activeDisplay || !activeDisplay->isPoweredOn())) {
5692 onActiveDisplayChangedLocked(activeDisplay.get(), *display);
5693 }
5694
5695 if (displayId == mActiveDisplayId) {
5696 if (FlagManager::getInstance().correct_virtual_display_power_state()) {
5697 applyOptimizationPolicy("setPhysicalDisplayPowerMode(ON)");
5698 } else {
5699 disablePowerOptimizations("setPhysicalDisplayPowerMode(ON)");
5700 }
5701 }
5702
5703 getHwComposer().setPowerMode(displayId, mode);
5704 if (mode != hal::PowerMode::DOZE_SUSPEND) {
5705 const bool enable =
5706 mScheduler->getVsyncSchedule(displayId)->getPendingHardwareVsyncState();
5707 requestHardwareVsync(displayId, enable);
5708
5709 if (displayId == mActiveDisplayId) {
5710 mScheduler->enableSyntheticVsync(false);
5711 }
5712
5713 constexpr bool kAllowToEnable = true;
5714 mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable, activeMode.get());
5715 }
5716
5717 mVisibleRegionsDirty = true;
5718 scheduleComposite(FrameHint::kActive);
5719 } else if (mode == hal::PowerMode::OFF) {
5720 const bool currentModeNotDozeSuspend = (currentMode != hal::PowerMode::DOZE_SUSPEND);
5721 // Turn off the display
5722 if (displayId == mActiveDisplayId) {
5723 if (const auto display = getActivatableDisplay()) {
5724 onActiveDisplayChangedLocked(activeDisplay.get(), *display);
5725 } else {
5726 if (FlagManager::getInstance().correct_virtual_display_power_state()) {
5727 applyOptimizationPolicy("setPhysicalDisplayPowerMode(OFF)");
5728 } else {
5729 enablePowerOptimizations("setPhysicalDisplayPowerMode(OFF)");
5730 }
5731
5732 if (currentModeNotDozeSuspend) {
5733 mScheduler->enableSyntheticVsync();
5734 }
5735 }
5736 }
5737 if (currentModeNotDozeSuspend) {
5738 constexpr bool kDisallow = true;
5739 mScheduler->disableHardwareVsync(displayId, kDisallow);
5740 }
5741
5742 // We must disable VSYNC *before* turning off the display. The call to
5743 // disableHardwareVsync, above, schedules a task to turn it off after
5744 // this method returns. But by that point, the display is OFF, so the
5745 // call just updates the pending state, without actually disabling
5746 // VSYNC.
5747 requestHardwareVsync(displayId, false);
5748 getHwComposer().setPowerMode(displayId, mode);
5749
5750 mVisibleRegionsDirty = true;
5751 // from this point on, SF will stop drawing on this display
5752 } else if (mode == hal::PowerMode::DOZE || mode == hal::PowerMode::ON) {
5753 // Update display while dozing
5754 getHwComposer().setPowerMode(displayId, mode);
5755 if (currentMode == hal::PowerMode::DOZE_SUSPEND) {
5756 if (displayId == mActiveDisplayId) {
5757 ALOGI("Force repainting for DOZE_SUSPEND -> DOZE or ON.");
5758 mVisibleRegionsDirty = true;
5759 scheduleRepaint();
5760 mScheduler->enableSyntheticVsync(false);
5761 }
5762 constexpr bool kAllowToEnable = true;
5763 mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable, activeMode.get());
5764 }
5765 } else if (mode == hal::PowerMode::DOZE_SUSPEND) {
5766 // Leave display going to doze
5767 constexpr bool kDisallow = true;
5768 mScheduler->disableHardwareVsync(displayId, kDisallow);
5769
5770 if (displayId == mActiveDisplayId) {
5771 mScheduler->enableSyntheticVsync();
5772 }
5773 getHwComposer().setPowerMode(displayId, mode);
5774 } else {
5775 ALOGE("Attempting to set unknown power mode: %d\n", mode);
5776 getHwComposer().setPowerMode(displayId, mode);
5777 }
5778
5779 if (displayId == mActiveDisplayId) {
5780 mTimeStats->setPowerMode(mode);
5781 mScheduler->setActiveDisplayPowerModeForRefreshRateStats(mode);
5782 }
5783
5784 mScheduler->setDisplayPowerMode(displayId, mode);
5785
5786 ALOGD("Finished setting power mode %d on physical display %s", mode,
5787 to_string(displayId).c_str());
5788 }
5789
setVirtualDisplayPowerMode(const sp<DisplayDevice> & display,hal::PowerMode mode)5790 void SurfaceFlinger::setVirtualDisplayPowerMode(const sp<DisplayDevice>& display,
5791 hal::PowerMode mode) {
5792 if (!display->isVirtual()) {
5793 ALOGE("%s: Invalid operation on physical display", __func__);
5794 return;
5795 }
5796
5797 const auto displayId = display->getVirtualId();
5798 ALOGD("Setting power mode %d on virtual display %s %s", mode, to_string(displayId).c_str(),
5799 display->getDisplayName().c_str());
5800
5801 display->setPowerMode(static_cast<hal::PowerMode>(mode));
5802
5803 applyOptimizationPolicy(__func__);
5804
5805 ALOGD("Finished setting power mode %d on virtual display %s", mode,
5806 to_string(displayId).c_str());
5807 }
5808
shouldOptimizeForPerformance()5809 bool SurfaceFlinger::shouldOptimizeForPerformance() {
5810 for (const auto& [_, display] : mDisplays) {
5811 // Displays that are optimized for power are always powered on and should not influence
5812 // whether there is an active display for the purpose of power optimization, etc. If these
5813 // displays are being shown somewhere, a different (physical or virtual) display that is
5814 // optimized for performance will be powered on in addition. Displays optimized for
5815 // performance will change power mode, so if they are off then they are not active.
5816 if (display->isPoweredOn() &&
5817 display->getOptimizationPolicy() ==
5818 gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance) {
5819 return true;
5820 }
5821 }
5822 return false;
5823 }
5824
enablePowerOptimizations(const char * whence)5825 void SurfaceFlinger::enablePowerOptimizations(const char* whence) {
5826 ALOGD("%s: Enabling power optimizations", whence);
5827
5828 setSchedAttr(false, whence);
5829 setSchedFifo(false, whence);
5830 }
5831
disablePowerOptimizations(const char * whence)5832 void SurfaceFlinger::disablePowerOptimizations(const char* whence) {
5833 ALOGD("%s: Disabling power optimizations", whence);
5834
5835 // TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall
5836 // and set it before SCHED_FIFO due to b/190237315.
5837 setSchedAttr(true, whence);
5838 setSchedFifo(true, whence);
5839 }
5840
applyOptimizationPolicy(const char * whence)5841 void SurfaceFlinger::applyOptimizationPolicy(const char* whence) {
5842 if (shouldOptimizeForPerformance()) {
5843 disablePowerOptimizations(whence);
5844 } else {
5845 enablePowerOptimizations(whence);
5846 }
5847 }
5848
setPowerMode(const sp<IBinder> & displayToken,int mode)5849 void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
5850 auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) {
5851 mSkipPowerOnForQuiescent = false;
5852 const auto display = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(displayToken));
5853 if (!display) {
5854 Mutex::Autolock lock(mStateLock);
5855 const ssize_t index = mCurrentState.displays.indexOfKey(displayToken);
5856 if (index >= 0) {
5857 auto& state = mCurrentState.displays.editValueFor(displayToken);
5858 if (state.isVirtual()) {
5859 ALOGD("Setting power mode %d for a dormant virtual display with token %p", mode,
5860 displayToken.get());
5861 state.initialPowerMode = static_cast<hal::PowerMode>(mode);
5862 return;
5863 }
5864 }
5865 ALOGE("Failed to set power mode %d for display token %p", mode, displayToken.get());
5866 } else if (display->isVirtual()) {
5867 if (FlagManager::getInstance().correct_virtual_display_power_state()) {
5868 ftl::FakeGuard guard(mStateLock);
5869 setVirtualDisplayPowerMode(display, static_cast<hal::PowerMode>(mode));
5870 } else {
5871 ALOGW("Attempt to set power mode %d for virtual display", mode);
5872 }
5873 } else {
5874 ftl::FakeGuard guard(mStateLock);
5875 setPhysicalDisplayPowerMode(display, static_cast<hal::PowerMode>(mode));
5876 }
5877 });
5878
5879 future.wait();
5880 }
5881
doDump(int fd,const DumpArgs & args,bool asProto)5882 status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, bool asProto) {
5883 std::string result;
5884
5885 IPCThreadState* ipc = IPCThreadState::self();
5886 const int pid = ipc->getCallingPid();
5887 const int uid = ipc->getCallingUid();
5888
5889 if ((uid != AID_SHELL) && !PermissionCache::checkPermission(sDump, pid, uid)) {
5890 StringAppendF(&result, "Permission Denial: can't dump SurfaceFlinger from pid=%d, uid=%d\n",
5891 pid, uid);
5892 write(fd, result.c_str(), result.size());
5893 return NO_ERROR;
5894 }
5895
5896 if (asProto && args.empty()) {
5897 perfetto::protos::LayersTraceFileProto traceFileProto =
5898 mLayerTracing.createTraceFileProto();
5899 perfetto::protos::LayersSnapshotProto* layersTrace = traceFileProto.add_entry();
5900 perfetto::protos::LayersProto layersProto = dumpProtoFromMainThread();
5901 layersTrace->mutable_layers()->Swap(&layersProto);
5902 auto displayProtos = dumpDisplayProto();
5903 layersTrace->mutable_displays()->Swap(&displayProtos);
5904 result.append(traceFileProto.SerializeAsString());
5905 write(fd, result.c_str(), result.size());
5906 return NO_ERROR;
5907 }
5908
5909 static const std::unordered_map<std::string, Dumper> dumpers = {
5910 {"--comp-displays"s, dumper(&SurfaceFlinger::dumpCompositionDisplays)},
5911 {"--display-id"s, dumper(&SurfaceFlinger::dumpDisplayIdentificationData)},
5912 {"--displays"s, dumper(&SurfaceFlinger::dumpDisplays)},
5913 {"--edid"s, argsDumper(&SurfaceFlinger::dumpRawDisplayIdentificationData)},
5914 {"--events"s, dumper(&SurfaceFlinger::dumpEvents)},
5915 {"--frametimeline"s, argsDumper(&SurfaceFlinger::dumpFrameTimeline)},
5916 {"--frontend"s, mainThreadDumper(&SurfaceFlinger::dumpFrontEnd)},
5917 {"--hdrinfo"s, dumper(&SurfaceFlinger::dumpHdrInfo)},
5918 {"--hwclayers"s, mainThreadDumper(&SurfaceFlinger::dumpHwcLayersMinidump)},
5919 {"--latency"s, argsMainThreadDumper(&SurfaceFlinger::dumpStats)},
5920 {"--latency-clear"s, argsMainThreadDumper(&SurfaceFlinger::clearStats)},
5921 {"--list"s, mainThreadDumper(&SurfaceFlinger::listLayers)},
5922 {"--planner"s, argsDumper(&SurfaceFlinger::dumpPlannerInfo)},
5923 {"--scheduler"s, dumper(&SurfaceFlinger::dumpScheduler)},
5924 {"--timestats"s, protoDumper(&SurfaceFlinger::dumpTimeStats)},
5925 {"--vsync"s, dumper(&SurfaceFlinger::dumpVsync)},
5926 {"--wide-color"s, dumper(&SurfaceFlinger::dumpWideColorInfo)},
5927 };
5928
5929 const auto flag = args.empty() ? ""s : std::string(String8(args[0]));
5930 if (const auto it = dumpers.find(flag); it != dumpers.end()) {
5931 (it->second)(args, asProto, result);
5932 write(fd, result.c_str(), result.size());
5933 return NO_ERROR;
5934 }
5935
5936 // Collect debug data from main thread
5937 std::string compositionLayers;
5938 mScheduler
5939 ->schedule([&]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(kMainThreadContext) {
5940 dumpVisibleFrontEnd(compositionLayers);
5941 })
5942 .get();
5943 // get window info listener data without the state lock
5944 auto windowInfosDebug = mWindowInfosListenerInvoker->getDebugInfo();
5945 compositionLayers.append("Window Infos:\n");
5946 StringAppendF(&compositionLayers, " max send vsync id: %" PRId64 "\n",
5947 ftl::to_underlying(windowInfosDebug.maxSendDelayVsyncId));
5948 StringAppendF(&compositionLayers, " max send delay (ns): %" PRId64 " ns\n",
5949 windowInfosDebug.maxSendDelayDuration);
5950 StringAppendF(&compositionLayers, " unsent messages: %zu\n",
5951 windowInfosDebug.pendingMessageCount);
5952 compositionLayers.append("\n");
5953 dumpAll(args, compositionLayers, result);
5954 write(fd, result.c_str(), result.size());
5955 return NO_ERROR;
5956 }
5957
dumpCritical(int fd,const DumpArgs &,bool asProto)5958 status_t SurfaceFlinger::dumpCritical(int fd, const DumpArgs&, bool asProto) {
5959 return doDump(fd, DumpArgs(), asProto);
5960 }
5961
listLayers(std::string & result) const5962 void SurfaceFlinger::listLayers(std::string& result) const {
5963 for (const auto& layer : mLayerLifecycleManager.getLayers()) {
5964 StringAppendF(&result, "%s\n", layer->getDebugString().c_str());
5965 }
5966 }
5967
dumpStats(const DumpArgs & args,std::string & result) const5968 void SurfaceFlinger::dumpStats(const DumpArgs& args, std::string& result) const {
5969 StringAppendF(&result, "%" PRId64 "\n", mScheduler->getPacesetterVsyncPeriod().ns());
5970 if (args.size() < 2) return;
5971
5972 const auto name = String8(args[1]);
5973 traverseLegacyLayers([&](Layer* layer) {
5974 if (layer->getName() == name.c_str()) {
5975 layer->dumpFrameStats(result);
5976 }
5977 });
5978 }
5979
clearStats(const DumpArgs & args,std::string &)5980 void SurfaceFlinger::clearStats(const DumpArgs& args, std::string&) {
5981 const bool clearAll = args.size() < 2;
5982 const auto name = clearAll ? String8() : String8(args[1]);
5983
5984 traverseLegacyLayers([&](Layer* layer) {
5985 if (clearAll || layer->getName() == name.c_str()) {
5986 layer->clearFrameStats();
5987 }
5988 });
5989 }
5990
dumpTimeStats(const DumpArgs & args,bool asProto,std::string & result) const5991 void SurfaceFlinger::dumpTimeStats(const DumpArgs& args, bool asProto, std::string& result) const {
5992 mTimeStats->parseArgs(asProto, args, result);
5993 }
5994
dumpFrameTimeline(const DumpArgs & args,std::string & result) const5995 void SurfaceFlinger::dumpFrameTimeline(const DumpArgs& args, std::string& result) const {
5996 mFrameTimeline->parseArgs(args, result);
5997 }
5998
logFrameStats(TimePoint now)5999 void SurfaceFlinger::logFrameStats(TimePoint now) {
6000 static TimePoint sTimestamp = now;
6001 if (now - sTimestamp < 30min) return;
6002 sTimestamp = now;
6003
6004 SFTRACE_CALL();
6005 traverseLegacyLayers([&](Layer* layer) { layer->logFrameStats(); });
6006 }
6007
appendSfConfigString(std::string & result) const6008 void SurfaceFlinger::appendSfConfigString(std::string& result) const {
6009 result.append(" [sf");
6010
6011 StringAppendF(&result, " PRESENT_TIME_OFFSET=%" PRId64, dispSyncPresentTimeOffset);
6012 StringAppendF(&result, " FORCE_HWC_FOR_RBG_TO_YUV=%d", useHwcForRgbToYuv);
6013 StringAppendF(&result, " MAX_VIRT_DISPLAY_DIM=%zu",
6014 getHwComposer().getMaxVirtualDisplayDimension());
6015 StringAppendF(&result, " RUNNING_WITHOUT_SYNC_FRAMEWORK=%d", !hasSyncFramework);
6016 StringAppendF(&result, " NUM_FRAMEBUFFER_SURFACE_BUFFERS=%" PRId64,
6017 maxFrameBufferAcquiredBuffers);
6018 result.append("]");
6019 }
6020
dumpScheduler(std::string & result) const6021 void SurfaceFlinger::dumpScheduler(std::string& result) const {
6022 utils::Dumper dumper{result};
6023
6024 mScheduler->dump(dumper);
6025
6026 // TODO(b/241285876): Move to DisplayModeController.
6027 dumper.dump("debugDisplayModeSetByBackdoor"sv, mDebugDisplayModeSetByBackdoor);
6028 dumper.eol();
6029 }
6030
dumpEvents(std::string & result) const6031 void SurfaceFlinger::dumpEvents(std::string& result) const {
6032 mScheduler->dump(scheduler::Cycle::Render, result);
6033 }
6034
dumpVsync(std::string & result) const6035 void SurfaceFlinger::dumpVsync(std::string& result) const {
6036 mScheduler->dumpVsync(result);
6037 }
6038
dumpPlannerInfo(const DumpArgs & args,std::string & result) const6039 void SurfaceFlinger::dumpPlannerInfo(const DumpArgs& args, std::string& result) const {
6040 for (const auto& [token, display] : mDisplays) {
6041 const auto compositionDisplay = display->getCompositionDisplay();
6042 compositionDisplay->dumpPlannerInfo(args, result);
6043 }
6044 }
6045
dumpCompositionDisplays(std::string & result) const6046 void SurfaceFlinger::dumpCompositionDisplays(std::string& result) const {
6047 for (const auto& [token, display] : mDisplays) {
6048 display->getCompositionDisplay()->dump(result);
6049 result += '\n';
6050 }
6051 }
6052
dumpDisplays(std::string & result) const6053 void SurfaceFlinger::dumpDisplays(std::string& result) const {
6054 utils::Dumper dumper{result};
6055
6056 for (const auto& [id, display] : mPhysicalDisplays) {
6057 utils::Dumper::Section section(dumper, ftl::Concat("Display ", id.value).str());
6058
6059 display.snapshot().dump(dumper);
6060
6061 if (const auto device = getDisplayDeviceLocked(id)) {
6062 device->dump(dumper);
6063 }
6064 }
6065
6066 for (const auto& [token, display] : mDisplays) {
6067 if (display->isVirtual()) {
6068 const VirtualDisplayId virtualId = display->getVirtualId();
6069 utils::Dumper::Section section(dumper,
6070 ftl::Concat("Virtual Display ", virtualId.value).str());
6071 display->dump(dumper);
6072
6073 std::lock_guard lock(mVirtualDisplaysMutex);
6074 if (const auto snapshotOpt = mVirtualDisplays.get(virtualId)) {
6075 snapshotOpt->get().dump(dumper);
6076 }
6077 }
6078 }
6079 }
6080
dumpDisplayIdentificationData(std::string & result) const6081 void SurfaceFlinger::dumpDisplayIdentificationData(std::string& result) const {
6082 for (const auto& [token, display] : mDisplays) {
6083 const auto displayId = asPhysicalDisplayId(display->getDisplayIdVariant());
6084 if (!displayId) {
6085 continue;
6086 }
6087
6088 const auto hwcDisplayId = getHwComposer().fromPhysicalDisplayId(*displayId);
6089 if (!hwcDisplayId) {
6090 continue;
6091 }
6092
6093 StringAppendF(&result,
6094 "Display %s (HWC display %" PRIu64 "): ", to_string(*displayId).c_str(),
6095 *hwcDisplayId);
6096
6097 uint8_t port;
6098 DisplayIdentificationData data;
6099 if (!getHwComposer().getDisplayIdentificationData(*hwcDisplayId, &port, &data)) {
6100 result.append("no display identification data\n");
6101 continue;
6102 }
6103
6104 if (data.empty()) {
6105 result.append("empty display identification data\n");
6106 continue;
6107 }
6108
6109 if (!isEdid(data)) {
6110 result.append("unknown format for display identification data\n");
6111 continue;
6112 }
6113
6114 const auto edid = parseEdid(data);
6115 if (!edid) {
6116 result.append("invalid EDID\n");
6117 continue;
6118 }
6119
6120 StringAppendF(&result, "port=%u pnpId=%s displayName=\"", port, edid->pnpId.data());
6121 result.append(edid->displayName.data(), edid->displayName.length());
6122 result.append("\"\n");
6123 }
6124
6125 for (const auto& [token, display] : mDisplays) {
6126 const auto virtualDisplayId = asVirtualDisplayId(display->getDisplayIdVariant());
6127 if (virtualDisplayId) {
6128 StringAppendF(&result, "Display %s (Virtual display): displayName=\"%s\"",
6129 to_string(*virtualDisplayId).c_str(), display->getDisplayName().c_str());
6130 std::lock_guard lock(mVirtualDisplaysMutex);
6131 if (const auto snapshotOpt = mVirtualDisplays.get(*virtualDisplayId)) {
6132 StringAppendF(&result, " uniqueId=\"%s\"", snapshotOpt->get().uniqueId().c_str());
6133 }
6134 result.append("\n");
6135 }
6136 }
6137 }
6138
dumpRawDisplayIdentificationData(const DumpArgs & args,std::string & result) const6139 void SurfaceFlinger::dumpRawDisplayIdentificationData(const DumpArgs& args,
6140 std::string& result) const {
6141 hal::HWDisplayId hwcDisplayId;
6142 uint8_t port;
6143 DisplayIdentificationData data;
6144
6145 if (args.size() > 1 && base::ParseUint(String8(args[1]), &hwcDisplayId) &&
6146 getHwComposer().getDisplayIdentificationData(hwcDisplayId, &port, &data)) {
6147 result.append(reinterpret_cast<const char*>(data.data()), data.size());
6148 }
6149 }
6150
dumpWideColorInfo(std::string & result) const6151 void SurfaceFlinger::dumpWideColorInfo(std::string& result) const {
6152 StringAppendF(&result, "Device supports wide color: %d\n", mSupportsWideColor);
6153 StringAppendF(&result, "DisplayColorSetting: %s\n",
6154 decodeDisplayColorSetting(mDisplayColorSetting).c_str());
6155
6156 // TODO: print out if wide-color mode is active or not.
6157
6158 for (const auto& [id, display] : mPhysicalDisplays) {
6159 StringAppendF(&result, "Display %s color modes:\n", to_string(id).c_str());
6160 for (const auto mode : display.snapshot().colorModes()) {
6161 StringAppendF(&result, " %s (%d)\n", decodeColorMode(mode).c_str(),
6162 fmt::underlying(mode));
6163 }
6164
6165 if (const auto display = getDisplayDeviceLocked(id)) {
6166 ui::ColorMode currentMode = display->getCompositionDisplay()->getState().colorMode;
6167 StringAppendF(&result, " Current color mode: %s (%d)\n",
6168 decodeColorMode(currentMode).c_str(), fmt::underlying(currentMode));
6169 }
6170 }
6171 result.append("\n");
6172 }
6173
dumpHdrInfo(std::string & result) const6174 void SurfaceFlinger::dumpHdrInfo(std::string& result) const {
6175 for (const auto& [displayId, listener] : mHdrLayerInfoListeners) {
6176 StringAppendF(&result, "HDR events for display %" PRIu64 "\n", displayId.value);
6177 listener->dump(result);
6178 result.append("\n");
6179 }
6180 }
6181
dumpFrontEnd(std::string & result)6182 void SurfaceFlinger::dumpFrontEnd(std::string& result) {
6183 std::ostringstream out;
6184 out << "\nComposition list (bottom to top)\n";
6185 ui::LayerStack lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
6186 for (const auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) {
6187 if (lastPrintedLayerStackHeader != snapshot->outputFilter.layerStack) {
6188 lastPrintedLayerStackHeader = snapshot->outputFilter.layerStack;
6189 out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
6190 }
6191 out << " " << *snapshot << "\n";
6192 }
6193
6194 out << "\nInput list\n";
6195 lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
6196 mLayerSnapshotBuilder.forEachInputSnapshot([&](const frontend::LayerSnapshot& snapshot) {
6197 if (lastPrintedLayerStackHeader != snapshot.outputFilter.layerStack) {
6198 lastPrintedLayerStackHeader = snapshot.outputFilter.layerStack;
6199 out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
6200 }
6201 out << " " << snapshot << "\n";
6202 });
6203
6204 out << "\nLayer Hierarchy\n"
6205 << mLayerHierarchyBuilder.getHierarchy().dump() << "\nOffscreen Hierarchy\n"
6206 << mLayerHierarchyBuilder.getOffscreenHierarchy().dump() << "\n\n";
6207 result.append(out.str());
6208 }
6209
dumpVisibleFrontEnd(std::string & result)6210 void SurfaceFlinger::dumpVisibleFrontEnd(std::string& result) {
6211 std::ostringstream out;
6212 out << "\nComposition list (bottom to top)\n";
6213 ui::LayerStack lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
6214 mLayerSnapshotBuilder.forEachVisibleSnapshot(
6215 [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) {
6216 if (snapshot->hasSomethingToDraw()) {
6217 if (lastPrintedLayerStackHeader != snapshot->outputFilter.layerStack) {
6218 lastPrintedLayerStackHeader = snapshot->outputFilter.layerStack;
6219 out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
6220 }
6221 out << " " << *snapshot << "\n";
6222 }
6223 });
6224
6225 out << "\nInput list\n";
6226 lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
6227 mLayerSnapshotBuilder.forEachInputSnapshot([&](const frontend::LayerSnapshot& snapshot) {
6228 if (lastPrintedLayerStackHeader != snapshot.outputFilter.layerStack) {
6229 lastPrintedLayerStackHeader = snapshot.outputFilter.layerStack;
6230 out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
6231 }
6232 out << " " << snapshot << "\n";
6233 });
6234
6235 out << "\nLayer Hierarchy\n"
6236 << mLayerHierarchyBuilder.getHierarchy() << "\nOffscreen Hierarchy\n"
6237 << mLayerHierarchyBuilder.getOffscreenHierarchy() << "\n\n";
6238 result = out.str();
6239 dumpHwcLayersMinidump(result);
6240 }
6241
dumpDrawingStateProto(uint32_t traceFlags) const6242 perfetto::protos::LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {
6243 std::unordered_set<uint64_t> stackIdsToSkip;
6244
6245 // Determine if virtual layers display should be skipped
6246 if ((traceFlags & LayerTracing::TRACE_VIRTUAL_DISPLAYS) == 0) {
6247 for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
6248 if (display->isVirtual()) {
6249 stackIdsToSkip.insert(display->getLayerStack().id);
6250 }
6251 }
6252 }
6253
6254 auto traceGenerator =
6255 LayerProtoFromSnapshotGenerator(mLayerSnapshotBuilder, mFrontEndDisplayInfos,
6256 mLegacyLayers, traceFlags)
6257 .with(mLayerHierarchyBuilder.getHierarchy());
6258
6259 if (traceFlags & LayerTracing::Flag::TRACE_EXTRA) {
6260 traceGenerator.withOffscreenLayers(mLayerHierarchyBuilder.getOffscreenHierarchy());
6261 }
6262
6263 return traceGenerator.generate();
6264 }
6265
6266 google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto>
dumpDisplayProto() const6267 SurfaceFlinger::dumpDisplayProto() const {
6268 google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto> displays;
6269 for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
6270 perfetto::protos::DisplayProto* displayProto = displays.Add();
6271 displayProto->set_id(display->getId().value);
6272 displayProto->set_name(display->getDisplayName());
6273 displayProto->set_layer_stack(display->getLayerStack().id);
6274
6275 if (!display->isVirtual()) {
6276 const auto dpi = display->refreshRateSelector().getActiveMode().modePtr->getDpi();
6277 displayProto->set_dpi_x(dpi.x);
6278 displayProto->set_dpi_y(dpi.y);
6279 }
6280
6281 LayerProtoHelper::writeSizeToProto(display->getWidth(), display->getHeight(),
6282 [&]() { return displayProto->mutable_size(); });
6283 LayerProtoHelper::writeToProto(display->getLayerStackSpaceRect(), [&]() {
6284 return displayProto->mutable_layer_stack_space_rect();
6285 });
6286 LayerProtoHelper::writeTransformToProto(display->getTransform(),
6287 displayProto->mutable_transform());
6288 displayProto->set_is_virtual(display->isVirtual());
6289 }
6290 return displays;
6291 }
6292
dumpHwc(std::string & result) const6293 void SurfaceFlinger::dumpHwc(std::string& result) const {
6294 getHwComposer().dump(result);
6295 }
6296
dumpProtoFromMainThread(uint32_t traceFlags)6297 perfetto::protos::LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) {
6298 return mScheduler
6299 ->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) {
6300 return dumpDrawingStateProto(traceFlags);
6301 })
6302 .get();
6303 }
6304
dumpHwcLayersMinidump(std::string & result) const6305 void SurfaceFlinger::dumpHwcLayersMinidump(std::string& result) const {
6306 for (const auto& [token, display] : mDisplays) {
6307 const auto displayId = asHalDisplayId(display->getDisplayIdVariant());
6308 if (!displayId) {
6309 continue;
6310 }
6311
6312 StringAppendF(&result, "Display %s (%s) HWC layers:\n", to_string(*displayId).c_str(),
6313 displayId == mActiveDisplayId ? "active" : "inactive");
6314 Layer::miniDumpHeader(result);
6315
6316 const DisplayDevice& ref = *display;
6317 mLayerSnapshotBuilder.forEachVisibleSnapshot(
6318 [&](const frontend::LayerSnapshot& snapshot) FTL_FAKE_GUARD(kMainThreadContext) {
6319 if (!snapshot.hasSomethingToDraw() ||
6320 ref.getLayerStack() != snapshot.outputFilter.layerStack) {
6321 return;
6322 }
6323 auto it = mLegacyLayers.find(snapshot.sequence);
6324 LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
6325 "Couldnt find layer object for %s",
6326 snapshot.getDebugString().c_str());
6327 it->second->miniDump(result, snapshot, ref);
6328 });
6329 result.append("\n");
6330 }
6331 }
6332
dumpAll(const DumpArgs & args,const std::string & compositionLayers,std::string & result) const6333 void SurfaceFlinger::dumpAll(const DumpArgs& args, const std::string& compositionLayers,
6334 std::string& result) const {
6335 TimedLock lock(mStateLock, s2ns(1), __func__);
6336 if (!lock.locked()) {
6337 StringAppendF(&result, "Dumping without lock after timeout: %s (%d)\n",
6338 strerror(-lock.status), lock.status);
6339 }
6340
6341 const bool colorize = !args.empty() && args[0] == String16("--color");
6342 Colorizer colorizer(colorize);
6343
6344 // figure out if we're stuck somewhere
6345 const nsecs_t now = systemTime();
6346 const nsecs_t inTransaction(mDebugInTransaction);
6347 nsecs_t inTransactionDuration = (inTransaction) ? now - inTransaction : 0;
6348
6349 /*
6350 * Dump library configuration.
6351 */
6352
6353 colorizer.bold(result);
6354 result.append("Build configuration:");
6355 colorizer.reset(result);
6356 appendSfConfigString(result);
6357 result.append("\n");
6358
6359 result.append("\nDisplay identification data:\n");
6360 dumpDisplayIdentificationData(result);
6361
6362 result.append("\nWide-Color information:\n");
6363 dumpWideColorInfo(result);
6364
6365 dumpHdrInfo(result);
6366
6367 colorizer.bold(result);
6368 result.append("Sync configuration: ");
6369 colorizer.reset(result);
6370 result.append(SyncFeatures::getInstance().toString());
6371 result.append("\n\n");
6372
6373 colorizer.bold(result);
6374 result.append("Scheduler:\n");
6375 colorizer.reset(result);
6376 dumpScheduler(result);
6377 dumpEvents(result);
6378 dumpVsync(result);
6379 result.append("\n");
6380
6381 /*
6382 * Dump the visible layer list
6383 */
6384 colorizer.bold(result);
6385 StringAppendF(&result, "SurfaceFlinger New Frontend Enabled:%s\n", "true");
6386 StringAppendF(&result, "Active Layers - layers with client handles (count = %zu)\n",
6387 mNumLayers.load());
6388 colorizer.reset(result);
6389
6390 result.append(compositionLayers);
6391
6392 colorizer.bold(result);
6393 StringAppendF(&result, "Displays (%zu entries)\n", mDisplays.size());
6394 colorizer.reset(result);
6395 dumpDisplays(result);
6396 dumpCompositionDisplays(result);
6397 result.push_back('\n');
6398
6399 mCompositionEngine->dump(result);
6400
6401 /*
6402 * Dump SurfaceFlinger global state
6403 */
6404
6405 colorizer.bold(result);
6406 result.append("SurfaceFlinger global state:\n");
6407 colorizer.reset(result);
6408
6409 getRenderEngine().dump(result);
6410
6411 result.append("ClientCache state:\n");
6412 ClientCache::getInstance().dump(result);
6413 DebugEGLImageTracker::getInstance()->dump(result);
6414
6415 if (const auto display = getDefaultDisplayDeviceLocked()) {
6416 display->getCompositionDisplay()->getState().undefinedRegion.dump(result,
6417 "undefinedRegion");
6418 StringAppendF(&result, " orientation=%s, isPoweredOn=%d\n",
6419 toCString(display->getOrientation()), display->isPoweredOn());
6420 }
6421 StringAppendF(&result, " transaction-flags : %08x\n", mTransactionFlags.load());
6422
6423 if (const auto display = getDefaultDisplayDeviceLocked()) {
6424 std::string peakFps, xDpi, yDpi;
6425 const auto activeMode = display->refreshRateSelector().getActiveMode();
6426 if (const auto activeModePtr = activeMode.modePtr.get()) {
6427 peakFps = to_string(activeMode.modePtr->getPeakFps());
6428 const auto dpi = activeModePtr->getDpi();
6429 xDpi = base::StringPrintf("%.2f", dpi.x);
6430 yDpi = base::StringPrintf("%.2f", dpi.y);
6431 } else {
6432 peakFps = "unknown";
6433 xDpi = "unknown";
6434 yDpi = "unknown";
6435 }
6436 StringAppendF(&result,
6437 " peak-refresh-rate : %s\n"
6438 " x-dpi : %s\n"
6439 " y-dpi : %s\n",
6440 peakFps.c_str(), xDpi.c_str(), yDpi.c_str());
6441 }
6442
6443 StringAppendF(&result, " transaction time: %f us\n", inTransactionDuration / 1000.0);
6444
6445 result.append("\nTransaction tracing: ");
6446 if (mTransactionTracing) {
6447 result.append("enabled\n");
6448 mTransactionTracing->dump(result);
6449 } else {
6450 result.append("disabled\n");
6451 }
6452 result.push_back('\n');
6453
6454 {
6455 DumpArgs plannerArgs;
6456 plannerArgs.add(); // first argument is ignored
6457 plannerArgs.add(String16("--layers"));
6458 dumpPlannerInfo(plannerArgs, result);
6459 }
6460
6461 /*
6462 * Dump HWComposer state
6463 */
6464 colorizer.bold(result);
6465 result.append("h/w composer state:\n");
6466 colorizer.reset(result);
6467 const bool hwcDisabled = mDebugDisableHWC || mDebugFlashDelay;
6468 StringAppendF(&result, " h/w composer %s\n", hwcDisabled ? "disabled" : "enabled");
6469 dumpHwc(result);
6470
6471 /*
6472 * Dump gralloc state
6473 */
6474 const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
6475 alloc.dump(result);
6476
6477 /*
6478 * Dump flag/property manager state
6479 */
6480 FlagManager::getInstance().dump(result);
6481
6482 result.append(mTimeStats->miniDump());
6483 result.append("\n");
6484 }
6485
calculateColorMatrix(float saturation)6486 mat4 SurfaceFlinger::calculateColorMatrix(float saturation) {
6487 if (saturation == 1) {
6488 return mat4();
6489 }
6490
6491 float3 luminance{0.213f, 0.715f, 0.072f};
6492 luminance *= 1.0f - saturation;
6493 mat4 saturationMatrix = mat4(vec4{luminance.r + saturation, luminance.r, luminance.r, 0.0f},
6494 vec4{luminance.g, luminance.g + saturation, luminance.g, 0.0f},
6495 vec4{luminance.b, luminance.b, luminance.b + saturation, 0.0f},
6496 vec4{0.0f, 0.0f, 0.0f, 1.0f});
6497 return saturationMatrix;
6498 }
6499
updateColorMatrixLocked()6500 void SurfaceFlinger::updateColorMatrixLocked() {
6501 mat4 colorMatrix =
6502 mClientColorMatrix * calculateColorMatrix(mGlobalSaturationFactor) * mDaltonizer();
6503
6504 if (mCurrentState.colorMatrix != colorMatrix) {
6505 mCurrentState.colorMatrix = colorMatrix;
6506 mCurrentState.colorMatrixChanged = true;
6507 setTransactionFlags(eTransactionNeeded);
6508 }
6509 }
6510
CheckTransactCodeCredentials(uint32_t code)6511 status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) {
6512 #pragma clang diagnostic push
6513 #pragma clang diagnostic error "-Wswitch-enum"
6514 switch (static_cast<ISurfaceComposerTag>(code)) {
6515 // These methods should at minimum make sure that the client requested
6516 // access to SF.
6517 case GET_HDR_CAPABILITIES:
6518 case GET_AUTO_LOW_LATENCY_MODE_SUPPORT:
6519 case GET_GAME_CONTENT_TYPE_SUPPORT:
6520 case ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN: {
6521 // OVERRIDE_HDR_TYPES is used by CTS tests, which acquire the necessary
6522 // permission dynamically. Don't use the permission cache for this check.
6523 bool usePermissionCache = code != OVERRIDE_HDR_TYPES;
6524 if (!callingThreadHasUnscopedSurfaceFlingerAccess(usePermissionCache)) {
6525 IPCThreadState* ipc = IPCThreadState::self();
6526 ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d",
6527 ipc->getCallingPid(), ipc->getCallingUid());
6528 return PERMISSION_DENIED;
6529 }
6530 return OK;
6531 }
6532 // The following calls are currently used by clients that do not
6533 // request necessary permissions. However, they do not expose any secret
6534 // information, so it is OK to pass them.
6535 case GET_ACTIVE_COLOR_MODE:
6536 case GET_ACTIVE_DISPLAY_MODE:
6537 case GET_DISPLAY_COLOR_MODES:
6538 case GET_DISPLAY_MODES:
6539 case GET_SCHEDULING_POLICY:
6540 // Calling setTransactionState is safe, because you need to have been
6541 // granted a reference to Client* and Handle* to do anything with it.
6542 case SET_TRANSACTION_STATE: {
6543 // This is not sensitive information, so should not require permission control.
6544 return OK;
6545 }
6546 case BOOT_FINISHED:
6547 // Used by apps to hook Choreographer to SurfaceFlinger.
6548 case CREATE_DISPLAY_EVENT_CONNECTION:
6549 case CREATE_CONNECTION:
6550 case CREATE_VIRTUAL_DISPLAY:
6551 case DESTROY_VIRTUAL_DISPLAY:
6552 case GET_PRIMARY_PHYSICAL_DISPLAY_ID:
6553 case GET_PHYSICAL_DISPLAY_IDS:
6554 case GET_PHYSICAL_DISPLAY_TOKEN:
6555 case AUTHENTICATE_SURFACE:
6556 case SET_POWER_MODE:
6557 case GET_SUPPORTED_FRAME_TIMESTAMPS:
6558 case GET_DISPLAY_STATE:
6559 case GET_DISPLAY_STATS:
6560 case GET_STATIC_DISPLAY_INFO:
6561 case GET_DYNAMIC_DISPLAY_INFO:
6562 case GET_DISPLAY_NATIVE_PRIMARIES:
6563 case SET_ACTIVE_COLOR_MODE:
6564 case SET_BOOT_DISPLAY_MODE:
6565 case CLEAR_BOOT_DISPLAY_MODE:
6566 case GET_BOOT_DISPLAY_MODE_SUPPORT:
6567 case SET_AUTO_LOW_LATENCY_MODE:
6568 case SET_GAME_CONTENT_TYPE:
6569 case CAPTURE_LAYERS:
6570 case CAPTURE_DISPLAY:
6571 case CAPTURE_DISPLAY_BY_ID:
6572 case CLEAR_ANIMATION_FRAME_STATS:
6573 case GET_ANIMATION_FRAME_STATS:
6574 case OVERRIDE_HDR_TYPES:
6575 case ON_PULL_ATOM:
6576 case ENABLE_VSYNC_INJECTIONS:
6577 case INJECT_VSYNC:
6578 case GET_LAYER_DEBUG_INFO:
6579 case GET_COLOR_MANAGEMENT:
6580 case GET_COMPOSITION_PREFERENCE:
6581 case GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES:
6582 case SET_DISPLAY_CONTENT_SAMPLING_ENABLED:
6583 case GET_DISPLAYED_CONTENT_SAMPLE:
6584 case GET_PROTECTED_CONTENT_SUPPORT:
6585 case IS_WIDE_COLOR_DISPLAY:
6586 case ADD_REGION_SAMPLING_LISTENER:
6587 case REMOVE_REGION_SAMPLING_LISTENER:
6588 case ADD_FPS_LISTENER:
6589 case REMOVE_FPS_LISTENER:
6590 case ADD_TUNNEL_MODE_ENABLED_LISTENER:
6591 case REMOVE_TUNNEL_MODE_ENABLED_LISTENER:
6592 case ADD_WINDOW_INFOS_LISTENER:
6593 case REMOVE_WINDOW_INFOS_LISTENER:
6594 case SET_DESIRED_DISPLAY_MODE_SPECS:
6595 case GET_DESIRED_DISPLAY_MODE_SPECS:
6596 case GET_DISPLAY_BRIGHTNESS_SUPPORT:
6597 case SET_DISPLAY_BRIGHTNESS:
6598 case ADD_HDR_LAYER_INFO_LISTENER:
6599 case REMOVE_HDR_LAYER_INFO_LISTENER:
6600 case NOTIFY_POWER_BOOST:
6601 case SET_GLOBAL_SHADOW_SETTINGS:
6602 case GET_DISPLAY_DECORATION_SUPPORT:
6603 case SET_FRAME_RATE:
6604 case SET_OVERRIDE_FRAME_RATE:
6605 case SET_FRAME_TIMELINE_INFO:
6606 case ADD_TRANSACTION_TRACE_LISTENER:
6607 case GET_GPU_CONTEXT_PRIORITY:
6608 case GET_MAX_ACQUIRED_BUFFER_COUNT:
6609 LOG_FATAL("Deprecated opcode: %d, migrated to AIDL", code);
6610 return PERMISSION_DENIED;
6611 }
6612
6613 // These codes are used for the IBinder protocol to either interrogate the recipient
6614 // side of the transaction for its canonical interface descriptor or to dump its state.
6615 // We let them pass by default.
6616 if (code == IBinder::INTERFACE_TRANSACTION || code == IBinder::DUMP_TRANSACTION ||
6617 code == IBinder::PING_TRANSACTION || code == IBinder::SHELL_COMMAND_TRANSACTION ||
6618 code == IBinder::SYSPROPS_TRANSACTION) {
6619 return OK;
6620 }
6621 // Numbers from 1000 to 1047 are currently used for backdoors. The code
6622 // in onTransact verifies that the user is root, and has access to use SF.
6623 if (code >= 1000 && code <= 1047) {
6624 ALOGV("Accessing SurfaceFlinger through backdoor code: %u", code);
6625 return OK;
6626 }
6627 ALOGE("Permission Denial: SurfaceFlinger did not recognize request code: %u", code);
6628 return PERMISSION_DENIED;
6629 #pragma clang diagnostic pop
6630 }
6631
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)6632 status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
6633 uint32_t flags) {
6634 if (const status_t error = CheckTransactCodeCredentials(code); error != OK) {
6635 return error;
6636 }
6637
6638 status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
6639 if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
6640 CHECK_INTERFACE(ISurfaceComposer, data, reply);
6641 IPCThreadState* ipc = IPCThreadState::self();
6642 const int uid = ipc->getCallingUid();
6643 if (CC_UNLIKELY(uid != AID_SYSTEM &&
6644 !PermissionCache::checkCallingPermission(sHardwareTest))) {
6645 const int pid = ipc->getCallingPid();
6646 ALOGE("Permission Denial: "
6647 "can't access SurfaceFlinger pid=%d, uid=%d",
6648 pid, uid);
6649 return PERMISSION_DENIED;
6650 }
6651 int n;
6652 switch (code) {
6653 case 1000: // Unused.
6654 case 1001:
6655 return NAME_NOT_FOUND;
6656 case 1002: // Toggle flashing on surface damage.
6657 sfdo_setDebugFlash(data.readInt32());
6658 return NO_ERROR;
6659 case 1004: // Force composite ahead of next VSYNC.
6660 case 1006:
6661 sfdo_scheduleComposite();
6662 return NO_ERROR;
6663 case 1005: { // Force commit ahead of next VSYNC.
6664 sfdo_scheduleCommit();
6665 return NO_ERROR;
6666 }
6667 case 1007: // Unused.
6668 return NAME_NOT_FOUND;
6669 case 1008: // Toggle forced GPU composition.
6670 sfdo_forceClientComposition(data.readInt32() != 0);
6671 return NO_ERROR;
6672 case 1009: // Toggle use of transform hint.
6673 mDebugDisableTransformHint = data.readInt32() != 0;
6674 scheduleRepaint();
6675 return NO_ERROR;
6676 case 1010: // Interrogate.
6677 reply->writeInt32(0);
6678 reply->writeInt32(0);
6679 reply->writeInt32(mDebugFlashDelay);
6680 reply->writeInt32(0);
6681 reply->writeInt32(mDebugDisableHWC);
6682 return NO_ERROR;
6683 case 1013: // Unused.
6684 return NAME_NOT_FOUND;
6685 case 1014: {
6686 Mutex::Autolock _l(mStateLock);
6687 // daltonize
6688 n = data.readInt32();
6689 mDaltonizer.setLevel(data.readInt32());
6690 switch (n % 10) {
6691 case 1:
6692 mDaltonizer.setType(ColorBlindnessType::Protanomaly);
6693 break;
6694 case 2:
6695 mDaltonizer.setType(ColorBlindnessType::Deuteranomaly);
6696 break;
6697 case 3:
6698 mDaltonizer.setType(ColorBlindnessType::Tritanomaly);
6699 break;
6700 default:
6701 mDaltonizer.setType(ColorBlindnessType::None);
6702 break;
6703 }
6704 if (n >= 10) {
6705 mDaltonizer.setMode(ColorBlindnessMode::Correction);
6706 } else {
6707 mDaltonizer.setMode(ColorBlindnessMode::Simulation);
6708 }
6709
6710 updateColorMatrixLocked();
6711 return NO_ERROR;
6712 }
6713 case 1015: {
6714 Mutex::Autolock _l(mStateLock);
6715 // apply a color matrix
6716 n = data.readInt32();
6717 if (n) {
6718 // color matrix is sent as a column-major mat4 matrix
6719 for (size_t i = 0; i < 4; i++) {
6720 for (size_t j = 0; j < 4; j++) {
6721 mClientColorMatrix[i][j] = data.readFloat();
6722 }
6723 }
6724 } else {
6725 mClientColorMatrix = mat4();
6726 }
6727
6728 // Check that supplied matrix's last row is {0,0,0,1} so we can avoid
6729 // the division by w in the fragment shader
6730 float4 lastRow(transpose(mClientColorMatrix)[3]);
6731 if (any(greaterThan(abs(lastRow - float4{0, 0, 0, 1}), float4{1e-4f}))) {
6732 ALOGE("The color transform's last row must be (0, 0, 0, 1)");
6733 }
6734
6735 updateColorMatrixLocked();
6736 return NO_ERROR;
6737 }
6738 case 1016: { // Unused.
6739 return NAME_NOT_FOUND;
6740 }
6741 case 1017: {
6742 n = data.readInt32();
6743 mForceFullDamage = n != 0;
6744 return NO_ERROR;
6745 }
6746 case 1018: { // Set the render deadline as a duration until VSYNC.
6747 n = data.readInt32();
6748 mScheduler->setDuration(scheduler::Cycle::Render, std::chrono::nanoseconds(n), 0ns);
6749 return NO_ERROR;
6750 }
6751 case 1019: { // Set the deadline of the last composite as a duration until VSYNC.
6752 n = data.readInt32();
6753 mScheduler->setDuration(scheduler::Cycle::LastComposite,
6754 std::chrono::nanoseconds(n), 0ns);
6755 return NO_ERROR;
6756 }
6757 case 1020: { // Unused
6758 return NAME_NOT_FOUND;
6759 }
6760 case 1021: { // Disable HWC virtual displays
6761 const bool enable = data.readInt32() != 0;
6762 static_cast<void>(
6763 mScheduler->schedule([this, enable] { enableHalVirtualDisplays(enable); }));
6764 return NO_ERROR;
6765 }
6766 case 1022: { // Set saturation boost
6767 Mutex::Autolock _l(mStateLock);
6768 mGlobalSaturationFactor = std::max(0.0f, std::min(data.readFloat(), 2.0f));
6769
6770 updateColorMatrixLocked();
6771 return NO_ERROR;
6772 }
6773 case 1023: { // Set color mode.
6774 mDisplayColorSetting = static_cast<DisplayColorSetting>(data.readInt32());
6775
6776 if (int32_t colorMode; data.readInt32(&colorMode) == NO_ERROR) {
6777 mForceColorMode = static_cast<ui::ColorMode>(colorMode);
6778 }
6779 scheduleRepaint();
6780 return NO_ERROR;
6781 }
6782 // Deprecate, use 1030 to check whether the device is color managed.
6783 case 1024: {
6784 return NAME_NOT_FOUND;
6785 }
6786 // Deprecated, use perfetto to start/stop the layer tracing
6787 case 1025: {
6788 return NAME_NOT_FOUND;
6789 }
6790 // Deprecated, execute "adb shell perfetto --query" to see the ongoing tracing sessions
6791 case 1026: {
6792 return NAME_NOT_FOUND;
6793 }
6794 // Is a DisplayColorSetting supported?
6795 case 1027: {
6796 const auto display = getDefaultDisplayDevice();
6797 if (!display) {
6798 return NAME_NOT_FOUND;
6799 }
6800
6801 DisplayColorSetting setting = static_cast<DisplayColorSetting>(data.readInt32());
6802 switch (setting) {
6803 case DisplayColorSetting::kManaged:
6804 case DisplayColorSetting::kUnmanaged:
6805 reply->writeBool(true);
6806 break;
6807 case DisplayColorSetting::kEnhanced:
6808 reply->writeBool(display->hasRenderIntent(RenderIntent::ENHANCE));
6809 break;
6810 default: // vendor display color setting
6811 reply->writeBool(
6812 display->hasRenderIntent(static_cast<RenderIntent>(setting)));
6813 break;
6814 }
6815 return NO_ERROR;
6816 }
6817 case 1028: { // Unused.
6818 return NAME_NOT_FOUND;
6819 }
6820 // Deprecated, use perfetto to set the active layer tracing buffer size
6821 case 1029: {
6822 return NAME_NOT_FOUND;
6823 }
6824 // Is device color managed?
6825 case 1030: {
6826 // ColorDisplayManager stil calls this
6827 reply->writeBool(true);
6828 return NO_ERROR;
6829 }
6830 // Override default composition data space
6831 // adb shell service call SurfaceFlinger 1031 i32 1 DATASPACE_NUMBER DATASPACE_NUMBER \
6832 // && adb shell stop zygote && adb shell start zygote
6833 // to restore: adb shell service call SurfaceFlinger 1031 i32 0 && \
6834 // adb shell stop zygote && adb shell start zygote
6835 case 1031: {
6836 Mutex::Autolock _l(mStateLock);
6837 n = data.readInt32();
6838 if (n) {
6839 n = data.readInt32();
6840 if (n) {
6841 Dataspace dataspace = static_cast<Dataspace>(n);
6842 if (!validateCompositionDataspace(dataspace)) {
6843 return BAD_VALUE;
6844 }
6845 mDefaultCompositionDataspace = dataspace;
6846 }
6847 n = data.readInt32();
6848 if (n) {
6849 Dataspace dataspace = static_cast<Dataspace>(n);
6850 if (!validateCompositionDataspace(dataspace)) {
6851 return BAD_VALUE;
6852 }
6853 mWideColorGamutCompositionDataspace = dataspace;
6854 }
6855 } else {
6856 // restore composition data space.
6857 mDefaultCompositionDataspace = defaultCompositionDataspace;
6858 mWideColorGamutCompositionDataspace = wideColorGamutCompositionDataspace;
6859 }
6860 return NO_ERROR;
6861 }
6862 // Deprecated, use perfetto to set layer trace flags
6863 case 1033: {
6864 return NAME_NOT_FOUND;
6865 }
6866 case 1034: {
6867 n = data.readInt32();
6868 if (n == 0 || n == 1) {
6869 sfdo_enableRefreshRateOverlay(static_cast<bool>(n));
6870 } else {
6871 Mutex::Autolock lock(mStateLock);
6872 reply->writeBool(isRefreshRateOverlayEnabled());
6873 }
6874 return NO_ERROR;
6875 }
6876 case 1035: {
6877 // Parameters:
6878 // - (required) i32 mode id.
6879 // - (optional) i64 display id. Using default display if not provided.
6880 // - (optional) f min render rate. Using mode's fps is not provided.
6881 // - (optional) f max render rate. Using mode's fps is not provided.
6882
6883 const int modeId = data.readInt32();
6884
6885 const auto display = [&]() -> sp<IBinder> {
6886 uint64_t value;
6887 if (data.readUint64(&value) != NO_ERROR) {
6888 return getDefaultDisplayDevice()->getDisplayToken().promote();
6889 }
6890
6891 if (const auto token =
6892 getPhysicalDisplayToken(PhysicalDisplayId::fromValue(value))) {
6893 return token;
6894 }
6895
6896 ALOGE("Invalid physical display ID");
6897 return nullptr;
6898 }();
6899
6900 const auto getFps = [&] {
6901 float value;
6902 if (data.readFloat(&value) == NO_ERROR) {
6903 return Fps::fromValue(value);
6904 }
6905
6906 return Fps();
6907 };
6908
6909 const auto minFps = getFps();
6910 const auto maxFps = getFps();
6911
6912 mDebugDisplayModeSetByBackdoor = false;
6913 const status_t result =
6914 setActiveModeFromBackdoor(display, DisplayModeId{modeId}, minFps, maxFps);
6915 mDebugDisplayModeSetByBackdoor = result == NO_ERROR;
6916 return result;
6917 }
6918 // Turn on/off frame rate flexibility mode. When turned on it overrides the display
6919 // manager frame rate policy a new policy which allows switching between all refresh
6920 // rates.
6921 case 1036: {
6922 if (data.readInt32() > 0) { // turn on
6923 return mScheduler
6924 ->schedule([this]() FTL_FAKE_GUARD(kMainThreadContext) {
6925 const auto display =
6926 FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
6927
6928 // This is a little racy, but not in a way that hurts anything. As
6929 // we grab the defaultMode from the display manager policy, we could
6930 // be setting a new display manager policy, leaving us using a stale
6931 // defaultMode. The defaultMode doesn't matter for the override
6932 // policy though, since we set allowGroupSwitching to true, so it's
6933 // not a problem.
6934 scheduler::RefreshRateSelector::OverridePolicy overridePolicy;
6935 overridePolicy.defaultMode = display->refreshRateSelector()
6936 .getDisplayManagerPolicy()
6937 .defaultMode;
6938 overridePolicy.allowGroupSwitching = true;
6939 return setDesiredDisplayModeSpecsInternal(display, overridePolicy);
6940 })
6941 .get();
6942 } else { // turn off
6943 return mScheduler
6944 ->schedule([this]() FTL_FAKE_GUARD(kMainThreadContext) {
6945 const auto display =
6946 FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
6947 return setDesiredDisplayModeSpecsInternal(
6948 display,
6949 scheduler::RefreshRateSelector::NoOverridePolicy{});
6950 })
6951 .get();
6952 }
6953 }
6954 // Inject a hotplug connected event for the primary display. This will deallocate and
6955 // reallocate the display state including framebuffers.
6956 case 1037: {
6957 const hal::HWDisplayId hwcId =
6958 (Mutex::Autolock(mStateLock), getHwComposer().getPrimaryHwcDisplayId());
6959
6960 onComposerHalHotplugEvent(hwcId, DisplayHotplugEvent::CONNECTED);
6961 return NO_ERROR;
6962 }
6963 // Modify the max number of display frames stored within FrameTimeline
6964 case 1038: {
6965 n = data.readInt32();
6966 if (n < 0 || n > MAX_ALLOWED_DISPLAY_FRAMES) {
6967 ALOGW("Invalid max size. Maximum allowed is %d", MAX_ALLOWED_DISPLAY_FRAMES);
6968 return BAD_VALUE;
6969 }
6970 if (n == 0) {
6971 // restore to default
6972 mFrameTimeline->reset();
6973 return NO_ERROR;
6974 }
6975 mFrameTimeline->setMaxDisplayFrames(n);
6976 return NO_ERROR;
6977 }
6978 case 1039: {
6979 const auto uid = static_cast<uid_t>(data.readInt32());
6980 const auto refreshRate = data.readFloat();
6981 mScheduler->setPreferredRefreshRateForUid(FrameRateOverride{uid, refreshRate});
6982 return NO_ERROR;
6983 }
6984 // Toggle caching feature
6985 // First argument is an int32 - nonzero enables caching and zero disables caching
6986 // Second argument is an optional uint64 - if present, then limits enabling/disabling
6987 // caching to a particular physical display
6988 case 1040: {
6989 auto future = mScheduler->schedule([&] {
6990 n = data.readInt32();
6991 PhysicalDisplayId inputId;
6992 if (uint64_t inputDisplayId; data.readUint64(&inputDisplayId) == NO_ERROR) {
6993 inputId = PhysicalDisplayId::fromValue(inputDisplayId);
6994 if (!getPhysicalDisplayToken(inputId)) {
6995 ALOGE("No display with id: %" PRIu64, inputDisplayId);
6996 return NAME_NOT_FOUND;
6997 }
6998 }
6999 {
7000 Mutex::Autolock lock(mStateLock);
7001 mLayerCachingEnabled = n != 0;
7002 for (const auto& [_, display] : mDisplays) {
7003 if (inputId == display->getPhysicalId()) {
7004 display->enableLayerCaching(mLayerCachingEnabled);
7005 }
7006 }
7007 }
7008 return OK;
7009 });
7010
7011 if (const status_t error = future.get(); error != OK) {
7012 return error;
7013 }
7014 scheduleRepaint();
7015 return NO_ERROR;
7016 }
7017 case 1041: { // Transaction tracing
7018 if (mTransactionTracing) {
7019 int arg = data.readInt32();
7020 if (arg == -1) {
7021 mScheduler->schedule([&]() { mTransactionTracing.reset(); }).get();
7022 } else if (arg > 0) {
7023 // Transaction tracing is always running but allow the user to temporarily
7024 // increase the buffer when actively debugging.
7025 mTransactionTracing->setBufferSize(
7026 TransactionTracing::LEGACY_ACTIVE_TRACING_BUFFER_SIZE);
7027 } else {
7028 TransactionTraceWriter::getInstance().invoke("", /* overwrite= */ true);
7029 mTransactionTracing->setBufferSize(
7030 TransactionTracing::CONTINUOUS_TRACING_BUFFER_SIZE);
7031 }
7032 }
7033 reply->writeInt32(NO_ERROR);
7034 return NO_ERROR;
7035 }
7036 case 1042: { // Write transaction trace to file
7037 if (mTransactionTracing) {
7038 mTransactionTracing->writeToFile();
7039 }
7040 reply->writeInt32(NO_ERROR);
7041 return NO_ERROR;
7042 }
7043 // hdr sdr ratio overlay
7044 case 1043: {
7045 auto future = mScheduler->schedule(
7046 [&]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(kMainThreadContext) {
7047 n = data.readInt32();
7048 if (n == 0 || n == 1) {
7049 mHdrSdrRatioOverlay = n != 0;
7050 enableHdrSdrRatioOverlay(mHdrSdrRatioOverlay);
7051 } else {
7052 reply->writeBool(isHdrSdrRatioOverlayEnabled());
7053 }
7054 });
7055 future.wait();
7056 return NO_ERROR;
7057 }
7058
7059 case 1044: { // Enable/Disable mirroring from one display to another
7060 /*
7061 * Mirror one display onto another.
7062 * Ensure the source and destination displays are on.
7063 * Commands:
7064 * 0: Mirror one display to another
7065 * 1: Disable mirroring to a previously mirrored display
7066 * 2: Disable mirroring on previously mirrored displays
7067 *
7068 * Ex:
7069 * Get the display ids:
7070 * adb shell dumpsys SurfaceFlinger --display-id
7071 * Mirror first display to the second:
7072 * adb shell service call SurfaceFlinger 1044 i64 0 i64 4619827677550801152 i64
7073 * 4619827677550801153
7074 * Stop mirroring:
7075 * adb shell service call SurfaceFlinger 1044 i64 1
7076 */
7077
7078 int64_t arg0 = data.readInt64();
7079
7080 switch (arg0) {
7081 case 0: {
7082 // Mirror arg1 to arg2
7083 int64_t arg1 = data.readInt64();
7084 int64_t arg2 = data.readInt64();
7085 // Enable mirroring for one display
7086 auto mirrorRoot = SurfaceComposerClient::getDefault()->mirrorDisplay(
7087 DisplayId::fromValue(arg1));
7088 const auto token2 =
7089 getPhysicalDisplayToken(PhysicalDisplayId::fromValue(arg2));
7090 ui::LayerStack layerStack;
7091 {
7092 Mutex::Autolock lock(mStateLock);
7093 sp<DisplayDevice> display = getDisplayDeviceLocked(token2);
7094 layerStack = display->getLayerStack();
7095 }
7096 SurfaceComposerClient::Transaction t;
7097 t.setDisplayLayerStack(token2, layerStack);
7098 t.setLayer(mirrorRoot, INT_MAX); // Top-most layer
7099 t.setLayerStack(mirrorRoot, layerStack);
7100 t.apply();
7101
7102 mMirrorMapForDebug.emplace_or_replace(arg2, mirrorRoot);
7103 break;
7104 }
7105
7106 case 1: {
7107 // Disable mirroring for arg1
7108 int64_t arg1 = data.readInt64();
7109 mMirrorMapForDebug.erase(arg1);
7110 break;
7111 }
7112
7113 case 2: {
7114 // Disable mirroring for all displays
7115 mMirrorMapForDebug.clear();
7116 break;
7117 }
7118
7119 default:
7120 return BAD_VALUE;
7121 }
7122 return NO_ERROR;
7123 }
7124 // Inject jank
7125 // First argument is a float that describes the fraction of frame duration to jank by.
7126 // Second argument is a delay in ms for triggering the jank. This is useful for working
7127 // with tools that steal the adb connection. This argument is optional.
7128 case 1045: {
7129 if (FlagManager::getInstance().vrr_config()) {
7130 float jankAmount = data.readFloat();
7131 int32_t jankDelayMs = 0;
7132 if (data.readInt32(&jankDelayMs) != NO_ERROR) {
7133 jankDelayMs = 0;
7134 }
7135
7136 const auto jankDelayDuration = Duration(std::chrono::milliseconds(jankDelayMs));
7137
7138 const bool jankAmountValid = jankAmount > 0.0 && jankAmount < 100.0;
7139
7140 if (!jankAmountValid) {
7141 ALOGD("Ignoring invalid jank amount: %f", jankAmount);
7142 reply->writeInt32(BAD_VALUE);
7143 return BAD_VALUE;
7144 }
7145
7146 (void)mScheduler->scheduleDelayed(
7147 [&, jankAmount]() FTL_FAKE_GUARD(kMainThreadContext) {
7148 mScheduler->injectPacesetterDelay(jankAmount);
7149 scheduleComposite(FrameHint::kActive);
7150 },
7151 jankDelayDuration.ns());
7152 reply->writeInt32(NO_ERROR);
7153 return NO_ERROR;
7154 }
7155 return err;
7156 }
7157 // Introduce jank to HWC
7158 case 1046: {
7159 int32_t jankDelayMs = 0;
7160 if (data.readInt32(&jankDelayMs) != NO_ERROR) {
7161 return BAD_VALUE;
7162 }
7163 mScheduler->setDebugPresentDelay(TimePoint::fromNs(ms2ns(jankDelayMs)));
7164 return NO_ERROR;
7165 }
7166 // Update WorkDuration
7167 // parameters:
7168 // - (required) i64 minSfNs, used as the late.sf WorkDuration.
7169 // - (required) i64 maxSfNs, used as the early.sf and earlyGl.sf WorkDuration.
7170 // - (required) i64 appDurationNs, used as the late.app, early.app and earlyGl.app
7171 // WorkDuration.
7172 // Usage:
7173 // adb shell service call SurfaceFlinger 1047 i64 12333333 i64 16666666 i64 16666666
7174 case 1047: {
7175 if (!property_get_bool("debug.sf.use_phase_offsets_as_durations", false)) {
7176 ALOGE("Not supported when work duration is not enabled");
7177 return INVALID_OPERATION;
7178 }
7179 int64_t minSfNs = 0;
7180 int64_t maxSfNs = 0;
7181 int64_t appDurationNs = 0;
7182 if (data.readInt64(&minSfNs) != NO_ERROR || data.readInt64(&maxSfNs) != NO_ERROR ||
7183 data.readInt64(&appDurationNs) != NO_ERROR) {
7184 return BAD_VALUE;
7185 }
7186 mScheduler->reloadPhaseConfiguration(mDisplayModeController
7187 .getActiveMode(mActiveDisplayId)
7188 .fps,
7189 Duration::fromNs(minSfNs),
7190 Duration::fromNs(maxSfNs),
7191 Duration::fromNs(appDurationNs));
7192 return NO_ERROR;
7193 }
7194 }
7195 }
7196 return err;
7197 }
7198
kernelTimerChanged(bool expired)7199 void SurfaceFlinger::kernelTimerChanged(bool expired) {
7200 static bool updateOverlay =
7201 property_get_bool("debug.sf.kernel_idle_timer_update_overlay", true);
7202 if (!updateOverlay) return;
7203
7204 // Update the overlay on the main thread to avoid race conditions with
7205 // RefreshRateSelector::getActiveMode
7206 static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) {
7207 const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
7208 if (!display) {
7209 ALOGW("%s: default display is null", __func__);
7210 return;
7211 }
7212 if (!display->isRefreshRateOverlayEnabled()) return;
7213
7214 const auto state = mDisplayModeController.getKernelIdleTimerState(display->getPhysicalId());
7215
7216 if (display->onKernelTimerChanged(state.desiredModeIdOpt, state.isEnabled && expired)) {
7217 mScheduler->scheduleFrame();
7218 }
7219 }));
7220 }
7221
vrrDisplayIdle(bool idle)7222 void SurfaceFlinger::vrrDisplayIdle(bool idle) {
7223 // Update the overlay on the main thread to avoid race conditions with
7224 // RefreshRateSelector::getActiveMode
7225 static_cast<void>(mScheduler->schedule([=, this] {
7226 const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
7227 if (!display) {
7228 ALOGW("%s: default display is null", __func__);
7229 return;
7230 }
7231 if (!display->isRefreshRateOverlayEnabled()) return;
7232
7233 display->onVrrIdle(idle);
7234 mScheduler->scheduleFrame();
7235 }));
7236 }
7237
getKernelIdleTimerProperties(PhysicalDisplayId displayId)7238 auto SurfaceFlinger::getKernelIdleTimerProperties(PhysicalDisplayId displayId)
7239 -> std::pair<std::optional<KernelIdleTimerController>, std::chrono::milliseconds> {
7240 const bool isKernelIdleTimerHwcSupported = getHwComposer().getComposer()->isSupported(
7241 android::Hwc2::Composer::OptionalFeature::KernelIdleTimer);
7242 const auto timeout = getIdleTimerTimeout(displayId);
7243 if (isKernelIdleTimerHwcSupported) {
7244 if (getHwComposer().hasDisplayIdleTimerCapability(displayId)) {
7245 // In order to decide if we can use the HWC api for idle timer
7246 // we query DisplayCapability::DISPLAY_IDLE_TIMER directly on the composer
7247 // without relying on hasDisplayCapability.
7248 // hasDisplayCapability relies on DisplayCapabilities
7249 // which are updated after we set the PowerMode::ON.
7250 // DISPLAY_IDLE_TIMER is a display driver property
7251 // and is available before the PowerMode::ON
7252 return {KernelIdleTimerController::HwcApi, timeout};
7253 }
7254 return {std::nullopt, timeout};
7255 }
7256 if (getKernelIdleTimerSyspropConfig(displayId)) {
7257 return {KernelIdleTimerController::Sysprop, timeout};
7258 }
7259
7260 return {std::nullopt, timeout};
7261 }
7262
7263 // A simple RAII class to disconnect from an ANativeWindow* when it goes out of scope
7264 class WindowDisconnector {
7265 public:
WindowDisconnector(ANativeWindow * window,int api)7266 WindowDisconnector(ANativeWindow* window, int api) : mWindow(window), mApi(api) {}
~WindowDisconnector()7267 ~WindowDisconnector() { native_window_api_disconnect(mWindow, mApi); }
7268
7269 private:
7270 ANativeWindow* mWindow;
7271 const int mApi;
7272 };
7273
hasCaptureBlackoutContentPermission()7274 static bool hasCaptureBlackoutContentPermission() {
7275 IPCThreadState* ipc = IPCThreadState::self();
7276 const int pid = ipc->getCallingPid();
7277 const int uid = ipc->getCallingUid();
7278 return uid == AID_GRAPHICS || uid == AID_SYSTEM ||
7279 PermissionCache::checkPermission(sCaptureBlackoutContent, pid, uid);
7280 }
7281
validateScreenshotPermissions(const CaptureArgs & captureArgs)7282 static status_t validateScreenshotPermissions(const CaptureArgs& captureArgs) {
7283 IPCThreadState* ipc = IPCThreadState::self();
7284 const int pid = ipc->getCallingPid();
7285 const int uid = ipc->getCallingUid();
7286 if (uid == AID_GRAPHICS || uid == AID_SYSTEM ||
7287 PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
7288 return OK;
7289 }
7290
7291 // If the caller doesn't have the correct permissions but is only attempting to screenshot
7292 // itself, we allow it to continue.
7293 if (captureArgs.uid == uid) {
7294 return OK;
7295 }
7296
7297 ALOGE("Permission Denial: can't take screenshot pid=%d, uid=%d", pid, uid);
7298 return PERMISSION_DENIED;
7299 }
7300
setSchedFifo(bool enabled,const char * whence)7301 void SurfaceFlinger::setSchedFifo(bool enabled, const char* whence) {
7302 static constexpr int kFifoPriority = 2;
7303 static constexpr int kOtherPriority = 0;
7304
7305 struct sched_param param = {0};
7306 int sched_policy;
7307 if (enabled && !FlagManager::getInstance().disable_sched_fifo_sf()) {
7308 sched_policy = SCHED_FIFO;
7309 param.sched_priority = kFifoPriority;
7310 } else {
7311 sched_policy = SCHED_OTHER;
7312 param.sched_priority = kOtherPriority;
7313 }
7314
7315 if (sched_setscheduler(0, sched_policy, ¶m) != 0) {
7316 const char* kPolicy[] = {"SCHED_OTHER", "SCHED_FIFO"};
7317 ALOGW("%s: Failed to set %s: %s", whence, kPolicy[sched_policy == SCHED_FIFO],
7318 strerror(errno));
7319 }
7320 }
7321
setSchedAttr(bool enabled,const char * whence)7322 void SurfaceFlinger::setSchedAttr(bool enabled, const char* whence) {
7323 static const unsigned int kUclampMin =
7324 base::GetUintProperty<unsigned int>("ro.surface_flinger.uclamp.min"s, 0U);
7325
7326 if (!kUclampMin) {
7327 // uclamp.min set to 0 (default), skip setting
7328 return;
7329 }
7330
7331 sched_attr attr = {};
7332 attr.size = sizeof(attr);
7333
7334 attr.sched_flags = (SCHED_FLAG_KEEP_ALL | SCHED_FLAG_UTIL_CLAMP);
7335 attr.sched_util_min = enabled ? kUclampMin : 0;
7336 attr.sched_util_max = 1024;
7337
7338 if (syscall(__NR_sched_setattr, 0, &attr, 0)) {
7339 const char* kAction[] = {"disable", "enable"};
7340 ALOGW("%s: Failed to %s uclamp.min: %s", whence, kAction[enabled], strerror(errno));
7341 }
7342 }
7343
7344 namespace {
7345
pickBestDataspace(ui::Dataspace requestedDataspace,ui::ColorMode colorMode,bool capturingHdrLayers,bool hintForSeamlessTransition)7346 ui::Dataspace pickBestDataspace(ui::Dataspace requestedDataspace, ui::ColorMode colorMode,
7347 bool capturingHdrLayers, bool hintForSeamlessTransition) {
7348 if (requestedDataspace != ui::Dataspace::UNKNOWN) {
7349 return requestedDataspace;
7350 }
7351
7352 const auto dataspaceForColorMode = ui::pickDataspaceFor(colorMode);
7353
7354 // TODO: Enable once HDR screenshots are ready.
7355 if constexpr (/* DISABLES CODE */ (false)) {
7356 // For now since we only support 8-bit screenshots, just use HLG and
7357 // assume that 1.0 >= display max luminance. This isn't quite as future
7358 // proof as PQ is, but is good enough.
7359 // Consider using PQ once we support 16-bit screenshots and we're able
7360 // to consistently supply metadata to image encoders.
7361 return ui::Dataspace::BT2020_HLG;
7362 }
7363
7364 return dataspaceForColorMode;
7365 }
7366
7367 } // namespace
7368
invokeScreenCaptureError(const status_t status,const sp<IScreenCaptureListener> & captureListener)7369 static void invokeScreenCaptureError(const status_t status,
7370 const sp<IScreenCaptureListener>& captureListener) {
7371 ScreenCaptureResults captureResults;
7372 captureResults.fenceResult = base::unexpected(status);
7373 captureListener->onScreenCaptureCompleted(captureResults);
7374 }
7375
captureDisplay(const DisplayCaptureArgs & args,const sp<IScreenCaptureListener> & captureListener)7376 void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args,
7377 const sp<IScreenCaptureListener>& captureListener) {
7378 SFTRACE_CALL();
7379
7380 const auto& captureArgs = args.captureArgs;
7381 status_t validate = validateScreenshotPermissions(captureArgs);
7382 if (validate != OK) {
7383 ALOGD("Permission denied to captureDisplay");
7384 invokeScreenCaptureError(validate, captureListener);
7385 return;
7386 }
7387
7388 if (!args.displayToken) {
7389 ALOGD("Invalid display token to captureDisplay");
7390 invokeScreenCaptureError(BAD_VALUE, captureListener);
7391 return;
7392 }
7393
7394 if (captureArgs.captureSecureLayers && !hasCaptureBlackoutContentPermission()) {
7395 ALOGD("Attempting to capture secure layers without CAPTURE_BLACKOUT_CONTENT");
7396 invokeScreenCaptureError(PERMISSION_DENIED, captureListener);
7397 return;
7398 }
7399
7400 wp<const DisplayDevice> displayWeak;
7401 ftl::Optional<DisplayIdVariant> displayIdVariantOpt;
7402 ui::LayerStack layerStack;
7403 ui::Size reqSize(args.width, args.height);
7404 std::unordered_set<uint32_t> excludeLayerIds;
7405 Rect layerStackSpaceRect;
7406 bool displayIsSecure;
7407
7408 {
7409 Mutex::Autolock lock(mStateLock);
7410 sp<DisplayDevice> display = getDisplayDeviceLocked(args.displayToken);
7411 if (!display) {
7412 ALOGD("Unable to find display device for captureDisplay");
7413 invokeScreenCaptureError(NAME_NOT_FOUND, captureListener);
7414 return;
7415 }
7416 displayWeak = display;
7417 displayIdVariantOpt = display->getDisplayIdVariant();
7418 layerStack = display->getLayerStack();
7419 displayIsSecure = display->isSecure();
7420
7421 layerStackSpaceRect = display->getLayerStackSpaceRect();
7422 // set the requested width/height to the logical display layer stack rect size by default
7423 if (args.width == 0 || args.height == 0) {
7424 reqSize = layerStackSpaceRect.getSize();
7425 }
7426
7427 for (const auto& handle : captureArgs.excludeHandles) {
7428 uint32_t excludeLayer = LayerHandle::getLayerId(handle);
7429 if (excludeLayer != UNASSIGNED_LAYER_ID) {
7430 excludeLayerIds.emplace(excludeLayer);
7431 } else {
7432 ALOGD("Invalid layer handle passed as excludeLayer to captureDisplay");
7433 invokeScreenCaptureError(NAME_NOT_FOUND, captureListener);
7434 return;
7435 }
7436 }
7437 }
7438
7439 GetLayerSnapshotsFunction getLayerSnapshotsFn =
7440 getLayerSnapshotsForScreenshots(layerStack, captureArgs.uid,
7441 std::move(excludeLayerIds));
7442
7443 ScreenshotArgs screenshotArgs;
7444 screenshotArgs.captureTypeVariant = displayWeak;
7445 screenshotArgs.displayIdVariant = displayIdVariantOpt;
7446 screenshotArgs.sourceCrop = gui::aidl_utils::fromARect(captureArgs.sourceCrop);
7447 if (screenshotArgs.sourceCrop.isEmpty()) {
7448 screenshotArgs.sourceCrop = layerStackSpaceRect;
7449 }
7450 screenshotArgs.reqSize = reqSize;
7451 screenshotArgs.dataspace = static_cast<ui::Dataspace>(captureArgs.dataspace);
7452 screenshotArgs.isSecure = captureArgs.captureSecureLayers && displayIsSecure;
7453 screenshotArgs.seamlessTransition = captureArgs.hintForSeamlessTransition;
7454
7455 captureScreenCommon(screenshotArgs, getLayerSnapshotsFn, reqSize,
7456 static_cast<ui::PixelFormat>(captureArgs.pixelFormat),
7457 captureArgs.allowProtected, captureArgs.grayscale, captureListener);
7458 }
7459
captureDisplay(DisplayId displayId,const CaptureArgs & args,const sp<IScreenCaptureListener> & captureListener)7460 void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args,
7461 const sp<IScreenCaptureListener>& captureListener) {
7462 ui::LayerStack layerStack;
7463 wp<const DisplayDevice> displayWeak;
7464 ftl::Optional<DisplayIdVariant> displayIdVariantOpt;
7465 ui::Size size;
7466 Rect layerStackSpaceRect;
7467 bool displayIsSecure;
7468
7469 {
7470 Mutex::Autolock lock(mStateLock);
7471
7472 const auto display = getDisplayDeviceLocked(displayId);
7473 if (!display) {
7474 ALOGD("Unable to find display device for captureDisplay");
7475 invokeScreenCaptureError(NAME_NOT_FOUND, captureListener);
7476 return;
7477 }
7478
7479 displayWeak = display;
7480 displayIdVariantOpt = display->getDisplayIdVariant();
7481 layerStack = display->getLayerStack();
7482 layerStackSpaceRect = display->getLayerStackSpaceRect();
7483 size = display->getLayerStackSpaceRect().getSize();
7484 displayIsSecure = display->isSecure();
7485 }
7486
7487 size.width *= args.frameScaleX;
7488 size.height *= args.frameScaleY;
7489
7490 // We could query a real value for this but it'll be a long, long time until we support
7491 // displays that need upwards of 1GB per buffer so...
7492 constexpr auto kMaxTextureSize = 16384;
7493 if (size.width <= 0 || size.height <= 0 || size.width >= kMaxTextureSize ||
7494 size.height >= kMaxTextureSize) {
7495 ALOGD("captureDisplay resolved to invalid size %d x %d", size.width, size.height);
7496 invokeScreenCaptureError(BAD_VALUE, captureListener);
7497 return;
7498 }
7499
7500 GetLayerSnapshotsFunction getLayerSnapshotsFn =
7501 getLayerSnapshotsForScreenshots(layerStack, CaptureArgs::UNSET_UID,
7502 /*snapshotFilterFn=*/nullptr);
7503
7504 if (captureListener == nullptr) {
7505 ALOGE("capture screen must provide a capture listener callback");
7506 invokeScreenCaptureError(BAD_VALUE, captureListener);
7507 return;
7508 }
7509
7510 constexpr bool kAllowProtected = false;
7511 constexpr bool kGrayscale = false;
7512
7513 ScreenshotArgs screenshotArgs;
7514 screenshotArgs.captureTypeVariant = displayWeak;
7515 screenshotArgs.displayIdVariant = displayIdVariantOpt;
7516 screenshotArgs.sourceCrop = layerStackSpaceRect;
7517 screenshotArgs.reqSize = size;
7518 screenshotArgs.dataspace = static_cast<ui::Dataspace>(args.dataspace);
7519 screenshotArgs.isSecure = args.captureSecureLayers && displayIsSecure;
7520 screenshotArgs.seamlessTransition = args.hintForSeamlessTransition;
7521
7522 captureScreenCommon(screenshotArgs, getLayerSnapshotsFn, size,
7523 static_cast<ui::PixelFormat>(args.pixelFormat), kAllowProtected, kGrayscale,
7524 captureListener);
7525 }
7526
captureLayersSync(const LayerCaptureArgs & args)7527 ScreenCaptureResults SurfaceFlinger::captureLayersSync(const LayerCaptureArgs& args) {
7528 sp<SyncScreenCaptureListener> captureListener = sp<SyncScreenCaptureListener>::make();
7529 captureLayers(args, captureListener);
7530 return captureListener->waitForResults();
7531 }
7532
captureLayers(const LayerCaptureArgs & args,const sp<IScreenCaptureListener> & captureListener)7533 void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args,
7534 const sp<IScreenCaptureListener>& captureListener) {
7535 SFTRACE_CALL();
7536
7537 const auto& captureArgs = args.captureArgs;
7538
7539 status_t validate = validateScreenshotPermissions(captureArgs);
7540 if (validate != OK) {
7541 ALOGD("Permission denied to captureLayers");
7542 invokeScreenCaptureError(validate, captureListener);
7543 return;
7544 }
7545
7546 auto crop = gui::aidl_utils::fromARect(captureArgs.sourceCrop);
7547
7548 ui::Size reqSize;
7549 sp<Layer> parent;
7550 std::unordered_set<uint32_t> excludeLayerIds;
7551 ui::Dataspace dataspace = static_cast<ui::Dataspace>(captureArgs.dataspace);
7552
7553 if (captureArgs.captureSecureLayers && !hasCaptureBlackoutContentPermission()) {
7554 ALOGD("Attempting to capture secure layers without CAPTURE_BLACKOUT_CONTENT");
7555 invokeScreenCaptureError(PERMISSION_DENIED, captureListener);
7556 return;
7557 }
7558
7559 {
7560 Mutex::Autolock lock(mStateLock);
7561
7562 parent = LayerHandle::getLayer(args.layerHandle);
7563 if (parent == nullptr) {
7564 ALOGD("captureLayers called with an invalid or removed parent");
7565 invokeScreenCaptureError(NAME_NOT_FOUND, captureListener);
7566 return;
7567 }
7568
7569 Rect parentSourceBounds = parent->getCroppedBufferSize(parent->getDrawingState());
7570 if (crop.width() <= 0) {
7571 crop.left = 0;
7572 crop.right = parentSourceBounds.getWidth();
7573 }
7574
7575 if (crop.height() <= 0) {
7576 crop.top = 0;
7577 crop.bottom = parentSourceBounds.getHeight();
7578 }
7579
7580 if (crop.isEmpty() || captureArgs.frameScaleX <= 0.0f || captureArgs.frameScaleY <= 0.0f) {
7581 // Error out if the layer has no source bounds (i.e. they are boundless) and a source
7582 // crop was not specified, or an invalid frame scale was provided.
7583 ALOGD("Boundless layer, unspecified crop, or invalid frame scale to captureLayers");
7584 invokeScreenCaptureError(BAD_VALUE, captureListener);
7585 return;
7586 }
7587 reqSize = ui::Size(crop.width() * captureArgs.frameScaleX,
7588 crop.height() * captureArgs.frameScaleY);
7589
7590 for (const auto& handle : captureArgs.excludeHandles) {
7591 uint32_t excludeLayer = LayerHandle::getLayerId(handle);
7592 if (excludeLayer != UNASSIGNED_LAYER_ID) {
7593 excludeLayerIds.emplace(excludeLayer);
7594 } else {
7595 ALOGD("Invalid layer handle passed as excludeLayer to captureLayers");
7596 invokeScreenCaptureError(NAME_NOT_FOUND, captureListener);
7597 return;
7598 }
7599 }
7600 } // mStateLock
7601
7602 // really small crop or frameScale
7603 if (reqSize.width <= 0 || reqSize.height <= 0) {
7604 ALOGD("Failed to captureLayers: crop or scale too small");
7605 invokeScreenCaptureError(BAD_VALUE, captureListener);
7606 return;
7607 }
7608
7609 std::optional<FloatRect> parentCrop = std::nullopt;
7610 if (args.childrenOnly) {
7611 parentCrop = crop.isEmpty() ? FloatRect(0, 0, reqSize.width, reqSize.height)
7612 : crop.toFloatRect();
7613 }
7614
7615 GetLayerSnapshotsFunction getLayerSnapshotsFn =
7616 getLayerSnapshotsForScreenshots(parent->sequence, captureArgs.uid,
7617 std::move(excludeLayerIds), args.childrenOnly,
7618 parentCrop);
7619
7620 if (captureListener == nullptr) {
7621 ALOGD("capture screen must provide a capture listener callback");
7622 invokeScreenCaptureError(BAD_VALUE, captureListener);
7623 return;
7624 }
7625
7626 ScreenshotArgs screenshotArgs;
7627 screenshotArgs.captureTypeVariant = parent->getSequence();
7628 screenshotArgs.childrenOnly = args.childrenOnly;
7629 screenshotArgs.sourceCrop = crop;
7630 screenshotArgs.reqSize = reqSize;
7631 screenshotArgs.dataspace = static_cast<ui::Dataspace>(captureArgs.dataspace);
7632 screenshotArgs.isSecure = captureArgs.captureSecureLayers;
7633 screenshotArgs.seamlessTransition = captureArgs.hintForSeamlessTransition;
7634
7635 captureScreenCommon(screenshotArgs, getLayerSnapshotsFn, reqSize,
7636 static_cast<ui::PixelFormat>(captureArgs.pixelFormat),
7637 captureArgs.allowProtected, captureArgs.grayscale, captureListener);
7638 }
7639
7640 // Creates a Future release fence for a layer and keeps track of it in a list to
7641 // release the buffer when the Future is complete. Calls from composittion
7642 // involve needing to refresh the composition start time for stats.
attachReleaseFenceFutureToLayer(Layer * layer,LayerFE * layerFE,ui::LayerStack layerStack)7643 void SurfaceFlinger::attachReleaseFenceFutureToLayer(Layer* layer, LayerFE* layerFE,
7644 ui::LayerStack layerStack) {
7645 ftl::Future<FenceResult> futureFence = layerFE->createReleaseFenceFuture();
7646 layer->prepareReleaseCallbacks(std::move(futureFence), layerStack);
7647 }
7648
7649 // Loop over all visible layers to see whether there's any protected layer. A protected layer is
7650 // typically a layer with DRM contents, or have the GRALLOC_USAGE_PROTECTED set on the buffer.
7651 // A protected layer has no implication on whether it's secure, which is explicitly set by
7652 // application to avoid being screenshot or drawn via unsecure display.
layersHasProtectedLayer(const std::vector<std::pair<Layer *,sp<LayerFE>>> & layers) const7653 bool SurfaceFlinger::layersHasProtectedLayer(
7654 const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) const {
7655 bool protectedLayerFound = false;
7656 for (auto& [_, layerFE] : layers) {
7657 protectedLayerFound |=
7658 (layerFE->mSnapshot->isVisible && layerFE->mSnapshot->hasProtectedContent);
7659 if (protectedLayerFound) {
7660 break;
7661 }
7662 }
7663 return protectedLayerFound;
7664 }
7665
7666 // Getting layer snapshots and accessing display state should take place on
7667 // main thread. Accessing display requires mStateLock, and contention for
7668 // this lock is reduced when grabbed from the main thread, thus also reducing
7669 // risk of deadlocks. Returns false if no display is found.
getSnapshotsFromMainThread(ScreenshotArgs & args,GetLayerSnapshotsFunction getLayerSnapshotsFn,std::vector<std::pair<Layer *,sp<LayerFE>>> & layers)7670 bool SurfaceFlinger::getSnapshotsFromMainThread(
7671 ScreenshotArgs& args, GetLayerSnapshotsFunction getLayerSnapshotsFn,
7672 std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) {
7673 return mScheduler
7674 ->schedule([=, this, &args, &layers]() REQUIRES(kMainThreadContext) {
7675 SFTRACE_NAME_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Screenshot");
7676 mPowerAdvisor->setScreenshotWorkload();
7677 SFTRACE_NAME("getSnapshotsFromMainThread");
7678 layers = getLayerSnapshotsFn();
7679 // Non-threaded RenderEngine eventually returns to the main thread a 2nd time
7680 // to complete the screenshot. Release fences should only be added during the 2nd
7681 // hop to main thread in order to avoid potential deadlocks from waiting for the
7682 // the future fence to fire.
7683 if (mRenderEngine->isThreaded()) {
7684 for (auto& [layer, layerFE] : layers) {
7685 attachReleaseFenceFutureToLayer(layer, layerFE.get(),
7686 ui::INVALID_LAYER_STACK);
7687 }
7688 }
7689 return getDisplayStateOnMainThread(args);
7690 })
7691 .get();
7692 }
7693
captureScreenCommon(ScreenshotArgs & args,GetLayerSnapshotsFunction getLayerSnapshotsFn,ui::Size bufferSize,ui::PixelFormat reqPixelFormat,bool allowProtected,bool grayscale,const sp<IScreenCaptureListener> & captureListener)7694 void SurfaceFlinger::captureScreenCommon(ScreenshotArgs& args,
7695 GetLayerSnapshotsFunction getLayerSnapshotsFn,
7696 ui::Size bufferSize, ui::PixelFormat reqPixelFormat,
7697 bool allowProtected, bool grayscale,
7698 const sp<IScreenCaptureListener>& captureListener) {
7699 SFTRACE_CALL();
7700
7701 if (exceedsMaxRenderTargetSize(bufferSize.getWidth(), bufferSize.getHeight())) {
7702 ALOGE("Attempted to capture screen with size (%" PRId32 ", %" PRId32
7703 ") that exceeds render target size limit.",
7704 bufferSize.getWidth(), bufferSize.getHeight());
7705 invokeScreenCaptureError(BAD_VALUE, captureListener);
7706 return;
7707 }
7708
7709 std::vector<std::pair<Layer*, sp<LayerFE>>> layers;
7710 bool hasDisplayState = getSnapshotsFromMainThread(args, getLayerSnapshotsFn, layers);
7711 if (!hasDisplayState) {
7712 ALOGD("Display state not found");
7713 invokeScreenCaptureError(NO_MEMORY, captureListener);
7714 }
7715
7716 const bool hasHdrLayer = std::any_of(layers.cbegin(), layers.cend(), [this](const auto& layer) {
7717 return isHdrLayer(*(layer.second->mSnapshot.get()));
7718 });
7719
7720 const bool supportsProtected = getRenderEngine().supportsProtectedContent();
7721 bool hasProtectedLayer = false;
7722 if (allowProtected && supportsProtected) {
7723 hasProtectedLayer = layersHasProtectedLayer(layers);
7724 }
7725 const bool isProtected = hasProtectedLayer && allowProtected && supportsProtected;
7726 const uint32_t usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER |
7727 GRALLOC_USAGE_HW_TEXTURE |
7728 (isProtected ? GRALLOC_USAGE_PROTECTED
7729 : GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
7730 sp<GraphicBuffer> buffer =
7731 getFactory().createGraphicBuffer(bufferSize.getWidth(), bufferSize.getHeight(),
7732 static_cast<android_pixel_format>(reqPixelFormat),
7733 1 /* layerCount */, usage, "screenshot");
7734
7735 const status_t bufferStatus = buffer->initCheck();
7736 if (bufferStatus != OK) {
7737 // Animations may end up being really janky, but don't crash here.
7738 // Otherwise an irreponsible process may cause an SF crash by allocating
7739 // too much.
7740 ALOGE("%s: Buffer failed to allocate: %d", __func__, bufferStatus);
7741 invokeScreenCaptureError(bufferStatus, captureListener);
7742 return;
7743 }
7744 const std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared<
7745 renderengine::impl::ExternalTexture>(buffer, getRenderEngine(),
7746 renderengine::impl::ExternalTexture::Usage::
7747 WRITEABLE);
7748
7749 std::shared_ptr<renderengine::impl::ExternalTexture> hdrTexture;
7750 std::shared_ptr<renderengine::impl::ExternalTexture> gainmapTexture;
7751
7752 if (hasHdrLayer && !args.seamlessTransition &&
7753 FlagManager::getInstance().true_hdr_screenshots()) {
7754 const auto hdrBuffer =
7755 getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(),
7756 HAL_PIXEL_FORMAT_RGBA_FP16, 1 /* layerCount */,
7757 buffer->getUsage(), "screenshot-hdr");
7758 const auto gainmapBuffer =
7759 getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(),
7760 buffer->getPixelFormat(), 1 /* layerCount */,
7761 buffer->getUsage(), "screenshot-gainmap");
7762
7763 const status_t hdrBufferStatus = hdrBuffer->initCheck();
7764 const status_t gainmapBufferStatus = gainmapBuffer->initCheck();
7765
7766 if (hdrBufferStatus != OK || gainmapBufferStatus != -OK) {
7767 if (hdrBufferStatus != OK) {
7768 ALOGW("%s: Buffer failed to allocate for hdr: %d. Screenshoting SDR instead.",
7769 __func__, hdrBufferStatus);
7770 } else {
7771 ALOGW("%s: Buffer failed to allocate for gainmap: %d. Screenshoting SDR instead.",
7772 __func__, gainmapBufferStatus);
7773 }
7774 } else {
7775 hdrTexture = std::make_shared<
7776 renderengine::impl::ExternalTexture>(hdrBuffer, getRenderEngine(),
7777 renderengine::impl::ExternalTexture::
7778 Usage::WRITEABLE);
7779 gainmapTexture = std::make_shared<
7780 renderengine::impl::ExternalTexture>(gainmapBuffer, getRenderEngine(),
7781 renderengine::impl::ExternalTexture::
7782 Usage::WRITEABLE);
7783 }
7784 }
7785
7786 auto futureFence =
7787 captureScreenshot(args, texture, false /* regionSampling */, grayscale, isProtected,
7788 captureListener, layers, hdrTexture, gainmapTexture);
7789 futureFence.get();
7790 }
7791
7792 // Returns true if display is found and args was populated with display state
7793 // data. Otherwise, returns false.
getDisplayStateOnMainThread(ScreenshotArgs & args)7794 bool SurfaceFlinger::getDisplayStateOnMainThread(ScreenshotArgs& args) {
7795 sp<const DisplayDevice> display = nullptr;
7796 {
7797 Mutex::Autolock lock(mStateLock);
7798 // Screenshot initiated through captureLayers
7799 if (auto* layerSequence = std::get_if<int32_t>(&args.captureTypeVariant)) {
7800 // LayerSnapshotBuilder should only be accessed from the main thread.
7801 const frontend::LayerSnapshot* snapshot =
7802 mLayerSnapshotBuilder.getSnapshot(*layerSequence);
7803 if (!snapshot) {
7804 ALOGW("Couldn't find layer snapshot for %d", *layerSequence);
7805 } else {
7806 if (!args.childrenOnly) {
7807 args.transform = snapshot->localTransform.inverse();
7808 }
7809 if (args.sourceCrop.isEmpty()) {
7810 args.sourceCrop = snapshot->bufferSize;
7811 }
7812 display = findDisplay(
7813 [layerStack = snapshot->outputFilter.layerStack](const auto& display) {
7814 return display.getLayerStack() == layerStack;
7815 });
7816 }
7817
7818 // Screenshot initiated through captureDisplay
7819 } else if (auto* displayWeak =
7820 std::get_if<wp<const DisplayDevice>>(&args.captureTypeVariant)) {
7821 display = displayWeak->promote();
7822 }
7823
7824 if (display == nullptr) {
7825 display = getDefaultDisplayDeviceLocked();
7826 }
7827
7828 if (display != nullptr) {
7829 const auto& state = display->getCompositionDisplay()->getState();
7830 args.displayBrightnessNits = state.displayBrightnessNits;
7831 args.sdrWhitePointNits = state.sdrWhitePointNits;
7832 args.renderIntent = state.renderIntent;
7833 args.colorMode = state.colorMode;
7834 return true;
7835 }
7836 }
7837 return false;
7838 }
7839
captureScreenshot(ScreenshotArgs & args,const std::shared_ptr<renderengine::ExternalTexture> & buffer,bool regionSampling,bool grayscale,bool isProtected,const sp<IScreenCaptureListener> & captureListener,const std::vector<std::pair<Layer *,sp<LayerFE>>> & layers,const std::shared_ptr<renderengine::ExternalTexture> & hdrBuffer,const std::shared_ptr<renderengine::ExternalTexture> & gainmapBuffer)7840 ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot(
7841 ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>& buffer,
7842 bool regionSampling, bool grayscale, bool isProtected,
7843 const sp<IScreenCaptureListener>& captureListener,
7844 const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers,
7845 const std::shared_ptr<renderengine::ExternalTexture>& hdrBuffer,
7846 const std::shared_ptr<renderengine::ExternalTexture>& gainmapBuffer) {
7847 SFTRACE_CALL();
7848
7849 ScreenCaptureResults captureResults;
7850 ftl::SharedFuture<FenceResult> renderFuture;
7851
7852 float hdrSdrRatio = args.displayBrightnessNits / args.sdrWhitePointNits;
7853
7854 if (hdrBuffer && gainmapBuffer) {
7855 ftl::SharedFuture<FenceResult> hdrRenderFuture =
7856 renderScreenImpl(args, hdrBuffer, regionSampling, grayscale, isProtected,
7857 captureResults, layers);
7858 captureResults.buffer = buffer->getBuffer();
7859 captureResults.optionalGainMap = gainmapBuffer->getBuffer();
7860
7861 renderFuture =
7862 ftl::Future(std::move(hdrRenderFuture))
7863 .then([&, hdrSdrRatio, dataspace = captureResults.capturedDataspace, buffer,
7864 hdrBuffer, gainmapBuffer](FenceResult fenceResult) -> FenceResult {
7865 if (!fenceResult.ok()) {
7866 return fenceResult;
7867 }
7868
7869 return getRenderEngine()
7870 .tonemapAndDrawGainmap(hdrBuffer, fenceResult.value()->get(),
7871 hdrSdrRatio,
7872 static_cast<ui::Dataspace>(dataspace),
7873 buffer, gainmapBuffer)
7874 .get();
7875 })
7876 .share();
7877 } else {
7878 renderFuture = renderScreenImpl(args, buffer, regionSampling, grayscale, isProtected,
7879 captureResults, layers);
7880 }
7881
7882 if (captureListener) {
7883 // Defer blocking on renderFuture back to the Binder thread.
7884 return ftl::Future(std::move(renderFuture))
7885 .then([captureListener, captureResults = std::move(captureResults),
7886 hdrSdrRatio](FenceResult fenceResult) mutable -> FenceResult {
7887 captureResults.fenceResult = std::move(fenceResult);
7888 captureResults.hdrSdrRatio = hdrSdrRatio;
7889 captureListener->onScreenCaptureCompleted(captureResults);
7890 return base::unexpected(NO_ERROR);
7891 })
7892 .share();
7893 }
7894 return renderFuture;
7895 }
7896
renderScreenImpl(ScreenshotArgs & args,const std::shared_ptr<renderengine::ExternalTexture> & buffer,bool regionSampling,bool grayscale,bool isProtected,ScreenCaptureResults & captureResults,const std::vector<std::pair<Layer *,sp<LayerFE>>> & layers)7897 ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl(
7898 ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>& buffer,
7899 bool regionSampling, bool grayscale, bool isProtected, ScreenCaptureResults& captureResults,
7900 const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) {
7901 SFTRACE_CALL();
7902
7903 for (auto& [_, layerFE] : layers) {
7904 frontend::LayerSnapshot* snapshot = layerFE->mSnapshot.get();
7905 captureResults.capturedSecureLayers |= (snapshot->isVisible && snapshot->isSecure);
7906 captureResults.capturedHdrLayers |= isHdrLayer(*snapshot);
7907 layerFE->mSnapshot->geomLayerTransform =
7908 args.transform * layerFE->mSnapshot->geomLayerTransform;
7909 layerFE->mSnapshot->geomInverseLayerTransform =
7910 layerFE->mSnapshot->geomLayerTransform.inverse();
7911 }
7912
7913 const bool enableLocalTonemapping =
7914 FlagManager::getInstance().local_tonemap_screenshots() && !args.seamlessTransition;
7915
7916 captureResults.capturedDataspace =
7917 pickBestDataspace(args.dataspace, args.colorMode, captureResults.capturedHdrLayers,
7918 args.seamlessTransition);
7919
7920 // Only clamp the display brightness if this is not a seamless transition.
7921 // Otherwise for seamless transitions it's important to match the current
7922 // display state as the buffer will be shown under these same conditions, and we
7923 // want to avoid any flickers.
7924 if (captureResults.capturedHdrLayers) {
7925 if (!enableLocalTonemapping && args.sdrWhitePointNits > 1.0f && !args.seamlessTransition) {
7926 // Restrict the amount of HDR "headroom" in the screenshot to avoid
7927 // over-dimming the SDR portion. 2.0 chosen by experimentation
7928 constexpr float kMaxScreenshotHeadroom = 2.0f;
7929 // TODO: Aim to update displayBrightnessNits earlier in screenshot
7930 // path so ScreenshotArgs can be passed as const
7931 args.displayBrightnessNits = std::min(args.sdrWhitePointNits * kMaxScreenshotHeadroom,
7932 args.displayBrightnessNits);
7933 }
7934 } else {
7935 args.displayBrightnessNits = args.sdrWhitePointNits;
7936 }
7937
7938 auto renderIntent = RenderIntent::TONE_MAP_COLORIMETRIC;
7939 // Screenshots leaving the device should be colorimetric
7940 if (args.dataspace == ui::Dataspace::UNKNOWN && args.seamlessTransition) {
7941 renderIntent = args.renderIntent;
7942 }
7943
7944 auto capturedBuffer = buffer;
7945 captureResults.buffer = capturedBuffer->getBuffer();
7946
7947 ui::LayerStack layerStack{ui::DEFAULT_LAYER_STACK};
7948 if (!layers.empty()) {
7949 const sp<LayerFE>& layerFE = layers.back().second;
7950 layerStack = layerFE->getCompositionState()->outputFilter.layerStack;
7951 }
7952
7953 auto present = [this, buffer = capturedBuffer, dataspace = captureResults.capturedDataspace,
7954 grayscale, isProtected, layers, layerStack, regionSampling, args, renderIntent,
7955 enableLocalTonemapping]() -> FenceResult {
7956 std::unique_ptr<compositionengine::CompositionEngine> compositionEngine =
7957 mFactory.createCompositionEngine();
7958 compositionEngine->setRenderEngine(mRenderEngine.get());
7959 compositionEngine->setHwComposer(mHWComposer.get());
7960
7961 std::vector<sp<compositionengine::LayerFE>> layerFEs;
7962 layerFEs.reserve(layers.size());
7963 for (auto& [layer, layerFE] : layers) {
7964 // Release fences were not yet added for non-threaded render engine. To avoid
7965 // deadlocks between main thread and binder threads waiting for the future fence
7966 // result, fences should be added to layers in the same hop onto the main thread.
7967 if (!mRenderEngine->isThreaded()) {
7968 attachReleaseFenceFutureToLayer(layer, layerFE.get(), ui::INVALID_LAYER_STACK);
7969 }
7970 layerFEs.push_back(layerFE);
7971 }
7972
7973 compositionengine::Output::ColorProfile colorProfile{.dataspace = dataspace,
7974 .renderIntent = renderIntent};
7975
7976 float targetBrightness = 1.0f;
7977 if (enableLocalTonemapping) {
7978 // Boost the whole scene so that SDR white is at 1.0 while still communicating the hdr
7979 // sdr ratio via display brightness / sdrWhite nits.
7980 targetBrightness = args.sdrWhitePointNits / args.displayBrightnessNits;
7981 } else if (dataspace == ui::Dataspace::BT2020_HLG) {
7982 const float maxBrightnessNits =
7983 args.displayBrightnessNits / args.sdrWhitePointNits * 203;
7984 // With a low dimming ratio, don't fit the entire curve. Otherwise mixed content
7985 // will appear way too bright.
7986 if (maxBrightnessNits < 1000.f) {
7987 targetBrightness = 1000.f / maxBrightnessNits;
7988 }
7989 }
7990
7991 // Capturing screenshots using layers have a clear capture fill (0 alpha).
7992 // Capturing via display or displayId, which do not use args.layerSequence,
7993 // has an opaque capture fill (1 alpha).
7994 const float layerAlpha =
7995 std::holds_alternative<int32_t>(args.captureTypeVariant) ? 0.0f : 1.0f;
7996
7997 // Screenshots leaving the device must not dim in gamma space.
7998 const bool dimInGammaSpaceForEnhancedScreenshots =
7999 mDimInGammaSpaceForEnhancedScreenshots && args.seamlessTransition;
8000
8001 std::shared_ptr<ScreenCaptureOutput> output = createScreenCaptureOutput(
8002 ScreenCaptureOutputArgs{.compositionEngine = *compositionEngine,
8003 .colorProfile = colorProfile,
8004 .layerStack = layerStack,
8005 .sourceCrop = args.sourceCrop,
8006 .buffer = std::move(buffer),
8007 .displayIdVariant = args.displayIdVariant,
8008 .reqBufferSize = args.reqSize,
8009 .sdrWhitePointNits = args.sdrWhitePointNits,
8010 .displayBrightnessNits = args.displayBrightnessNits,
8011 .targetBrightness = targetBrightness,
8012 .layerAlpha = layerAlpha,
8013 .regionSampling = regionSampling,
8014 .treat170mAsSrgb = mTreat170mAsSrgb,
8015 .dimInGammaSpaceForEnhancedScreenshots =
8016 dimInGammaSpaceForEnhancedScreenshots,
8017 .isSecure = args.isSecure,
8018 .isProtected = isProtected,
8019 .enableLocalTonemapping = enableLocalTonemapping});
8020
8021 const float colorSaturation = grayscale ? 0 : 1;
8022 compositionengine::CompositionRefreshArgs refreshArgs{
8023 .outputs = {output},
8024 .layers = std::move(layerFEs),
8025 .updatingOutputGeometryThisFrame = true,
8026 .updatingGeometryThisFrame = true,
8027 .colorTransformMatrix = calculateColorMatrix(colorSaturation),
8028 };
8029 compositionEngine->present(refreshArgs);
8030
8031 return output->getRenderSurface()->getClientTargetAcquireFence();
8032 };
8033
8034 // If RenderEngine is threaded, we can safely call CompositionEngine::present off the main
8035 // thread as the RenderEngine::drawLayers call will run on RenderEngine's thread. Otherwise,
8036 // we need RenderEngine to run on the main thread so we call CompositionEngine::present
8037 // immediately.
8038 //
8039 // TODO(b/196334700) Once we use RenderEngineThreaded everywhere we can always defer the call
8040 // to CompositionEngine::present.
8041 ftl::SharedFuture<FenceResult> presentFuture = mRenderEngine->isThreaded()
8042 ? ftl::yield(present()).share()
8043 : mScheduler->schedule(std::move(present)).share();
8044
8045 return presentFuture;
8046 }
8047
traverseLegacyLayers(const LayerVector::Visitor & visitor) const8048 void SurfaceFlinger::traverseLegacyLayers(const LayerVector::Visitor& visitor) const {
8049 for (auto& layer : mLegacyLayers) {
8050 visitor(layer.second.get());
8051 }
8052 }
8053
8054 // ---------------------------------------------------------------------------
8055
getPreferredDisplayMode(PhysicalDisplayId displayId,DisplayModeId defaultModeId) const8056 ftl::Optional<scheduler::FrameRateMode> SurfaceFlinger::getPreferredDisplayMode(
8057 PhysicalDisplayId displayId, DisplayModeId defaultModeId) const {
8058 if (const auto schedulerMode = mScheduler->getPreferredDisplayMode();
8059 schedulerMode.modePtr->getPhysicalDisplayId() == displayId) {
8060 return schedulerMode;
8061 }
8062
8063 return mPhysicalDisplays.get(displayId)
8064 .transform(&PhysicalDisplay::snapshotRef)
8065 .and_then([&](const display::DisplaySnapshot& snapshot) {
8066 return snapshot.displayModes().get(defaultModeId);
8067 })
8068 .transform([](const DisplayModePtr& modePtr) {
8069 return scheduler::FrameRateMode{modePtr->getPeakFps(), ftl::as_non_null(modePtr)};
8070 });
8071 }
8072
setDesiredDisplayModeSpecsInternal(const sp<DisplayDevice> & display,const scheduler::RefreshRateSelector::PolicyVariant & policy)8073 status_t SurfaceFlinger::setDesiredDisplayModeSpecsInternal(
8074 const sp<DisplayDevice>& display,
8075 const scheduler::RefreshRateSelector::PolicyVariant& policy) {
8076 const auto displayId = display->getPhysicalId();
8077 SFTRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str());
8078
8079 Mutex::Autolock lock(mStateLock);
8080
8081 if (mDebugDisplayModeSetByBackdoor) {
8082 // ignore this request as mode is overridden by backdoor
8083 return NO_ERROR;
8084 }
8085
8086 auto& selector = display->refreshRateSelector();
8087 using SetPolicyResult = scheduler::RefreshRateSelector::SetPolicyResult;
8088
8089 switch (selector.setPolicy(policy)) {
8090 case SetPolicyResult::Invalid:
8091 return BAD_VALUE;
8092 case SetPolicyResult::Unchanged:
8093 return NO_ERROR;
8094 case SetPolicyResult::Changed:
8095 break;
8096 }
8097
8098 return applyRefreshRateSelectorPolicy(displayId, selector);
8099 }
8100
applyRefreshRateSelectorPolicy(PhysicalDisplayId displayId,const scheduler::RefreshRateSelector & selector)8101 status_t SurfaceFlinger::applyRefreshRateSelectorPolicy(
8102 PhysicalDisplayId displayId, const scheduler::RefreshRateSelector& selector) {
8103 const scheduler::RefreshRateSelector::Policy currentPolicy = selector.getCurrentPolicy();
8104 ALOGV("Setting desired display mode specs: %s", currentPolicy.toString().c_str());
8105
8106 if (mScheduler->onDisplayModeChanged(displayId, selector.getActiveMode(),
8107 /*clearContentRequirements*/ true)) {
8108 mDisplayModeController.updateKernelIdleTimer(displayId);
8109 }
8110
8111 auto preferredModeOpt = getPreferredDisplayMode(displayId, currentPolicy.defaultMode);
8112 if (!preferredModeOpt) {
8113 ALOGE("%s: Preferred mode is unknown", __func__);
8114 return NAME_NOT_FOUND;
8115 }
8116
8117 auto preferredMode = std::move(*preferredModeOpt);
8118 const auto preferredModeId = preferredMode.modePtr->getId();
8119
8120 const Fps preferredFps = preferredMode.fps;
8121 ALOGV("Switching to Scheduler preferred mode %d (%s)", ftl::to_underlying(preferredModeId),
8122 to_string(preferredFps).c_str());
8123
8124 if (!selector.isModeAllowed(preferredMode)) {
8125 ALOGE("%s: Preferred mode %d is disallowed", __func__, ftl::to_underlying(preferredModeId));
8126 return INVALID_OPERATION;
8127 }
8128
8129 setDesiredMode({std::move(preferredMode), .emitEvent = true});
8130
8131 // Update the frameRateOverride list as the display render rate might have changed
8132 mScheduler->updateFrameRateOverrides(scheduler::GlobalSignals{}, preferredFps);
8133 return NO_ERROR;
8134 }
8135
8136 namespace {
translate(const gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange & aidlRange)8137 FpsRange translate(const gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange& aidlRange) {
8138 return FpsRange{Fps::fromValue(aidlRange.min), Fps::fromValue(aidlRange.max)};
8139 }
8140
translate(const gui::DisplayModeSpecs::RefreshRateRanges & aidlRanges)8141 FpsRanges translate(const gui::DisplayModeSpecs::RefreshRateRanges& aidlRanges) {
8142 return FpsRanges{translate(aidlRanges.physical), translate(aidlRanges.render)};
8143 }
8144
translate(const FpsRange & range)8145 gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange translate(const FpsRange& range) {
8146 gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange aidlRange;
8147 aidlRange.min = range.min.getValue();
8148 aidlRange.max = range.max.getValue();
8149 return aidlRange;
8150 }
8151
translate(const FpsRanges & ranges)8152 gui::DisplayModeSpecs::RefreshRateRanges translate(const FpsRanges& ranges) {
8153 gui::DisplayModeSpecs::RefreshRateRanges aidlRanges;
8154 aidlRanges.physical = translate(ranges.physical);
8155 aidlRanges.render = translate(ranges.render);
8156 return aidlRanges;
8157 }
8158
8159 } // namespace
8160
setDesiredDisplayModeSpecs(const sp<IBinder> & displayToken,const gui::DisplayModeSpecs & specs)8161 status_t SurfaceFlinger::setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
8162 const gui::DisplayModeSpecs& specs) {
8163 SFTRACE_CALL();
8164
8165 if (!displayToken) {
8166 return BAD_VALUE;
8167 }
8168
8169 auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) -> status_t {
8170 const auto display = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(displayToken));
8171 if (!display) {
8172 ALOGE("Attempt to set desired display modes for invalid display token %p",
8173 displayToken.get());
8174 return NAME_NOT_FOUND;
8175 } else if (display->isVirtual()) {
8176 ALOGW("Attempt to set desired display modes for virtual display");
8177 return INVALID_OPERATION;
8178 } else {
8179 using Policy = scheduler::RefreshRateSelector::DisplayManagerPolicy;
8180 const auto idleScreenConfigOpt =
8181 FlagManager::getInstance().idle_screen_refresh_rate_timeout()
8182 ? specs.idleScreenRefreshRateConfig
8183 : std::nullopt;
8184 const Policy policy{DisplayModeId(specs.defaultMode), translate(specs.primaryRanges),
8185 translate(specs.appRequestRanges), specs.allowGroupSwitching,
8186 idleScreenConfigOpt};
8187
8188 return setDesiredDisplayModeSpecsInternal(display, policy);
8189 }
8190 });
8191
8192 return future.get();
8193 }
8194
getDesiredDisplayModeSpecs(const sp<IBinder> & displayToken,gui::DisplayModeSpecs * outSpecs)8195 status_t SurfaceFlinger::getDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
8196 gui::DisplayModeSpecs* outSpecs) {
8197 SFTRACE_CALL();
8198
8199 if (!displayToken || !outSpecs) {
8200 return BAD_VALUE;
8201 }
8202
8203 Mutex::Autolock lock(mStateLock);
8204 const auto display = getDisplayDeviceLocked(displayToken);
8205 if (!display) {
8206 return NAME_NOT_FOUND;
8207 }
8208
8209 if (display->isVirtual()) {
8210 return INVALID_OPERATION;
8211 }
8212
8213 scheduler::RefreshRateSelector::Policy policy =
8214 display->refreshRateSelector().getDisplayManagerPolicy();
8215 outSpecs->defaultMode = ftl::to_underlying(policy.defaultMode);
8216 outSpecs->allowGroupSwitching = policy.allowGroupSwitching;
8217 outSpecs->primaryRanges = translate(policy.primaryRanges);
8218 outSpecs->appRequestRanges = translate(policy.appRequestRanges);
8219 return NO_ERROR;
8220 }
8221
onLayerFirstRef(Layer * layer)8222 void SurfaceFlinger::onLayerFirstRef(Layer* layer) {
8223 mNumLayers++;
8224 mScheduler->registerLayer(layer, scheduler::FrameRateCompatibility::Default);
8225 }
8226
onLayerDestroyed(Layer * layer)8227 void SurfaceFlinger::onLayerDestroyed(Layer* layer) {
8228 mNumLayers--;
8229 mScheduler->deregisterLayer(layer);
8230 if (mTransactionTracing) {
8231 mTransactionTracing->onLayerRemoved(layer->getSequence());
8232 }
8233 mScheduler->onLayerDestroyed(layer);
8234 }
8235
onLayerUpdate()8236 void SurfaceFlinger::onLayerUpdate() {
8237 scheduleCommit(FrameHint::kActive);
8238 }
8239
setGlobalShadowSettings(const half4 & ambientColor,const half4 & spotColor,float lightPosY,float lightPosZ,float lightRadius)8240 status_t SurfaceFlinger::setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
8241 float lightPosY, float lightPosZ,
8242 float lightRadius) {
8243 Mutex::Autolock _l(mStateLock);
8244 mCurrentState.globalShadowSettings.ambientColor = vec4(ambientColor);
8245 mCurrentState.globalShadowSettings.spotColor = vec4(spotColor);
8246 mCurrentState.globalShadowSettings.lightPos.y = lightPosY;
8247 mCurrentState.globalShadowSettings.lightPos.z = lightPosZ;
8248 mCurrentState.globalShadowSettings.lightRadius = lightRadius;
8249
8250 // these values are overridden when calculating the shadow settings for a layer.
8251 mCurrentState.globalShadowSettings.lightPos.x = 0.f;
8252 mCurrentState.globalShadowSettings.length = 0.f;
8253 return NO_ERROR;
8254 }
8255
getGenericLayerMetadataKeyMap() const8256 const std::unordered_map<std::string, uint32_t>& SurfaceFlinger::getGenericLayerMetadataKeyMap()
8257 const {
8258 // TODO(b/149500060): Remove this fixed/static mapping. Please prefer taking
8259 // on the work to remove the table in that bug rather than adding more to
8260 // it.
8261 static const std::unordered_map<std::string, uint32_t> genericLayerMetadataKeyMap{
8262 {"org.chromium.arc.V1_0.TaskId", gui::METADATA_TASK_ID},
8263 {"org.chromium.arc.V1_0.CursorInfo", gui::METADATA_MOUSE_CURSOR},
8264 };
8265 return genericLayerMetadataKeyMap;
8266 }
8267
setGameModeFrameRateOverride(uid_t uid,float frameRate)8268 status_t SurfaceFlinger::setGameModeFrameRateOverride(uid_t uid, float frameRate) {
8269 mScheduler->setGameModeFrameRateForUid(FrameRateOverride{uid, frameRate});
8270 return NO_ERROR;
8271 }
8272
setGameDefaultFrameRateOverride(uid_t uid,float frameRate)8273 status_t SurfaceFlinger::setGameDefaultFrameRateOverride(uid_t uid, float frameRate) {
8274 if (FlagManager::getInstance().game_default_frame_rate()) {
8275 mScheduler->setGameDefaultFrameRateForUid(
8276 FrameRateOverride{static_cast<uid_t>(uid), frameRate});
8277 }
8278 return NO_ERROR;
8279 }
8280
updateSmallAreaDetection(std::vector<std::pair<int32_t,float>> & appIdThresholdMappings)8281 status_t SurfaceFlinger::updateSmallAreaDetection(
8282 std::vector<std::pair<int32_t, float>>& appIdThresholdMappings) {
8283 mScheduler->updateSmallAreaDetection(appIdThresholdMappings);
8284 return NO_ERROR;
8285 }
8286
setSmallAreaDetectionThreshold(int32_t appId,float threshold)8287 status_t SurfaceFlinger::setSmallAreaDetectionThreshold(int32_t appId, float threshold) {
8288 mScheduler->setSmallAreaDetectionThreshold(appId, threshold);
8289 return NO_ERROR;
8290 }
8291
enableRefreshRateOverlay(bool enable)8292 void SurfaceFlinger::enableRefreshRateOverlay(bool enable) {
8293 bool setByHwc = getHwComposer().hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG);
8294 for (const auto& [displayId, physical] : mPhysicalDisplays) {
8295 if (physical.snapshot().connectionType() == ui::DisplayConnectionType::Internal ||
8296 FlagManager::getInstance().refresh_rate_overlay_on_external_display()) {
8297 if (const auto display = getDisplayDeviceLocked(displayId)) {
8298 const auto enableOverlay = [&](bool setByHwc) FTL_FAKE_GUARD(kMainThreadContext) {
8299 const auto activeMode = mDisplayModeController.getActiveMode(displayId);
8300 const Fps refreshRate = activeMode.modePtr->getVsyncRate();
8301 const Fps renderFps = activeMode.fps;
8302
8303 display->enableRefreshRateOverlay(enable, setByHwc, refreshRate, renderFps,
8304 mRefreshRateOverlaySpinner,
8305 mRefreshRateOverlayRenderRate,
8306 mRefreshRateOverlayShowInMiddle);
8307 };
8308
8309 enableOverlay(setByHwc);
8310 if (setByHwc) {
8311 const auto status =
8312 getHwComposer().setRefreshRateChangedCallbackDebugEnabled(displayId,
8313 enable);
8314 if (status != NO_ERROR) {
8315 ALOGE("Error %s refresh rate changed callback debug",
8316 enable ? "enabling" : "disabling");
8317 enableOverlay(/*setByHwc*/ false);
8318 }
8319 }
8320 }
8321 }
8322 }
8323 }
8324
enableHdrSdrRatioOverlay(bool enable)8325 void SurfaceFlinger::enableHdrSdrRatioOverlay(bool enable) {
8326 for (const auto& [id, display] : mPhysicalDisplays) {
8327 if (display.snapshot().connectionType() == ui::DisplayConnectionType::Internal) {
8328 if (const auto device = getDisplayDeviceLocked(id)) {
8329 device->enableHdrSdrRatioOverlay(enable);
8330 }
8331 }
8332 }
8333 }
8334
getGpuContextPriority()8335 int SurfaceFlinger::getGpuContextPriority() {
8336 return getRenderEngine().getContextPriority();
8337 }
8338
calculateMaxAcquiredBufferCount(Fps refreshRate,std::chrono::nanoseconds presentLatency)8339 int SurfaceFlinger::calculateMaxAcquiredBufferCount(Fps refreshRate,
8340 std::chrono::nanoseconds presentLatency) {
8341 int64_t pipelineDepth = presentLatency.count() / refreshRate.getPeriodNsecs();
8342 if (presentLatency.count() % refreshRate.getPeriodNsecs()) {
8343 pipelineDepth++;
8344 }
8345 const int64_t maxAcquiredBuffers =
8346 std::min(pipelineDepth - 1, maxAcquiredBuffersOpt.value_or(pipelineDepth - 1));
8347 return std::max(minAcquiredBuffers, maxAcquiredBuffers);
8348 }
8349
getMaxAcquiredBufferCount(int * buffers) const8350 status_t SurfaceFlinger::getMaxAcquiredBufferCount(int* buffers) const {
8351 Fps maxRefreshRate = 60_Hz;
8352
8353 if (!getHwComposer().isHeadless()) {
8354 if (const auto display = getDefaultDisplayDevice()) {
8355 maxRefreshRate = display->refreshRateSelector().getSupportedRefreshRateRange().max;
8356 }
8357 }
8358
8359 *buffers = getMaxAcquiredBufferCountForRefreshRate(maxRefreshRate);
8360 return NO_ERROR;
8361 }
8362
getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const8363 uint32_t SurfaceFlinger::getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const {
8364 Fps refreshRate = 60_Hz;
8365
8366 if (const auto frameRateOverride = mScheduler->getFrameRateOverride(uid)) {
8367 refreshRate = *frameRateOverride;
8368 } else if (!getHwComposer().isHeadless()) {
8369 if (const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked())) {
8370 refreshRate = display->refreshRateSelector().getActiveMode().fps;
8371 }
8372 }
8373
8374 return getMaxAcquiredBufferCountForRefreshRate(refreshRate);
8375 }
8376
getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) const8377 int SurfaceFlinger::getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) const {
8378 const auto vsyncConfig = mScheduler->getVsyncConfigsForRefreshRate(refreshRate).late;
8379 const auto presentLatency = vsyncConfig.appWorkDuration + vsyncConfig.sfWorkDuration;
8380 return calculateMaxAcquiredBufferCount(refreshRate, presentLatency);
8381 }
8382
sample()8383 void SurfaceFlinger::sample() {
8384 if (!mLumaSampling || !mRegionSamplingThread) {
8385 return;
8386 }
8387
8388 const auto scheduledFrameResultOpt = mScheduler->getScheduledFrameResult();
8389 const auto scheduleFrameTimeOpt = scheduledFrameResultOpt
8390 ? std::optional{scheduledFrameResultOpt->callbackTime}
8391 : std::nullopt;
8392 mRegionSamplingThread->onCompositionComplete(scheduleFrameTimeOpt);
8393 }
8394
onActiveDisplaySizeChanged(const DisplayDevice & activeDisplay)8395 void SurfaceFlinger::onActiveDisplaySizeChanged(const DisplayDevice& activeDisplay) {
8396 mScheduler->onActiveDisplayAreaChanged(activeDisplay.getWidth() * activeDisplay.getHeight());
8397 getRenderEngine().onActiveDisplaySizeChanged(activeDisplay.getSize());
8398 }
8399
getActivatableDisplay() const8400 sp<DisplayDevice> SurfaceFlinger::getActivatableDisplay() const {
8401 if (mPhysicalDisplays.size() == 1) return nullptr;
8402
8403 // TODO(b/255635821): Choose the pacesetter display, considering both internal and external
8404 // displays. For now, pick the other internal display, assuming a dual-display foldable.
8405 return findDisplay([this](const DisplayDevice& display) REQUIRES(mStateLock) {
8406 const auto idOpt = asPhysicalDisplayId(display.getDisplayIdVariant());
8407 return idOpt.has_value() && *idOpt != mActiveDisplayId && display.isPoweredOn() &&
8408 mPhysicalDisplays.get(*idOpt)
8409 .transform(&PhysicalDisplay::isInternal)
8410 .value_or(false);
8411 });
8412 }
8413
onActiveDisplayChangedLocked(const DisplayDevice * inactiveDisplayPtr,const DisplayDevice & activeDisplay)8414 void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveDisplayPtr,
8415 const DisplayDevice& activeDisplay) {
8416 SFTRACE_CALL();
8417
8418 if (inactiveDisplayPtr) {
8419 inactiveDisplayPtr->getCompositionDisplay()->setLayerCachingTexturePoolEnabled(false);
8420 }
8421
8422 mActiveDisplayId = activeDisplay.getPhysicalId();
8423 activeDisplay.getCompositionDisplay()->setLayerCachingTexturePoolEnabled(true);
8424
8425 // TODO(b/255635711): Check for pending mode changes on other displays.
8426 mScheduler->setModeChangePending(false);
8427
8428 mScheduler->setPacesetterDisplay(mActiveDisplayId);
8429
8430 onActiveDisplaySizeChanged(activeDisplay);
8431 mActiveDisplayTransformHint = activeDisplay.getTransformHint();
8432 sActiveDisplayRotationFlags = ui::Transform::toRotationFlags(activeDisplay.getOrientation());
8433
8434 // Whether or not the policy of the new active/pacesetter display changed while it was inactive
8435 // (in which case its preferred mode has already been propagated to HWC via setDesiredMode), the
8436 // Scheduler's cachedModeChangedParams must be initialized to the newly active mode, and the
8437 // kernel idle timer of the newly active display must be toggled.
8438 applyRefreshRateSelectorPolicy(mActiveDisplayId, activeDisplay.refreshRateSelector());
8439 }
8440
addWindowInfosListener(const sp<IWindowInfosListener> & windowInfosListener,gui::WindowInfosListenerInfo * outInfo)8441 status_t SurfaceFlinger::addWindowInfosListener(const sp<IWindowInfosListener>& windowInfosListener,
8442 gui::WindowInfosListenerInfo* outInfo) {
8443 mWindowInfosListenerInvoker->addWindowInfosListener(windowInfosListener, outInfo);
8444 setTransactionFlags(eInputInfoUpdateNeeded);
8445 return NO_ERROR;
8446 }
8447
removeWindowInfosListener(const sp<IWindowInfosListener> & windowInfosListener) const8448 status_t SurfaceFlinger::removeWindowInfosListener(
8449 const sp<IWindowInfosListener>& windowInfosListener) const {
8450 mWindowInfosListenerInvoker->removeWindowInfosListener(windowInfosListener);
8451 return NO_ERROR;
8452 }
8453
getStalledTransactionInfo(int pid,std::optional<TransactionHandler::StalledTransactionInfo> & result)8454 status_t SurfaceFlinger::getStalledTransactionInfo(
8455 int pid, std::optional<TransactionHandler::StalledTransactionInfo>& result) {
8456 // Used to add a stalled transaction which uses an internal lock.
8457 ftl::FakeGuard guard(kMainThreadContext);
8458 result = mTransactionHandler.getStalledTransactionInfo(pid);
8459 return NO_ERROR;
8460 }
8461
updateHdcpLevels(hal::HWDisplayId hwcDisplayId,int32_t connectedLevel,int32_t maxLevel)8462 void SurfaceFlinger::updateHdcpLevels(hal::HWDisplayId hwcDisplayId, int32_t connectedLevel,
8463 int32_t maxLevel) {
8464 Mutex::Autolock lock(mStateLock);
8465
8466 const auto idOpt = getHwComposer().toPhysicalDisplayId(hwcDisplayId);
8467 if (!idOpt) {
8468 ALOGE("No display found for HDCP level changed event: connected=%d, max=%d for "
8469 "display=%" PRIu64,
8470 connectedLevel, maxLevel, hwcDisplayId);
8471 return;
8472 }
8473
8474 const bool isInternalDisplay =
8475 mPhysicalDisplays.get(*idOpt).transform(&PhysicalDisplay::isInternal).value_or(false);
8476 if (isInternalDisplay) {
8477 ALOGW("Unexpected HDCP level changed for internal display: connected=%d, max=%d for "
8478 "display=%" PRIu64,
8479 connectedLevel, maxLevel, hwcDisplayId);
8480 return;
8481 }
8482
8483 static_cast<void>(mScheduler->schedule([this, displayId = *idOpt, connectedLevel, maxLevel]() {
8484 const bool secure = connectedLevel >= 2 /* HDCP_V1 */;
8485 if (const auto display = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(displayId))) {
8486 Mutex::Autolock lock(mStateLock);
8487 display->setSecure(secure);
8488 }
8489 FTL_FAKE_GUARD(kMainThreadContext, mDisplayModeController.setSecure(displayId, secure));
8490 mScheduler->onHdcpLevelsChanged(scheduler::Cycle::Render, displayId, connectedLevel,
8491 maxLevel);
8492 }));
8493 }
8494
addActivePictureListener(const sp<gui::IActivePictureListener> & listener)8495 void SurfaceFlinger::addActivePictureListener(const sp<gui::IActivePictureListener>& listener) {
8496 Mutex::Autolock lock(mStateLock);
8497 std::erase_if(mActivePictureListenersToRemove, [listener](const auto& otherListener) {
8498 return IInterface::asBinder(listener) == IInterface::asBinder(otherListener);
8499 });
8500 mActivePictureListenersToAdd.push_back(listener);
8501 }
8502
removeActivePictureListener(const sp<gui::IActivePictureListener> & listener)8503 void SurfaceFlinger::removeActivePictureListener(const sp<gui::IActivePictureListener>& listener) {
8504 Mutex::Autolock lock(mStateLock);
8505 std::erase_if(mActivePictureListenersToAdd, [listener](const auto& otherListener) {
8506 return IInterface::asBinder(listener) == IInterface::asBinder(otherListener);
8507 });
8508 mActivePictureListenersToRemove.push_back(listener);
8509 }
8510
getExternalTextureFromBufferData(BufferData & bufferData,const char * layerName,uint64_t transactionId)8511 std::shared_ptr<renderengine::ExternalTexture> SurfaceFlinger::getExternalTextureFromBufferData(
8512 BufferData& bufferData, const char* layerName, uint64_t transactionId) {
8513 if (bufferData.buffer &&
8514 exceedsMaxRenderTargetSize(bufferData.buffer->getWidth(), bufferData.buffer->getHeight())) {
8515 std::string errorMessage =
8516 base::StringPrintf("Attempted to create an ExternalTexture with size (%u, %u) for "
8517 "layer %s that exceeds render target size limit of %u.",
8518 bufferData.buffer->getWidth(), bufferData.buffer->getHeight(),
8519 layerName, static_cast<uint32_t>(mMaxRenderTargetSize));
8520 ALOGD("%s", errorMessage.c_str());
8521 if (bufferData.releaseBufferListener) {
8522 bufferData.releaseBufferListener->onTransactionQueueStalled(
8523 String8(errorMessage.c_str()));
8524 }
8525 return nullptr;
8526 }
8527
8528 bool cachedBufferChanged =
8529 bufferData.flags.test(BufferData::BufferDataChange::cachedBufferChanged);
8530 if (cachedBufferChanged && bufferData.buffer) {
8531 auto result = ClientCache::getInstance().add(bufferData.cachedBuffer, bufferData.buffer);
8532 if (result.ok()) {
8533 return result.value();
8534 }
8535
8536 if (result.error() == ClientCache::AddError::CacheFull) {
8537 ALOGE("Attempted to create an ExternalTexture for layer %s but CacheFull", layerName);
8538
8539 if (bufferData.releaseBufferListener) {
8540 bufferData.releaseBufferListener->onTransactionQueueStalled(
8541 String8("Buffer processing hung due to full buffer cache"));
8542 }
8543 }
8544
8545 return nullptr;
8546 }
8547
8548 if (cachedBufferChanged) {
8549 return ClientCache::getInstance().get(bufferData.cachedBuffer);
8550 }
8551
8552 if (bufferData.buffer) {
8553 return std::make_shared<
8554 renderengine::impl::ExternalTexture>(bufferData.buffer, getRenderEngine(),
8555 renderengine::impl::ExternalTexture::Usage::
8556 READABLE);
8557 }
8558
8559 return nullptr;
8560 }
8561
moveSnapshotsFromCompositionArgs(compositionengine::CompositionRefreshArgs & refreshArgs,const std::vector<std::pair<Layer *,LayerFE * >> & layers)8562 void SurfaceFlinger::moveSnapshotsFromCompositionArgs(
8563 compositionengine::CompositionRefreshArgs& refreshArgs,
8564 const std::vector<std::pair<Layer*, LayerFE*>>& layers) {
8565 std::vector<std::unique_ptr<frontend::LayerSnapshot>>& snapshots =
8566 mLayerSnapshotBuilder.getSnapshots();
8567 for (auto [_, layerFE] : layers) {
8568 auto i = layerFE->mSnapshot->globalZ;
8569 snapshots[i] = std::move(layerFE->mSnapshot);
8570 }
8571 }
8572
moveSnapshotsToCompositionArgs(compositionengine::CompositionRefreshArgs & refreshArgs,bool cursorOnly)8573 std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToCompositionArgs(
8574 compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly) {
8575 std::vector<std::pair<Layer*, LayerFE*>> layers;
8576 nsecs_t currentTime = systemTime();
8577 const bool needsMetadata = mCompositionEngine->getFeatureFlags().test(
8578 compositionengine::Feature::kSnapshotLayerMetadata);
8579 mLayerSnapshotBuilder.forEachSnapshot(
8580 [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD(
8581 kMainThreadContext) {
8582 if (cursorOnly &&
8583 snapshot->compositionType !=
8584 aidl::android::hardware::graphics::composer3::Composition::CURSOR) {
8585 return;
8586 }
8587
8588 if (!snapshot->hasSomethingToDraw()) {
8589 return;
8590 }
8591
8592 auto it = mLegacyLayers.find(snapshot->sequence);
8593 LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
8594 "Couldnt find layer object for %s",
8595 snapshot->getDebugString().c_str());
8596 auto& legacyLayer = it->second;
8597 sp<LayerFE> layerFE = legacyLayer->getCompositionEngineLayerFE(snapshot->path);
8598 snapshot->fps = getLayerFramerate(currentTime, snapshot->sequence);
8599 layerFE->mSnapshot = std::move(snapshot);
8600 refreshArgs.layers.push_back(layerFE);
8601 layers.emplace_back(legacyLayer.get(), layerFE.get());
8602 },
8603 [needsMetadata](const frontend::LayerSnapshot& snapshot) {
8604 return snapshot.isVisible ||
8605 (needsMetadata &&
8606 snapshot.changes.test(frontend::RequestedLayerState::Changes::Metadata));
8607 });
8608 return layers;
8609 }
8610
8611 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)8612 SurfaceFlinger::getLayerSnapshotsForScreenshots(
8613 std::optional<ui::LayerStack> layerStack, uint32_t uid,
8614 std::function<bool(const frontend::LayerSnapshot&, bool& outStopTraversal)>
8615 snapshotFilterFn) {
8616 return [&, layerStack, uid]() FTL_FAKE_GUARD(kMainThreadContext) {
8617 std::vector<std::pair<Layer*, sp<LayerFE>>> layers;
8618 bool stopTraversal = false;
8619 mLayerSnapshotBuilder.forEachVisibleSnapshot(
8620 [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD(
8621 kMainThreadContext) {
8622 if (stopTraversal) {
8623 return;
8624 }
8625 if (layerStack && snapshot->outputFilter.layerStack != *layerStack) {
8626 return;
8627 }
8628 if (uid != CaptureArgs::UNSET_UID && snapshot->uid != gui::Uid(uid)) {
8629 return;
8630 }
8631 if (!snapshot->hasSomethingToDraw()) {
8632 return;
8633 }
8634 if (snapshotFilterFn && !snapshotFilterFn(*snapshot, stopTraversal)) {
8635 return;
8636 }
8637
8638 auto it = mLegacyLayers.find(snapshot->sequence);
8639 LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
8640 "Couldnt find layer object for %s",
8641 snapshot->getDebugString().c_str());
8642 Layer* legacyLayer = (it == mLegacyLayers.end()) ? nullptr : it->second.get();
8643 sp<LayerFE> layerFE = getFactory().createLayerFE(snapshot->name, legacyLayer);
8644 layerFE->mSnapshot = std::make_unique<frontend::LayerSnapshot>(*snapshot);
8645 layers.emplace_back(legacyLayer, std::move(layerFE));
8646 });
8647
8648 return layers;
8649 };
8650 }
8651
8652 std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>
getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> layerStack,uint32_t uid,std::unordered_set<uint32_t> excludeLayerIds)8653 SurfaceFlinger::getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> layerStack,
8654 uint32_t uid,
8655 std::unordered_set<uint32_t> excludeLayerIds) {
8656 return [&, layerStack, uid,
8657 excludeLayerIds = std::move(excludeLayerIds)]() FTL_FAKE_GUARD(kMainThreadContext) {
8658 if (excludeLayerIds.empty()) {
8659 auto getLayerSnapshotsFn =
8660 getLayerSnapshotsForScreenshots(layerStack, uid, /*snapshotFilterFn=*/nullptr);
8661 std::vector<std::pair<Layer*, sp<LayerFE>>> layers = getLayerSnapshotsFn();
8662 return layers;
8663 }
8664
8665 frontend::LayerSnapshotBuilder::Args
8666 args{.root = mLayerHierarchyBuilder.getHierarchy(),
8667 .layerLifecycleManager = mLayerLifecycleManager,
8668 .forceUpdate = frontend::LayerSnapshotBuilder::ForceUpdateFlags::HIERARCHY,
8669 .displays = mFrontEndDisplayInfos,
8670 .displayChanges = true,
8671 .globalShadowSettings = mDrawingState.globalShadowSettings,
8672 .supportsBlur = mSupportsBlur,
8673 .forceFullDamage = mForceFullDamage,
8674 .excludeLayerIds = std::move(excludeLayerIds),
8675 .supportedLayerGenericMetadata =
8676 getHwComposer().getSupportedLayerGenericMetadata(),
8677 .genericLayerMetadataKeyMap = getGenericLayerMetadataKeyMap(),
8678 .skipRoundCornersWhenProtected =
8679 !getRenderEngine().supportsProtectedContent()};
8680 mLayerSnapshotBuilder.update(args);
8681
8682 auto getLayerSnapshotsFn =
8683 getLayerSnapshotsForScreenshots(layerStack, uid, /*snapshotFilterFn=*/nullptr);
8684 std::vector<std::pair<Layer*, sp<LayerFE>>> layers = getLayerSnapshotsFn();
8685
8686 args.excludeLayerIds.clear();
8687 mLayerSnapshotBuilder.update(args);
8688
8689 return layers;
8690 };
8691 }
8692
8693 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)8694 SurfaceFlinger::getLayerSnapshotsForScreenshots(uint32_t rootLayerId, uint32_t uid,
8695 std::unordered_set<uint32_t> excludeLayerIds,
8696 bool childrenOnly,
8697 const std::optional<FloatRect>& parentCrop) {
8698 return [&, rootLayerId, uid, excludeLayerIds = std::move(excludeLayerIds), childrenOnly,
8699 parentCrop]() FTL_FAKE_GUARD(kMainThreadContext) {
8700 auto root = mLayerHierarchyBuilder.getPartialHierarchy(rootLayerId, childrenOnly);
8701 frontend::LayerSnapshotBuilder::Args
8702 args{.root = root,
8703 .layerLifecycleManager = mLayerLifecycleManager,
8704 .forceUpdate = frontend::LayerSnapshotBuilder::ForceUpdateFlags::HIERARCHY,
8705 .displays = mFrontEndDisplayInfos,
8706 .displayChanges = true,
8707 .globalShadowSettings = mDrawingState.globalShadowSettings,
8708 .supportsBlur = mSupportsBlur,
8709 .forceFullDamage = mForceFullDamage,
8710 .parentCrop = parentCrop,
8711 .excludeLayerIds = std::move(excludeLayerIds),
8712 .supportedLayerGenericMetadata =
8713 getHwComposer().getSupportedLayerGenericMetadata(),
8714 .genericLayerMetadataKeyMap = getGenericLayerMetadataKeyMap(),
8715 .skipRoundCornersWhenProtected =
8716 !getRenderEngine().supportsProtectedContent()};
8717 // The layer may not exist if it was just created and a screenshot was requested immediately
8718 // after. In this case, the hierarchy will be empty so we will not render any layers.
8719 args.rootSnapshot.isSecure = mLayerLifecycleManager.getLayerFromId(rootLayerId) &&
8720 mLayerLifecycleManager.isLayerSecure(rootLayerId);
8721 mLayerSnapshotBuilder.update(args);
8722
8723 auto getLayerSnapshotsFn =
8724 getLayerSnapshotsForScreenshots({}, uid, /*snapshotFilterFn=*/nullptr);
8725 std::vector<std::pair<Layer*, sp<LayerFE>>> layers = getLayerSnapshotsFn();
8726 args.root = mLayerHierarchyBuilder.getHierarchy();
8727 args.parentCrop.reset();
8728 args.excludeLayerIds.clear();
8729 mLayerSnapshotBuilder.update(args);
8730 return layers;
8731 };
8732 }
8733
doActiveLayersTracingIfNeeded(bool isCompositionComputed,bool visibleRegionDirty,TimePoint time,VsyncId vsyncId)8734 void SurfaceFlinger::doActiveLayersTracingIfNeeded(bool isCompositionComputed,
8735 bool visibleRegionDirty, TimePoint time,
8736 VsyncId vsyncId) {
8737 if (!mLayerTracing.isActiveTracingStarted()) {
8738 return;
8739 }
8740 if (isCompositionComputed !=
8741 mLayerTracing.isActiveTracingFlagSet(LayerTracing::Flag::TRACE_COMPOSITION)) {
8742 return;
8743 }
8744 if (!visibleRegionDirty &&
8745 !mLayerTracing.isActiveTracingFlagSet(LayerTracing::Flag::TRACE_BUFFERS)) {
8746 return;
8747 }
8748 auto snapshot = takeLayersSnapshotProto(mLayerTracing.getActiveTracingFlags(), time, vsyncId,
8749 visibleRegionDirty);
8750 mLayerTracing.addProtoSnapshotToOstream(std::move(snapshot), LayerTracing::Mode::MODE_ACTIVE);
8751 }
8752
takeLayersSnapshotProto(uint32_t traceFlags,TimePoint time,VsyncId vsyncId,bool visibleRegionDirty)8753 perfetto::protos::LayersSnapshotProto SurfaceFlinger::takeLayersSnapshotProto(
8754 uint32_t traceFlags, TimePoint time, VsyncId vsyncId, bool visibleRegionDirty) {
8755 SFTRACE_CALL();
8756 perfetto::protos::LayersSnapshotProto snapshot;
8757 snapshot.set_elapsed_realtime_nanos(time.ns());
8758 snapshot.set_vsync_id(ftl::to_underlying(vsyncId));
8759 snapshot.set_where(visibleRegionDirty ? "visibleRegionsDirty" : "bufferLatched");
8760 snapshot.set_excludes_composition_state((traceFlags & LayerTracing::Flag::TRACE_COMPOSITION) ==
8761 0);
8762
8763 auto layers = dumpDrawingStateProto(traceFlags);
8764 *snapshot.mutable_layers() = std::move(layers);
8765
8766 if (traceFlags & LayerTracing::Flag::TRACE_HWC) {
8767 std::string hwcDump;
8768 dumpHwc(hwcDump);
8769 snapshot.set_hwc_blob(std::move(hwcDump));
8770 }
8771
8772 *snapshot.mutable_displays() = dumpDisplayProto();
8773
8774 return snapshot;
8775 }
8776
8777 // sfdo functions
8778
sfdo_enableRefreshRateOverlay(bool active)8779 void SurfaceFlinger::sfdo_enableRefreshRateOverlay(bool active) {
8780 auto future = mScheduler->schedule(
8781 [&]() FTL_FAKE_GUARD(mStateLock)
8782 FTL_FAKE_GUARD(kMainThreadContext) { enableRefreshRateOverlay(active); });
8783 future.wait();
8784 }
8785
sfdo_setDebugFlash(int delay)8786 void SurfaceFlinger::sfdo_setDebugFlash(int delay) {
8787 if (delay > 0) {
8788 mDebugFlashDelay = delay;
8789 } else {
8790 mDebugFlashDelay = mDebugFlashDelay ? 0 : 1;
8791 }
8792 scheduleRepaint();
8793 }
8794
sfdo_scheduleComposite()8795 void SurfaceFlinger::sfdo_scheduleComposite() {
8796 scheduleComposite(SurfaceFlinger::FrameHint::kActive);
8797 }
8798
sfdo_scheduleCommit()8799 void SurfaceFlinger::sfdo_scheduleCommit() {
8800 Mutex::Autolock lock(mStateLock);
8801 setTransactionFlags(eTransactionNeeded | eDisplayTransactionNeeded | eTraversalNeeded);
8802 }
8803
sfdo_forceClientComposition(bool enabled)8804 void SurfaceFlinger::sfdo_forceClientComposition(bool enabled) {
8805 mDebugDisableHWC = enabled;
8806 scheduleRepaint();
8807 }
8808
8809 // gui::ISurfaceComposer
8810
bootFinished()8811 binder::Status SurfaceComposerAIDL::bootFinished() {
8812 status_t status = checkAccessPermission();
8813 if (status != OK) {
8814 return binderStatusFromStatusT(status);
8815 }
8816 mFlinger->bootFinished();
8817 return binder::Status::ok();
8818 }
8819
createDisplayEventConnection(VsyncSource vsyncSource,EventRegistration eventRegistration,const sp<IBinder> & layerHandle,sp<IDisplayEventConnection> * outConnection)8820 binder::Status SurfaceComposerAIDL::createDisplayEventConnection(
8821 VsyncSource vsyncSource, EventRegistration eventRegistration,
8822 const sp<IBinder>& layerHandle, sp<IDisplayEventConnection>* outConnection) {
8823 sp<IDisplayEventConnection> conn =
8824 mFlinger->createDisplayEventConnection(vsyncSource, eventRegistration, layerHandle);
8825 if (conn == nullptr) {
8826 *outConnection = nullptr;
8827 return binderStatusFromStatusT(BAD_VALUE);
8828 } else {
8829 *outConnection = conn;
8830 return binder::Status::ok();
8831 }
8832 }
8833
createConnection(sp<gui::ISurfaceComposerClient> * outClient)8834 binder::Status SurfaceComposerAIDL::createConnection(sp<gui::ISurfaceComposerClient>* outClient) {
8835 const sp<Client> client = sp<Client>::make(mFlinger);
8836 if (client->initCheck() == NO_ERROR) {
8837 *outClient = client;
8838 if (FlagManager::getInstance().misc1()) {
8839 const int policy = SCHED_FIFO;
8840 client->setMinSchedulerPolicy(policy, sched_get_priority_min(policy));
8841 }
8842 return binder::Status::ok();
8843 } else {
8844 *outClient = nullptr;
8845 return binderStatusFromStatusT(BAD_VALUE);
8846 }
8847 }
8848
createVirtualDisplay(const std::string & displayName,bool isSecure,gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy,const std::string & uniqueId,float requestedRefreshRate,sp<IBinder> * outDisplay)8849 binder::Status SurfaceComposerAIDL::createVirtualDisplay(
8850 const std::string& displayName, bool isSecure,
8851 gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy, const std::string& uniqueId,
8852 float requestedRefreshRate, sp<IBinder>* outDisplay) {
8853 status_t status = checkAccessPermission();
8854 if (status != OK) {
8855 return binderStatusFromStatusT(status);
8856 }
8857 *outDisplay = mFlinger->createVirtualDisplay(displayName, isSecure, optimizationPolicy,
8858 uniqueId, requestedRefreshRate);
8859 return binder::Status::ok();
8860 }
8861
destroyVirtualDisplay(const sp<IBinder> & displayToken)8862 binder::Status SurfaceComposerAIDL::destroyVirtualDisplay(const sp<IBinder>& displayToken) {
8863 status_t status = checkAccessPermission();
8864 if (status != OK) {
8865 return binderStatusFromStatusT(status);
8866 }
8867 return binder::Status::fromStatusT(mFlinger->destroyVirtualDisplay(displayToken));
8868 }
8869
getPhysicalDisplayIds(std::vector<int64_t> * outDisplayIds)8870 binder::Status SurfaceComposerAIDL::getPhysicalDisplayIds(std::vector<int64_t>* outDisplayIds) {
8871 std::vector<PhysicalDisplayId> physicalDisplayIds = mFlinger->getPhysicalDisplayIds();
8872 std::vector<int64_t> displayIds;
8873 displayIds.reserve(physicalDisplayIds.size());
8874 for (const auto id : physicalDisplayIds) {
8875 displayIds.push_back(static_cast<int64_t>(id.value));
8876 }
8877 *outDisplayIds = std::move(displayIds);
8878 return binder::Status::ok();
8879 }
8880
getPhysicalDisplayToken(int64_t displayId,sp<IBinder> * outDisplay)8881 binder::Status SurfaceComposerAIDL::getPhysicalDisplayToken(int64_t displayId,
8882 sp<IBinder>* outDisplay) {
8883 status_t status = checkAccessPermission();
8884 if (status != OK) {
8885 return binderStatusFromStatusT(status);
8886 }
8887 const PhysicalDisplayId id = PhysicalDisplayId::fromValue(static_cast<uint64_t>(displayId));
8888 *outDisplay = mFlinger->getPhysicalDisplayToken(id);
8889 return binder::Status::ok();
8890 }
8891
setPowerMode(const sp<IBinder> & display,int mode)8892 binder::Status SurfaceComposerAIDL::setPowerMode(const sp<IBinder>& display, int mode) {
8893 status_t status = checkAccessPermission();
8894 if (status != OK) {
8895 return binderStatusFromStatusT(status);
8896 }
8897 mFlinger->setPowerMode(display, mode);
8898 return binder::Status::ok();
8899 }
8900
getSupportedFrameTimestamps(std::vector<FrameEvent> * outSupported)8901 binder::Status SurfaceComposerAIDL::getSupportedFrameTimestamps(
8902 std::vector<FrameEvent>* outSupported) {
8903 status_t status;
8904 if (!outSupported) {
8905 status = UNEXPECTED_NULL;
8906 } else {
8907 outSupported->clear();
8908 status = mFlinger->getSupportedFrameTimestamps(outSupported);
8909 }
8910 return binderStatusFromStatusT(status);
8911 }
8912
getDisplayStats(const sp<IBinder> & display,gui::DisplayStatInfo * outStatInfo)8913 binder::Status SurfaceComposerAIDL::getDisplayStats(const sp<IBinder>& display,
8914 gui::DisplayStatInfo* outStatInfo) {
8915 DisplayStatInfo statInfo;
8916 status_t status = mFlinger->getDisplayStats(display, &statInfo);
8917 if (status == NO_ERROR) {
8918 outStatInfo->vsyncTime = static_cast<long>(statInfo.vsyncTime);
8919 outStatInfo->vsyncPeriod = static_cast<long>(statInfo.vsyncPeriod);
8920 }
8921 return binderStatusFromStatusT(status);
8922 }
8923
getDisplayState(const sp<IBinder> & display,gui::DisplayState * outState)8924 binder::Status SurfaceComposerAIDL::getDisplayState(const sp<IBinder>& display,
8925 gui::DisplayState* outState) {
8926 ui::DisplayState state;
8927 status_t status = mFlinger->getDisplayState(display, &state);
8928 if (status == NO_ERROR) {
8929 outState->layerStack = state.layerStack.id;
8930 outState->orientation = static_cast<gui::Rotation>(state.orientation);
8931 outState->layerStackSpaceRect.width = state.layerStackSpaceRect.width;
8932 outState->layerStackSpaceRect.height = state.layerStackSpaceRect.height;
8933 }
8934 return binderStatusFromStatusT(status);
8935 }
8936
getStaticDisplayInfo(int64_t displayId,gui::StaticDisplayInfo * outInfo)8937 binder::Status SurfaceComposerAIDL::getStaticDisplayInfo(int64_t displayId,
8938 gui::StaticDisplayInfo* outInfo) {
8939 using Tag = gui::DeviceProductInfo::ManufactureOrModelDate::Tag;
8940 ui::StaticDisplayInfo info;
8941
8942 status_t status = mFlinger->getStaticDisplayInfo(displayId, &info);
8943 if (status == NO_ERROR) {
8944 // convert ui::StaticDisplayInfo to gui::StaticDisplayInfo
8945 outInfo->connectionType = static_cast<gui::DisplayConnectionType>(info.connectionType);
8946 outInfo->port = info.port;
8947 outInfo->density = info.density;
8948 outInfo->secure = info.secure;
8949 outInfo->installOrientation = static_cast<gui::Rotation>(info.installOrientation);
8950
8951 if (const std::optional<DeviceProductInfo> dpi = info.deviceProductInfo) {
8952 gui::DeviceProductInfo dinfo;
8953 dinfo.name = std::move(dpi->name);
8954 dinfo.manufacturerPnpId = std::vector<uint8_t>(dpi->manufacturerPnpId.begin(),
8955 dpi->manufacturerPnpId.end());
8956 dinfo.productId = dpi->productId;
8957 dinfo.relativeAddress =
8958 std::vector<uint8_t>(dpi->relativeAddress.begin(), dpi->relativeAddress.end());
8959 if (const auto* model =
8960 std::get_if<DeviceProductInfo::ModelYear>(&dpi->manufactureOrModelDate)) {
8961 gui::DeviceProductInfo::ModelYear modelYear;
8962 modelYear.year = model->year;
8963 dinfo.manufactureOrModelDate.set<Tag::modelYear>(modelYear);
8964 } else if (const auto* manufacture = std::get_if<DeviceProductInfo::ManufactureYear>(
8965 &dpi->manufactureOrModelDate)) {
8966 gui::DeviceProductInfo::ManufactureYear date;
8967 date.modelYear.year = manufacture->year;
8968 dinfo.manufactureOrModelDate.set<Tag::manufactureYear>(date);
8969 } else if (const auto* manufacture =
8970 std::get_if<DeviceProductInfo::ManufactureWeekAndYear>(
8971 &dpi->manufactureOrModelDate)) {
8972 gui::DeviceProductInfo::ManufactureWeekAndYear date;
8973 date.manufactureYear.modelYear.year = manufacture->year;
8974 date.week = manufacture->week;
8975 dinfo.manufactureOrModelDate.set<Tag::manufactureWeekAndYear>(date);
8976 }
8977
8978 outInfo->deviceProductInfo = dinfo;
8979 }
8980 }
8981 return binderStatusFromStatusT(status);
8982 }
8983
getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo & info,gui::DynamicDisplayInfo * & outInfo)8984 void SurfaceComposerAIDL::getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo& info,
8985 gui::DynamicDisplayInfo*& outInfo) {
8986 // convert ui::DynamicDisplayInfo to gui::DynamicDisplayInfo
8987 outInfo->supportedDisplayModes.clear();
8988 outInfo->supportedDisplayModes.reserve(info.supportedDisplayModes.size());
8989 for (const auto& mode : info.supportedDisplayModes) {
8990 gui::DisplayMode outMode;
8991 outMode.id = mode.id;
8992 outMode.resolution.width = mode.resolution.width;
8993 outMode.resolution.height = mode.resolution.height;
8994 outMode.xDpi = mode.xDpi;
8995 outMode.yDpi = mode.yDpi;
8996 outMode.peakRefreshRate = mode.peakRefreshRate;
8997 outMode.vsyncRate = mode.vsyncRate;
8998 outMode.appVsyncOffset = mode.appVsyncOffset;
8999 outMode.sfVsyncOffset = mode.sfVsyncOffset;
9000 outMode.presentationDeadline = mode.presentationDeadline;
9001 outMode.group = mode.group;
9002 std::transform(mode.supportedHdrTypes.begin(), mode.supportedHdrTypes.end(),
9003 std::back_inserter(outMode.supportedHdrTypes),
9004 [](const ui::Hdr& value) { return static_cast<int32_t>(value); });
9005 outInfo->supportedDisplayModes.push_back(outMode);
9006 }
9007
9008 outInfo->activeDisplayModeId = info.activeDisplayModeId;
9009 outInfo->renderFrameRate = info.renderFrameRate;
9010 outInfo->hasArrSupport = info.hasArrSupport;
9011 gui::FrameRateCategoryRate& frameRateCategoryRate = outInfo->frameRateCategoryRate;
9012 frameRateCategoryRate.normal = info.frameRateCategoryRate.getNormal();
9013 frameRateCategoryRate.high = info.frameRateCategoryRate.getHigh();
9014 outInfo->supportedRefreshRates.clear();
9015 outInfo->supportedRefreshRates.reserve(info.supportedRefreshRates.size());
9016 for (float supportedRefreshRate : info.supportedRefreshRates) {
9017 outInfo->supportedRefreshRates.push_back(supportedRefreshRate);
9018 }
9019
9020 outInfo->supportedColorModes.clear();
9021 outInfo->supportedColorModes.reserve(info.supportedColorModes.size());
9022 for (const auto& cmode : info.supportedColorModes) {
9023 outInfo->supportedColorModes.push_back(static_cast<int32_t>(cmode));
9024 }
9025
9026 outInfo->activeColorMode = static_cast<int32_t>(info.activeColorMode);
9027
9028 gui::HdrCapabilities& hdrCapabilities = outInfo->hdrCapabilities;
9029 hdrCapabilities.supportedHdrTypes.clear();
9030 hdrCapabilities.supportedHdrTypes.reserve(info.hdrCapabilities.getSupportedHdrTypes().size());
9031 for (const auto& hdr : info.hdrCapabilities.getSupportedHdrTypes()) {
9032 hdrCapabilities.supportedHdrTypes.push_back(static_cast<int32_t>(hdr));
9033 }
9034 hdrCapabilities.maxLuminance = info.hdrCapabilities.getDesiredMaxLuminance();
9035 hdrCapabilities.maxAverageLuminance = info.hdrCapabilities.getDesiredMaxAverageLuminance();
9036 hdrCapabilities.minLuminance = info.hdrCapabilities.getDesiredMinLuminance();
9037
9038 outInfo->autoLowLatencyModeSupported = info.autoLowLatencyModeSupported;
9039 outInfo->gameContentTypeSupported = info.gameContentTypeSupported;
9040 outInfo->preferredBootDisplayMode = info.preferredBootDisplayMode;
9041 }
9042
getDynamicDisplayInfoFromToken(const sp<IBinder> & display,gui::DynamicDisplayInfo * outInfo)9043 binder::Status SurfaceComposerAIDL::getDynamicDisplayInfoFromToken(
9044 const sp<IBinder>& display, gui::DynamicDisplayInfo* outInfo) {
9045 ui::DynamicDisplayInfo info;
9046 status_t status = mFlinger->getDynamicDisplayInfoFromToken(display, &info);
9047 if (status == NO_ERROR) {
9048 getDynamicDisplayInfoInternal(info, outInfo);
9049 }
9050 return binderStatusFromStatusT(status);
9051 }
9052
getDynamicDisplayInfoFromId(int64_t displayId,gui::DynamicDisplayInfo * outInfo)9053 binder::Status SurfaceComposerAIDL::getDynamicDisplayInfoFromId(int64_t displayId,
9054 gui::DynamicDisplayInfo* outInfo) {
9055 ui::DynamicDisplayInfo info;
9056 status_t status = mFlinger->getDynamicDisplayInfoFromId(displayId, &info);
9057 if (status == NO_ERROR) {
9058 getDynamicDisplayInfoInternal(info, outInfo);
9059 }
9060 return binderStatusFromStatusT(status);
9061 }
9062
getDisplayNativePrimaries(const sp<IBinder> & display,gui::DisplayPrimaries * outPrimaries)9063 binder::Status SurfaceComposerAIDL::getDisplayNativePrimaries(const sp<IBinder>& display,
9064 gui::DisplayPrimaries* outPrimaries) {
9065 ui::DisplayPrimaries primaries;
9066 status_t status = mFlinger->getDisplayNativePrimaries(display, primaries);
9067 if (status == NO_ERROR) {
9068 outPrimaries->red.X = primaries.red.X;
9069 outPrimaries->red.Y = primaries.red.Y;
9070 outPrimaries->red.Z = primaries.red.Z;
9071
9072 outPrimaries->green.X = primaries.green.X;
9073 outPrimaries->green.Y = primaries.green.Y;
9074 outPrimaries->green.Z = primaries.green.Z;
9075
9076 outPrimaries->blue.X = primaries.blue.X;
9077 outPrimaries->blue.Y = primaries.blue.Y;
9078 outPrimaries->blue.Z = primaries.blue.Z;
9079
9080 outPrimaries->white.X = primaries.white.X;
9081 outPrimaries->white.Y = primaries.white.Y;
9082 outPrimaries->white.Z = primaries.white.Z;
9083 }
9084 return binderStatusFromStatusT(status);
9085 }
9086
setActiveColorMode(const sp<IBinder> & display,int colorMode)9087 binder::Status SurfaceComposerAIDL::setActiveColorMode(const sp<IBinder>& display, int colorMode) {
9088 status_t status = checkAccessPermission();
9089 if (status == OK) {
9090 status = mFlinger->setActiveColorMode(display, static_cast<ui::ColorMode>(colorMode));
9091 }
9092 return binderStatusFromStatusT(status);
9093 }
9094
setBootDisplayMode(const sp<IBinder> & display,int displayModeId)9095 binder::Status SurfaceComposerAIDL::setBootDisplayMode(const sp<IBinder>& display,
9096 int displayModeId) {
9097 status_t status = checkAccessPermission();
9098 if (status == OK) {
9099 status = mFlinger->setBootDisplayMode(display, DisplayModeId{displayModeId});
9100 }
9101 return binderStatusFromStatusT(status);
9102 }
9103
clearBootDisplayMode(const sp<IBinder> & display)9104 binder::Status SurfaceComposerAIDL::clearBootDisplayMode(const sp<IBinder>& display) {
9105 status_t status = checkAccessPermission();
9106 if (status == OK) {
9107 status = mFlinger->clearBootDisplayMode(display);
9108 }
9109 return binderStatusFromStatusT(status);
9110 }
9111
getOverlaySupport(gui::OverlayProperties * outProperties)9112 binder::Status SurfaceComposerAIDL::getOverlaySupport(gui::OverlayProperties* outProperties) {
9113 status_t status = checkAccessPermission();
9114 if (status == OK) {
9115 status = mFlinger->getOverlaySupport(outProperties);
9116 }
9117 return binderStatusFromStatusT(status);
9118 }
9119
getBootDisplayModeSupport(bool * outMode)9120 binder::Status SurfaceComposerAIDL::getBootDisplayModeSupport(bool* outMode) {
9121 status_t status = checkAccessPermission();
9122 if (status == OK) {
9123 status = mFlinger->getBootDisplayModeSupport(outMode);
9124 }
9125 return binderStatusFromStatusT(status);
9126 }
9127
getHdrConversionCapabilities(std::vector<gui::HdrConversionCapability> * hdrConversionCapabilities)9128 binder::Status SurfaceComposerAIDL::getHdrConversionCapabilities(
9129 std::vector<gui::HdrConversionCapability>* hdrConversionCapabilities) {
9130 status_t status = checkAccessPermission();
9131 if (status == OK) {
9132 status = mFlinger->getHdrConversionCapabilities(hdrConversionCapabilities);
9133 }
9134 return binderStatusFromStatusT(status);
9135 }
9136
setHdrConversionStrategy(const gui::HdrConversionStrategy & hdrConversionStrategy,int32_t * outPreferredHdrOutputType)9137 binder::Status SurfaceComposerAIDL::setHdrConversionStrategy(
9138 const gui::HdrConversionStrategy& hdrConversionStrategy,
9139 int32_t* outPreferredHdrOutputType) {
9140 status_t status = checkAccessPermission();
9141 if (status == OK) {
9142 status = mFlinger->setHdrConversionStrategy(hdrConversionStrategy,
9143 outPreferredHdrOutputType);
9144 }
9145 return binderStatusFromStatusT(status);
9146 }
9147
getHdrOutputConversionSupport(bool * outMode)9148 binder::Status SurfaceComposerAIDL::getHdrOutputConversionSupport(bool* outMode) {
9149 status_t status = checkAccessPermission();
9150 if (status == OK) {
9151 status = mFlinger->getHdrOutputConversionSupport(outMode);
9152 }
9153 return binderStatusFromStatusT(status);
9154 }
9155
setAutoLowLatencyMode(const sp<IBinder> & display,bool on)9156 binder::Status SurfaceComposerAIDL::setAutoLowLatencyMode(const sp<IBinder>& display, bool on) {
9157 status_t status = checkAccessPermission();
9158 if (status != OK) {
9159 return binderStatusFromStatusT(status);
9160 }
9161 mFlinger->setAutoLowLatencyMode(display, on);
9162 return binder::Status::ok();
9163 }
9164
setGameContentType(const sp<IBinder> & display,bool on)9165 binder::Status SurfaceComposerAIDL::setGameContentType(const sp<IBinder>& display, bool on) {
9166 status_t status = checkAccessPermission();
9167 if (status != OK) {
9168 return binderStatusFromStatusT(status);
9169 }
9170 mFlinger->setGameContentType(display, on);
9171 return binder::Status::ok();
9172 }
9173
getMaxLayerPictureProfiles(const sp<IBinder> & display,int32_t * outMaxProfiles)9174 binder::Status SurfaceComposerAIDL::getMaxLayerPictureProfiles(const sp<IBinder>& display,
9175 int32_t* outMaxProfiles) {
9176 status_t status = checkAccessPermission();
9177 if (status != OK) {
9178 return binderStatusFromStatusT(status);
9179 }
9180 mFlinger->getMaxLayerPictureProfiles(display, outMaxProfiles);
9181 return binder::Status::ok();
9182 }
9183
captureDisplay(const DisplayCaptureArgs & args,const sp<IScreenCaptureListener> & captureListener)9184 binder::Status SurfaceComposerAIDL::captureDisplay(
9185 const DisplayCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) {
9186 mFlinger->captureDisplay(args, captureListener);
9187 return binderStatusFromStatusT(NO_ERROR);
9188 }
9189
captureDisplayById(int64_t displayId,const CaptureArgs & args,const sp<IScreenCaptureListener> & captureListener)9190 binder::Status SurfaceComposerAIDL::captureDisplayById(
9191 int64_t displayId, const CaptureArgs& args,
9192 const sp<IScreenCaptureListener>& captureListener) {
9193 // status_t status;
9194 IPCThreadState* ipc = IPCThreadState::self();
9195 const int uid = ipc->getCallingUid();
9196 if (uid == AID_ROOT || uid == AID_GRAPHICS || uid == AID_SYSTEM || uid == AID_SHELL) {
9197 std::optional<DisplayId> id = DisplayId::fromValue(static_cast<uint64_t>(displayId));
9198 mFlinger->captureDisplay(*id, args, captureListener);
9199 } else {
9200 ALOGD("Permission denied to captureDisplayById");
9201 invokeScreenCaptureError(PERMISSION_DENIED, captureListener);
9202 }
9203 return binderStatusFromStatusT(NO_ERROR);
9204 }
9205
captureLayersSync(const LayerCaptureArgs & args,ScreenCaptureResults * outResults)9206 binder::Status SurfaceComposerAIDL::captureLayersSync(const LayerCaptureArgs& args,
9207 ScreenCaptureResults* outResults) {
9208 *outResults = mFlinger->captureLayersSync(args);
9209 return binderStatusFromStatusT(NO_ERROR);
9210 }
9211
captureLayers(const LayerCaptureArgs & args,const sp<IScreenCaptureListener> & captureListener)9212 binder::Status SurfaceComposerAIDL::captureLayers(
9213 const LayerCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) {
9214 mFlinger->captureLayers(args, captureListener);
9215 return binderStatusFromStatusT(NO_ERROR);
9216 }
9217
overrideHdrTypes(const sp<IBinder> & display,const std::vector<int32_t> & hdrTypes)9218 binder::Status SurfaceComposerAIDL::overrideHdrTypes(const sp<IBinder>& display,
9219 const std::vector<int32_t>& hdrTypes) {
9220 // overrideHdrTypes is used by CTS tests, which acquire the necessary
9221 // permission dynamically. Don't use the permission cache for this check.
9222 status_t status = checkAccessPermission(false);
9223 if (status != OK) {
9224 return binderStatusFromStatusT(status);
9225 }
9226
9227 std::vector<ui::Hdr> hdrTypesVector;
9228 for (int32_t i : hdrTypes) {
9229 hdrTypesVector.push_back(static_cast<ui::Hdr>(i));
9230 }
9231 status = mFlinger->overrideHdrTypes(display, hdrTypesVector);
9232 return binderStatusFromStatusT(status);
9233 }
9234
onPullAtom(int32_t atomId,gui::PullAtomData * outPullData)9235 binder::Status SurfaceComposerAIDL::onPullAtom(int32_t atomId, gui::PullAtomData* outPullData) {
9236 status_t status;
9237 const int uid = IPCThreadState::self()->getCallingUid();
9238 if (uid != AID_SYSTEM) {
9239 status = PERMISSION_DENIED;
9240 } else {
9241 status = mFlinger->onPullAtom(atomId, &outPullData->data, &outPullData->success);
9242 }
9243 return binderStatusFromStatusT(status);
9244 }
9245
getCompositionPreference(gui::CompositionPreference * outPref)9246 binder::Status SurfaceComposerAIDL::getCompositionPreference(gui::CompositionPreference* outPref) {
9247 ui::Dataspace dataspace;
9248 ui::PixelFormat pixelFormat;
9249 ui::Dataspace wideColorGamutDataspace;
9250 ui::PixelFormat wideColorGamutPixelFormat;
9251 status_t status =
9252 mFlinger->getCompositionPreference(&dataspace, &pixelFormat, &wideColorGamutDataspace,
9253 &wideColorGamutPixelFormat);
9254 if (status == NO_ERROR) {
9255 outPref->defaultDataspace = static_cast<int32_t>(dataspace);
9256 outPref->defaultPixelFormat = static_cast<int32_t>(pixelFormat);
9257 outPref->wideColorGamutDataspace = static_cast<int32_t>(wideColorGamutDataspace);
9258 outPref->wideColorGamutPixelFormat = static_cast<int32_t>(wideColorGamutPixelFormat);
9259 }
9260 return binderStatusFromStatusT(status);
9261 }
9262
getDisplayedContentSamplingAttributes(const sp<IBinder> & display,gui::ContentSamplingAttributes * outAttrs)9263 binder::Status SurfaceComposerAIDL::getDisplayedContentSamplingAttributes(
9264 const sp<IBinder>& display, gui::ContentSamplingAttributes* outAttrs) {
9265 status_t status = checkAccessPermission();
9266 if (status != OK) {
9267 return binderStatusFromStatusT(status);
9268 }
9269
9270 ui::PixelFormat format;
9271 ui::Dataspace dataspace;
9272 uint8_t componentMask;
9273 status = mFlinger->getDisplayedContentSamplingAttributes(display, &format, &dataspace,
9274 &componentMask);
9275 if (status == NO_ERROR) {
9276 outAttrs->format = static_cast<int32_t>(format);
9277 outAttrs->dataspace = static_cast<int32_t>(dataspace);
9278 outAttrs->componentMask = static_cast<int8_t>(componentMask);
9279 }
9280 return binderStatusFromStatusT(status);
9281 }
9282
setDisplayContentSamplingEnabled(const sp<IBinder> & display,bool enable,int8_t componentMask,int64_t maxFrames)9283 binder::Status SurfaceComposerAIDL::setDisplayContentSamplingEnabled(const sp<IBinder>& display,
9284 bool enable,
9285 int8_t componentMask,
9286 int64_t maxFrames) {
9287 status_t status = checkAccessPermission();
9288 if (status == OK) {
9289 status = mFlinger->setDisplayContentSamplingEnabled(display, enable,
9290 static_cast<uint8_t>(componentMask),
9291 static_cast<uint64_t>(maxFrames));
9292 }
9293 return binderStatusFromStatusT(status);
9294 }
9295
getDisplayedContentSample(const sp<IBinder> & display,int64_t maxFrames,int64_t timestamp,gui::DisplayedFrameStats * outStats)9296 binder::Status SurfaceComposerAIDL::getDisplayedContentSample(const sp<IBinder>& display,
9297 int64_t maxFrames, int64_t timestamp,
9298 gui::DisplayedFrameStats* outStats) {
9299 if (!outStats) {
9300 return binderStatusFromStatusT(BAD_VALUE);
9301 }
9302
9303 status_t status = checkAccessPermission();
9304 if (status != OK) {
9305 return binderStatusFromStatusT(status);
9306 }
9307
9308 DisplayedFrameStats stats;
9309 status = mFlinger->getDisplayedContentSample(display, static_cast<uint64_t>(maxFrames),
9310 static_cast<uint64_t>(timestamp), &stats);
9311 if (status == NO_ERROR) {
9312 // convert from ui::DisplayedFrameStats to gui::DisplayedFrameStats
9313 outStats->numFrames = static_cast<int64_t>(stats.numFrames);
9314 outStats->component_0_sample.reserve(stats.component_0_sample.size());
9315 for (const auto& s : stats.component_0_sample) {
9316 outStats->component_0_sample.push_back(static_cast<int64_t>(s));
9317 }
9318 outStats->component_1_sample.reserve(stats.component_1_sample.size());
9319 for (const auto& s : stats.component_1_sample) {
9320 outStats->component_1_sample.push_back(static_cast<int64_t>(s));
9321 }
9322 outStats->component_2_sample.reserve(stats.component_2_sample.size());
9323 for (const auto& s : stats.component_2_sample) {
9324 outStats->component_2_sample.push_back(static_cast<int64_t>(s));
9325 }
9326 outStats->component_3_sample.reserve(stats.component_3_sample.size());
9327 for (const auto& s : stats.component_3_sample) {
9328 outStats->component_3_sample.push_back(static_cast<int64_t>(s));
9329 }
9330 }
9331 return binderStatusFromStatusT(status);
9332 }
9333
getProtectedContentSupport(bool * outSupported)9334 binder::Status SurfaceComposerAIDL::getProtectedContentSupport(bool* outSupported) {
9335 status_t status = mFlinger->getProtectedContentSupport(outSupported);
9336 return binderStatusFromStatusT(status);
9337 }
9338
isWideColorDisplay(const sp<IBinder> & token,bool * outIsWideColorDisplay)9339 binder::Status SurfaceComposerAIDL::isWideColorDisplay(const sp<IBinder>& token,
9340 bool* outIsWideColorDisplay) {
9341 status_t status = mFlinger->isWideColorDisplay(token, outIsWideColorDisplay);
9342 return binderStatusFromStatusT(status);
9343 }
9344
addRegionSamplingListener(const gui::ARect & samplingArea,const sp<IBinder> & stopLayerHandle,const sp<gui::IRegionSamplingListener> & listener)9345 binder::Status SurfaceComposerAIDL::addRegionSamplingListener(
9346 const gui::ARect& samplingArea, const sp<IBinder>& stopLayerHandle,
9347 const sp<gui::IRegionSamplingListener>& listener) {
9348 status_t status = checkReadFrameBufferPermission();
9349 if (status != OK) {
9350 return binderStatusFromStatusT(status);
9351 }
9352 android::Rect rect;
9353 rect.left = samplingArea.left;
9354 rect.top = samplingArea.top;
9355 rect.right = samplingArea.right;
9356 rect.bottom = samplingArea.bottom;
9357 status = mFlinger->addRegionSamplingListener(rect, stopLayerHandle, listener);
9358 return binderStatusFromStatusT(status);
9359 }
9360
removeRegionSamplingListener(const sp<gui::IRegionSamplingListener> & listener)9361 binder::Status SurfaceComposerAIDL::removeRegionSamplingListener(
9362 const sp<gui::IRegionSamplingListener>& listener) {
9363 status_t status = checkReadFrameBufferPermission();
9364 if (status == OK) {
9365 status = mFlinger->removeRegionSamplingListener(listener);
9366 }
9367 return binderStatusFromStatusT(status);
9368 }
9369
addFpsListener(int32_t taskId,const sp<gui::IFpsListener> & listener)9370 binder::Status SurfaceComposerAIDL::addFpsListener(int32_t taskId,
9371 const sp<gui::IFpsListener>& listener) {
9372 status_t status = checkReadFrameBufferPermission();
9373 if (status == OK) {
9374 status = mFlinger->addFpsListener(taskId, listener);
9375 }
9376 return binderStatusFromStatusT(status);
9377 }
9378
removeFpsListener(const sp<gui::IFpsListener> & listener)9379 binder::Status SurfaceComposerAIDL::removeFpsListener(const sp<gui::IFpsListener>& listener) {
9380 status_t status = checkReadFrameBufferPermission();
9381 if (status == OK) {
9382 status = mFlinger->removeFpsListener(listener);
9383 }
9384 return binderStatusFromStatusT(status);
9385 }
9386
addTunnelModeEnabledListener(const sp<gui::ITunnelModeEnabledListener> & listener)9387 binder::Status SurfaceComposerAIDL::addTunnelModeEnabledListener(
9388 const sp<gui::ITunnelModeEnabledListener>& listener) {
9389 status_t status = checkAccessPermission();
9390 if (status == OK) {
9391 status = mFlinger->addTunnelModeEnabledListener(listener);
9392 }
9393 return binderStatusFromStatusT(status);
9394 }
9395
removeTunnelModeEnabledListener(const sp<gui::ITunnelModeEnabledListener> & listener)9396 binder::Status SurfaceComposerAIDL::removeTunnelModeEnabledListener(
9397 const sp<gui::ITunnelModeEnabledListener>& listener) {
9398 status_t status = checkAccessPermission();
9399 if (status == OK) {
9400 status = mFlinger->removeTunnelModeEnabledListener(listener);
9401 }
9402 return binderStatusFromStatusT(status);
9403 }
9404
setDesiredDisplayModeSpecs(const sp<IBinder> & displayToken,const gui::DisplayModeSpecs & specs)9405 binder::Status SurfaceComposerAIDL::setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
9406 const gui::DisplayModeSpecs& specs) {
9407 status_t status = checkAccessPermission();
9408 if (status == OK) {
9409 status = mFlinger->setDesiredDisplayModeSpecs(displayToken, specs);
9410 }
9411 return binderStatusFromStatusT(status);
9412 }
9413
getDesiredDisplayModeSpecs(const sp<IBinder> & displayToken,gui::DisplayModeSpecs * outSpecs)9414 binder::Status SurfaceComposerAIDL::getDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
9415 gui::DisplayModeSpecs* outSpecs) {
9416 if (!outSpecs) {
9417 return binderStatusFromStatusT(BAD_VALUE);
9418 }
9419
9420 status_t status = checkAccessPermission();
9421 if (status != OK) {
9422 return binderStatusFromStatusT(status);
9423 }
9424
9425 status = mFlinger->getDesiredDisplayModeSpecs(displayToken, outSpecs);
9426 return binderStatusFromStatusT(status);
9427 }
9428
getDisplayBrightnessSupport(const sp<IBinder> & displayToken,bool * outSupport)9429 binder::Status SurfaceComposerAIDL::getDisplayBrightnessSupport(const sp<IBinder>& displayToken,
9430 bool* outSupport) {
9431 status_t status = mFlinger->getDisplayBrightnessSupport(displayToken, outSupport);
9432 return binderStatusFromStatusT(status);
9433 }
9434
setDisplayBrightness(const sp<IBinder> & displayToken,const gui::DisplayBrightness & brightness)9435 binder::Status SurfaceComposerAIDL::setDisplayBrightness(const sp<IBinder>& displayToken,
9436 const gui::DisplayBrightness& brightness) {
9437 status_t status = checkControlDisplayBrightnessPermission();
9438 if (status == OK) {
9439 status = mFlinger->setDisplayBrightness(displayToken, brightness);
9440 }
9441 return binderStatusFromStatusT(status);
9442 }
9443
addHdrLayerInfoListener(const sp<IBinder> & displayToken,const sp<gui::IHdrLayerInfoListener> & listener)9444 binder::Status SurfaceComposerAIDL::addHdrLayerInfoListener(
9445 const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener) {
9446 status_t status = checkControlDisplayBrightnessPermission();
9447 if (status == OK) {
9448 status = mFlinger->addHdrLayerInfoListener(displayToken, listener);
9449 }
9450 return binderStatusFromStatusT(status);
9451 }
9452
removeHdrLayerInfoListener(const sp<IBinder> & displayToken,const sp<gui::IHdrLayerInfoListener> & listener)9453 binder::Status SurfaceComposerAIDL::removeHdrLayerInfoListener(
9454 const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener) {
9455 status_t status = checkControlDisplayBrightnessPermission();
9456 if (status == OK) {
9457 status = mFlinger->removeHdrLayerInfoListener(displayToken, listener);
9458 }
9459 return binderStatusFromStatusT(status);
9460 }
9461
addActivePictureListener(const sp<gui::IActivePictureListener> & listener)9462 binder::Status SurfaceComposerAIDL::addActivePictureListener(
9463 const sp<gui::IActivePictureListener>& listener) {
9464 status_t status = checkObservePictureProfilesPermission();
9465 if (status == OK) {
9466 mFlinger->addActivePictureListener(listener);
9467 }
9468 return binderStatusFromStatusT(status);
9469 }
9470
removeActivePictureListener(const sp<gui::IActivePictureListener> & listener)9471 binder::Status SurfaceComposerAIDL::removeActivePictureListener(
9472 const sp<gui::IActivePictureListener>& listener) {
9473 status_t status = checkObservePictureProfilesPermission();
9474 if (status == OK) {
9475 mFlinger->removeActivePictureListener(listener);
9476 }
9477 return binderStatusFromStatusT(status);
9478 }
9479
notifyPowerBoost(int boostId)9480 binder::Status SurfaceComposerAIDL::notifyPowerBoost(int boostId) {
9481 status_t status = checkAccessPermission();
9482 if (status == OK) {
9483 status = mFlinger->notifyPowerBoost(boostId);
9484 }
9485 return binderStatusFromStatusT(status);
9486 }
9487
setGlobalShadowSettings(const gui::Color & ambientColor,const gui::Color & spotColor,float lightPosY,float lightPosZ,float lightRadius)9488 binder::Status SurfaceComposerAIDL::setGlobalShadowSettings(const gui::Color& ambientColor,
9489 const gui::Color& spotColor,
9490 float lightPosY, float lightPosZ,
9491 float lightRadius) {
9492 status_t status = checkAccessPermission();
9493 if (status != OK) {
9494 return binderStatusFromStatusT(status);
9495 }
9496
9497 half4 ambientColorHalf = {ambientColor.r, ambientColor.g, ambientColor.b, ambientColor.a};
9498 half4 spotColorHalf = {spotColor.r, spotColor.g, spotColor.b, spotColor.a};
9499 status = mFlinger->setGlobalShadowSettings(ambientColorHalf, spotColorHalf, lightPosY,
9500 lightPosZ, lightRadius);
9501 return binderStatusFromStatusT(status);
9502 }
9503
getDisplayDecorationSupport(const sp<IBinder> & displayToken,std::optional<gui::DisplayDecorationSupport> * outSupport)9504 binder::Status SurfaceComposerAIDL::getDisplayDecorationSupport(
9505 const sp<IBinder>& displayToken, std::optional<gui::DisplayDecorationSupport>* outSupport) {
9506 std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport> support;
9507 status_t status = mFlinger->getDisplayDecorationSupport(displayToken, &support);
9508 if (status != NO_ERROR) {
9509 ALOGE("getDisplayDecorationSupport failed with error %d", status);
9510 return binderStatusFromStatusT(status);
9511 }
9512
9513 if (!support || !support.has_value()) {
9514 outSupport->reset();
9515 } else {
9516 outSupport->emplace();
9517 outSupport->value().format = static_cast<int32_t>(support->format);
9518 outSupport->value().alphaInterpretation =
9519 static_cast<int32_t>(support->alphaInterpretation);
9520 }
9521
9522 return binder::Status::ok();
9523 }
9524
setGameModeFrameRateOverride(int32_t uid,float frameRate)9525 binder::Status SurfaceComposerAIDL::setGameModeFrameRateOverride(int32_t uid, float frameRate) {
9526 status_t status;
9527 const int c_uid = IPCThreadState::self()->getCallingUid();
9528 if (c_uid == AID_ROOT || c_uid == AID_SYSTEM) {
9529 status = mFlinger->setGameModeFrameRateOverride(uid, frameRate);
9530 } else {
9531 ALOGE("setGameModeFrameRateOverride() permission denied for uid: %d", c_uid);
9532 status = PERMISSION_DENIED;
9533 }
9534 return binderStatusFromStatusT(status);
9535 }
9536
setGameDefaultFrameRateOverride(int32_t uid,float frameRate)9537 binder::Status SurfaceComposerAIDL::setGameDefaultFrameRateOverride(int32_t uid, float frameRate) {
9538 status_t status;
9539 const int c_uid = IPCThreadState::self()->getCallingUid();
9540 if (c_uid == AID_ROOT || c_uid == AID_SYSTEM) {
9541 status = mFlinger->setGameDefaultFrameRateOverride(uid, frameRate);
9542 } else {
9543 ALOGE("setGameDefaultFrameRateOverride() permission denied for uid: %d", c_uid);
9544 status = PERMISSION_DENIED;
9545 }
9546 return binderStatusFromStatusT(status);
9547 }
9548
enableRefreshRateOverlay(bool active)9549 binder::Status SurfaceComposerAIDL::enableRefreshRateOverlay(bool active) {
9550 status_t status = checkAccessPermission();
9551 if (status != OK) {
9552 return binderStatusFromStatusT(status);
9553 }
9554 mFlinger->sfdo_enableRefreshRateOverlay(active);
9555 return binder::Status::ok();
9556 }
9557
setDebugFlash(int delay)9558 binder::Status SurfaceComposerAIDL::setDebugFlash(int delay) {
9559 status_t status = checkAccessPermission();
9560 if (status != OK) {
9561 return binderStatusFromStatusT(status);
9562 }
9563 mFlinger->sfdo_setDebugFlash(delay);
9564 return binder::Status::ok();
9565 }
9566
scheduleComposite()9567 binder::Status SurfaceComposerAIDL::scheduleComposite() {
9568 status_t status = checkAccessPermission();
9569 if (status != OK) {
9570 return binderStatusFromStatusT(status);
9571 }
9572 mFlinger->sfdo_scheduleComposite();
9573 return binder::Status::ok();
9574 }
9575
scheduleCommit()9576 binder::Status SurfaceComposerAIDL::scheduleCommit() {
9577 status_t status = checkAccessPermission();
9578 if (status != OK) {
9579 return binderStatusFromStatusT(status);
9580 }
9581 mFlinger->sfdo_scheduleCommit();
9582 return binder::Status::ok();
9583 }
9584
forceClientComposition(bool enabled)9585 binder::Status SurfaceComposerAIDL::forceClientComposition(bool enabled) {
9586 status_t status = checkAccessPermission();
9587 if (status != OK) {
9588 return binderStatusFromStatusT(status);
9589 }
9590 mFlinger->sfdo_forceClientComposition(enabled);
9591 return binder::Status::ok();
9592 }
9593
updateSmallAreaDetection(const std::vector<int32_t> & appIds,const std::vector<float> & thresholds)9594 binder::Status SurfaceComposerAIDL::updateSmallAreaDetection(const std::vector<int32_t>& appIds,
9595 const std::vector<float>& thresholds) {
9596 status_t status;
9597 const int c_uid = IPCThreadState::self()->getCallingUid();
9598 if (c_uid == AID_ROOT || c_uid == AID_SYSTEM) {
9599 if (appIds.size() != thresholds.size()) return binderStatusFromStatusT(BAD_VALUE);
9600
9601 std::vector<std::pair<int32_t, float>> mappings;
9602 const size_t size = appIds.size();
9603 mappings.reserve(size);
9604 for (int i = 0; i < size; i++) {
9605 auto row = std::make_pair(appIds[i], thresholds[i]);
9606 mappings.push_back(row);
9607 }
9608 status = mFlinger->updateSmallAreaDetection(mappings);
9609 } else {
9610 ALOGE("updateSmallAreaDetection() permission denied for uid: %d", c_uid);
9611 status = PERMISSION_DENIED;
9612 }
9613 return binderStatusFromStatusT(status);
9614 }
9615
setSmallAreaDetectionThreshold(int32_t appId,float threshold)9616 binder::Status SurfaceComposerAIDL::setSmallAreaDetectionThreshold(int32_t appId, float threshold) {
9617 status_t status;
9618 const int c_uid = IPCThreadState::self()->getCallingUid();
9619 if (c_uid == AID_ROOT || c_uid == AID_SYSTEM) {
9620 status = mFlinger->setSmallAreaDetectionThreshold(appId, threshold);
9621 } else {
9622 ALOGE("setSmallAreaDetectionThreshold() permission denied for uid: %d", c_uid);
9623 status = PERMISSION_DENIED;
9624 }
9625 return binderStatusFromStatusT(status);
9626 }
9627
getGpuContextPriority(int32_t * outPriority)9628 binder::Status SurfaceComposerAIDL::getGpuContextPriority(int32_t* outPriority) {
9629 *outPriority = mFlinger->getGpuContextPriority();
9630 return binder::Status::ok();
9631 }
9632
getMaxAcquiredBufferCount(int32_t * buffers)9633 binder::Status SurfaceComposerAIDL::getMaxAcquiredBufferCount(int32_t* buffers) {
9634 status_t status = mFlinger->getMaxAcquiredBufferCount(buffers);
9635 return binderStatusFromStatusT(status);
9636 }
9637
addWindowInfosListener(const sp<gui::IWindowInfosListener> & windowInfosListener,gui::WindowInfosListenerInfo * outInfo)9638 binder::Status SurfaceComposerAIDL::addWindowInfosListener(
9639 const sp<gui::IWindowInfosListener>& windowInfosListener,
9640 gui::WindowInfosListenerInfo* outInfo) {
9641 status_t status;
9642 const int pid = IPCThreadState::self()->getCallingPid();
9643 const int uid = IPCThreadState::self()->getCallingUid();
9644 // TODO(b/270566761) update permissions check so that only system_server and shell can add
9645 // WindowInfosListeners
9646 if (uid == AID_SYSTEM || uid == AID_GRAPHICS ||
9647 checkPermission(sAccessSurfaceFlinger, pid, uid)) {
9648 status = mFlinger->addWindowInfosListener(windowInfosListener, outInfo);
9649 } else {
9650 status = PERMISSION_DENIED;
9651 }
9652 return binderStatusFromStatusT(status);
9653 }
9654
removeWindowInfosListener(const sp<gui::IWindowInfosListener> & windowInfosListener)9655 binder::Status SurfaceComposerAIDL::removeWindowInfosListener(
9656 const sp<gui::IWindowInfosListener>& windowInfosListener) {
9657 status_t status;
9658 const int pid = IPCThreadState::self()->getCallingPid();
9659 const int uid = IPCThreadState::self()->getCallingUid();
9660 if (uid == AID_SYSTEM || uid == AID_GRAPHICS ||
9661 checkPermission(sAccessSurfaceFlinger, pid, uid)) {
9662 status = mFlinger->removeWindowInfosListener(windowInfosListener);
9663 } else {
9664 status = PERMISSION_DENIED;
9665 }
9666 return binderStatusFromStatusT(status);
9667 }
9668
getStalledTransactionInfo(int pid,std::optional<gui::StalledTransactionInfo> * outInfo)9669 binder::Status SurfaceComposerAIDL::getStalledTransactionInfo(
9670 int pid, std::optional<gui::StalledTransactionInfo>* outInfo) {
9671 const int callingPid = IPCThreadState::self()->getCallingPid();
9672 const int callingUid = IPCThreadState::self()->getCallingUid();
9673 if (!checkPermission(sAccessSurfaceFlinger, callingPid, callingUid)) {
9674 return binderStatusFromStatusT(PERMISSION_DENIED);
9675 }
9676
9677 std::optional<TransactionHandler::StalledTransactionInfo> stalledTransactionInfo;
9678 status_t status = mFlinger->getStalledTransactionInfo(pid, stalledTransactionInfo);
9679 if (stalledTransactionInfo) {
9680 gui::StalledTransactionInfo result;
9681 result.layerName = String16{stalledTransactionInfo->layerName.c_str()},
9682 result.bufferId = stalledTransactionInfo->bufferId,
9683 result.frameNumber = stalledTransactionInfo->frameNumber,
9684 outInfo->emplace(std::move(result));
9685 } else {
9686 outInfo->reset();
9687 }
9688 return binderStatusFromStatusT(status);
9689 }
9690
getSchedulingPolicy(gui::SchedulingPolicy * outPolicy)9691 binder::Status SurfaceComposerAIDL::getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) {
9692 return gui::getSchedulingPolicy(outPolicy);
9693 }
9694
notifyShutdown()9695 binder::Status SurfaceComposerAIDL::notifyShutdown() {
9696 TransactionTraceWriter::getInstance().invoke("systemShutdown_", /* overwrite= */ false);
9697 return ::android::binder::Status::ok();
9698 }
9699
addJankListener(const sp<IBinder> & layerHandle,const sp<gui::IJankListener> & listener)9700 binder::Status SurfaceComposerAIDL::addJankListener(const sp<IBinder>& layerHandle,
9701 const sp<gui::IJankListener>& listener) {
9702 sp<Layer> layer = LayerHandle::getLayer(layerHandle);
9703 if (layer == nullptr) {
9704 return binder::Status::fromExceptionCode(binder::Status::EX_NULL_POINTER);
9705 }
9706 JankTracker::addJankListener(layer->sequence, IInterface::asBinder(listener));
9707 return binder::Status::ok();
9708 }
9709
flushJankData(int32_t layerId)9710 binder::Status SurfaceComposerAIDL::flushJankData(int32_t layerId) {
9711 JankTracker::flushJankData(layerId);
9712 return binder::Status::ok();
9713 }
9714
removeJankListener(int32_t layerId,const sp<gui::IJankListener> & listener,int64_t afterVsync)9715 binder::Status SurfaceComposerAIDL::removeJankListener(int32_t layerId,
9716 const sp<gui::IJankListener>& listener,
9717 int64_t afterVsync) {
9718 JankTracker::removeJankListener(layerId, IInterface::asBinder(listener), afterVsync);
9719 return binder::Status::ok();
9720 }
9721
checkAccessPermission(bool usePermissionCache)9722 status_t SurfaceComposerAIDL::checkAccessPermission(bool usePermissionCache) {
9723 if (!mFlinger->callingThreadHasUnscopedSurfaceFlingerAccess(usePermissionCache)) {
9724 IPCThreadState* ipc = IPCThreadState::self();
9725 ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", ipc->getCallingPid(),
9726 ipc->getCallingUid());
9727 return PERMISSION_DENIED;
9728 }
9729 return OK;
9730 }
9731
checkControlDisplayBrightnessPermission()9732 status_t SurfaceComposerAIDL::checkControlDisplayBrightnessPermission() {
9733 IPCThreadState* ipc = IPCThreadState::self();
9734 const int pid = ipc->getCallingPid();
9735 const int uid = ipc->getCallingUid();
9736 if ((uid != AID_GRAPHICS) && (uid != AID_SYSTEM) &&
9737 !PermissionCache::checkPermission(sControlDisplayBrightness, pid, uid)) {
9738 ALOGE("Permission Denial: can't control brightness pid=%d, uid=%d", pid, uid);
9739 return PERMISSION_DENIED;
9740 }
9741 return OK;
9742 }
9743
checkReadFrameBufferPermission()9744 status_t SurfaceComposerAIDL::checkReadFrameBufferPermission() {
9745 IPCThreadState* ipc = IPCThreadState::self();
9746 const int pid = ipc->getCallingPid();
9747 const int uid = ipc->getCallingUid();
9748 if ((uid != AID_GRAPHICS) && !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
9749 ALOGE("Permission Denial: can't read framebuffer pid=%d, uid=%d", pid, uid);
9750 return PERMISSION_DENIED;
9751 }
9752 return OK;
9753 }
9754
checkObservePictureProfilesPermission()9755 status_t SurfaceComposerAIDL::checkObservePictureProfilesPermission() {
9756 IPCThreadState* ipc = IPCThreadState::self();
9757 const int pid = ipc->getCallingPid();
9758 const int uid = ipc->getCallingUid();
9759 if (!PermissionCache::checkPermission(sObservePictureProfiles, pid, uid)) {
9760 ALOGE("Permission Denial: can't manage picture profiles pid=%d, uid=%d", pid, uid);
9761 return PERMISSION_DENIED;
9762 }
9763 return OK;
9764 }
9765
forceFutureUpdate(int delayInMs)9766 void SurfaceFlinger::forceFutureUpdate(int delayInMs) {
9767 static_cast<void>(mScheduler->scheduleDelayed([&]() { scheduleRepaint(); }, ms2ns(delayInMs)));
9768 }
9769
getDisplayFromLayerStack(ui::LayerStack layerStack)9770 const DisplayDevice* SurfaceFlinger::getDisplayFromLayerStack(ui::LayerStack layerStack) {
9771 for (const auto& [_, display] : mDisplays) {
9772 if (display->getLayerStack() == layerStack) {
9773 return display.get();
9774 }
9775 }
9776 return nullptr;
9777 }
9778
9779 } // namespace android
9780
9781 #if defined(__gl_h_)
9782 #error "don't include gl/gl.h in this file"
9783 #endif
9784
9785 #if defined(__gl2_h_)
9786 #error "don't include gl2/gl2.h in this file"
9787 #endif
9788
9789 // TODO(b/129481165): remove the #pragma below and fix conversion issues
9790 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
9791