diff options
Diffstat (limited to 'services/surfaceflinger/Scheduler/VsyncConfiguration.cpp')
-rw-r--r-- | services/surfaceflinger/Scheduler/VsyncConfiguration.cpp | 380 |
1 files changed, 0 insertions, 380 deletions
diff --git a/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp b/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp deleted file mode 100644 index 43e02979c1..0000000000 --- a/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "VsyncConfiguration.h" - -#include <chrono> -#include <cinttypes> -#include <optional> - -#include <cutils/properties.h> -#include <log/log.h> - -#include "SurfaceFlingerProperties.h" - -namespace { - -using namespace std::chrono_literals; - -std::optional<nsecs_t> getProperty(const char* name) { - char value[PROPERTY_VALUE_MAX]; - property_get(name, value, "-1"); - if (const int i = atoi(value); i != -1) return i; - return std::nullopt; -} - -} // namespace - -namespace android::scheduler::impl { - -VsyncConfiguration::VsyncConfiguration(Fps currentFps) : mRefreshRateFps(currentFps) {} - -PhaseOffsets::VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRate(Fps fps) const { - std::lock_guard lock(mLock); - return getConfigsForRefreshRateLocked(fps); -} - -PhaseOffsets::VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRateLocked(Fps fps) const { - const auto iter = mOffsetsCache.find(fps); - if (iter != mOffsetsCache.end()) { - return iter->second; - } - - const auto offset = constructOffsets(fps.getPeriodNsecs()); - mOffsetsCache[fps] = offset; - return offset; -} - -void VsyncConfiguration::dump(std::string& result) const { - const auto [early, earlyGpu, late, hwcMinWorkDuration] = getCurrentConfigs(); - using base::StringAppendF; - StringAppendF(&result, - " app phase: %9" PRId64 " ns\t SF phase: %9" PRId64 - " ns\n" - " app duration: %9lld ns\t SF duration: %9lld ns\n" - " early app phase: %9" PRId64 " ns\t early SF phase: %9" PRId64 - " ns\n" - " early app duration: %9lld ns\t early SF duration: %9lld ns\n" - " GL early app phase: %9" PRId64 " ns\tGL early SF phase: %9" PRId64 - " ns\n" - " GL early app duration: %9lld ns\tGL early SF duration: %9lld ns\n" - " HWC min duration: %9lld ns\n", - late.appOffset, late.sfOffset, - - late.appWorkDuration.count(), late.sfWorkDuration.count(), - - early.appOffset, early.sfOffset, - - early.appWorkDuration.count(), early.sfWorkDuration.count(), - - earlyGpu.appOffset, earlyGpu.sfOffset, - - earlyGpu.appWorkDuration.count(), earlyGpu.sfWorkDuration.count(), - - hwcMinWorkDuration.count()); -} - -PhaseOffsets::PhaseOffsets(Fps currentRefreshRate) - : PhaseOffsets(currentRefreshRate, sysprop::vsync_event_phase_offset_ns(1000000), - sysprop::vsync_sf_event_phase_offset_ns(1000000), - getProperty("debug.sf.early_phase_offset_ns"), - getProperty("debug.sf.early_gl_phase_offset_ns"), - getProperty("debug.sf.early_app_phase_offset_ns"), - getProperty("debug.sf.early_gl_app_phase_offset_ns"), - getProperty("debug.sf.high_fps_late_app_phase_offset_ns").value_or(2000000), - getProperty("debug.sf.high_fps_late_sf_phase_offset_ns").value_or(1000000), - getProperty("debug.sf.high_fps_early_phase_offset_ns"), - getProperty("debug.sf.high_fps_early_gl_phase_offset_ns"), - getProperty("debug.sf.high_fps_early_app_phase_offset_ns"), - getProperty("debug.sf.high_fps_early_gl_app_phase_offset_ns"), - // Below defines the threshold when an offset is considered to be negative, - // i.e. targeting for the N+2 vsync instead of N+1. This means that: For offset - // < threshold, SF wake up (vsync_duration - offset) before HW vsync. For - // offset >= threshold, SF wake up (2 * vsync_duration - offset) before HW - // vsync. - getProperty("debug.sf.phase_offset_threshold_for_next_vsync_ns") - .value_or(std::numeric_limits<nsecs_t>::max()), - getProperty("debug.sf.hwc.min.duration").value_or(0)) {} - -PhaseOffsets::PhaseOffsets(Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs, - std::optional<nsecs_t> earlySfOffsetNs, - std::optional<nsecs_t> earlyGpuSfOffsetNs, - std::optional<nsecs_t> earlyAppOffsetNs, - std::optional<nsecs_t> earlyGpuAppOffsetNs, - nsecs_t highFpsVsyncPhaseOffsetNs, nsecs_t highFpsSfVSyncPhaseOffsetNs, - std::optional<nsecs_t> highFpsEarlySfOffsetNs, - std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs, - std::optional<nsecs_t> highFpsEarlyAppOffsetNs, - std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, - nsecs_t thresholdForNextVsync, nsecs_t hwcMinWorkDuration) - : VsyncConfiguration(currentFps), - mVSyncPhaseOffsetNs(vsyncPhaseOffsetNs), - mSfVSyncPhaseOffsetNs(sfVSyncPhaseOffsetNs), - mEarlySfOffsetNs(earlySfOffsetNs), - mEarlyGpuSfOffsetNs(earlyGpuSfOffsetNs), - mEarlyAppOffsetNs(earlyAppOffsetNs), - mEarlyGpuAppOffsetNs(earlyGpuAppOffsetNs), - mHighFpsVSyncPhaseOffsetNs(highFpsVsyncPhaseOffsetNs), - mHighFpsSfVSyncPhaseOffsetNs(highFpsSfVSyncPhaseOffsetNs), - mHighFpsEarlySfOffsetNs(highFpsEarlySfOffsetNs), - mHighFpsEarlyGpuSfOffsetNs(highFpsEarlyGpuSfOffsetNs), - mHighFpsEarlyAppOffsetNs(highFpsEarlyAppOffsetNs), - mHighFpsEarlyGpuAppOffsetNs(highFpsEarlyGpuAppOffsetNs), - mThresholdForNextVsync(thresholdForNextVsync), - mHwcMinWorkDuration(hwcMinWorkDuration) {} - -PhaseOffsets::VsyncConfigSet PhaseOffsets::constructOffsets(nsecs_t vsyncDuration) const { - if (vsyncDuration < std::chrono::nanoseconds(15ms).count()) { - return getHighFpsOffsets(vsyncDuration); - } else { - return getDefaultOffsets(vsyncDuration); - } -} - -namespace { -std::chrono::nanoseconds sfOffsetToDuration(nsecs_t sfOffset, nsecs_t vsyncDuration) { - return std::chrono::nanoseconds(vsyncDuration - sfOffset); -} - -std::chrono::nanoseconds appOffsetToDuration(nsecs_t appOffset, nsecs_t sfOffset, - nsecs_t vsyncDuration) { - auto duration = vsyncDuration + (sfOffset - appOffset); - if (duration < vsyncDuration) { - duration += vsyncDuration; - } - - return std::chrono::nanoseconds(duration); -} -} // namespace - -PhaseOffsets::VsyncConfigSet PhaseOffsets::getDefaultOffsets(nsecs_t vsyncDuration) const { - const auto earlySfOffset = - mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) < mThresholdForNextVsync - - ? mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) - : mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) - vsyncDuration; - const auto earlyAppOffset = mEarlyAppOffsetNs.value_or(mVSyncPhaseOffsetNs); - const auto earlyGpuSfOffset = - mEarlyGpuSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) < mThresholdForNextVsync - - ? mEarlyGpuSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) - : mEarlyGpuSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) - vsyncDuration; - const auto earlyGpuAppOffset = mEarlyGpuAppOffsetNs.value_or(mVSyncPhaseOffsetNs); - const auto lateSfOffset = mSfVSyncPhaseOffsetNs < mThresholdForNextVsync - ? mSfVSyncPhaseOffsetNs - : mSfVSyncPhaseOffsetNs - vsyncDuration; - const auto lateAppOffset = mVSyncPhaseOffsetNs; - - return { - .early = {.sfOffset = earlySfOffset, - .appOffset = earlyAppOffset, - .sfWorkDuration = sfOffsetToDuration(earlySfOffset, vsyncDuration), - .appWorkDuration = - appOffsetToDuration(earlyAppOffset, earlySfOffset, vsyncDuration)}, - .earlyGpu = {.sfOffset = earlyGpuSfOffset, - .appOffset = earlyGpuAppOffset, - .sfWorkDuration = sfOffsetToDuration(earlyGpuSfOffset, vsyncDuration), - .appWorkDuration = appOffsetToDuration(earlyGpuAppOffset, earlyGpuSfOffset, - vsyncDuration)}, - .late = {.sfOffset = lateSfOffset, - .appOffset = lateAppOffset, - .sfWorkDuration = sfOffsetToDuration(lateSfOffset, vsyncDuration), - .appWorkDuration = - appOffsetToDuration(lateAppOffset, lateSfOffset, vsyncDuration)}, - .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration), - }; -} - -PhaseOffsets::VsyncConfigSet PhaseOffsets::getHighFpsOffsets(nsecs_t vsyncDuration) const { - const auto earlySfOffset = - mHighFpsEarlySfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs) < mThresholdForNextVsync - ? mHighFpsEarlySfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs) - : mHighFpsEarlySfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs) - vsyncDuration; - const auto earlyAppOffset = mHighFpsEarlyAppOffsetNs.value_or(mHighFpsVSyncPhaseOffsetNs); - const auto earlyGpuSfOffset = mHighFpsEarlyGpuSfOffsetNs.value_or( - mHighFpsSfVSyncPhaseOffsetNs) < mThresholdForNextVsync - - ? mHighFpsEarlyGpuSfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs) - : mHighFpsEarlyGpuSfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs) - vsyncDuration; - const auto earlyGpuAppOffset = mHighFpsEarlyGpuAppOffsetNs.value_or(mHighFpsVSyncPhaseOffsetNs); - const auto lateSfOffset = mHighFpsSfVSyncPhaseOffsetNs < mThresholdForNextVsync - ? mHighFpsSfVSyncPhaseOffsetNs - : mHighFpsSfVSyncPhaseOffsetNs - vsyncDuration; - const auto lateAppOffset = mHighFpsVSyncPhaseOffsetNs; - - return { - .early = - { - .sfOffset = earlySfOffset, - .appOffset = earlyAppOffset, - .sfWorkDuration = sfOffsetToDuration(earlySfOffset, vsyncDuration), - .appWorkDuration = appOffsetToDuration(earlyAppOffset, earlySfOffset, - vsyncDuration), - }, - .earlyGpu = - { - .sfOffset = earlyGpuSfOffset, - .appOffset = earlyGpuAppOffset, - .sfWorkDuration = sfOffsetToDuration(earlyGpuSfOffset, vsyncDuration), - .appWorkDuration = appOffsetToDuration(earlyGpuAppOffset, - earlyGpuSfOffset, vsyncDuration), - }, - .late = - { - .sfOffset = lateSfOffset, - .appOffset = lateAppOffset, - .sfWorkDuration = sfOffsetToDuration(lateSfOffset, vsyncDuration), - .appWorkDuration = - appOffsetToDuration(lateAppOffset, lateSfOffset, vsyncDuration), - }, - .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration), - }; -} - -static void validateSysprops() { - const auto validatePropertyBool = [](const char* prop) { - LOG_ALWAYS_FATAL_IF(!property_get_bool(prop, false), "%s is false", prop); - }; - - validatePropertyBool("debug.sf.use_phase_offsets_as_durations"); - - LOG_ALWAYS_FATAL_IF(sysprop::vsync_event_phase_offset_ns(-1) != -1, - "ro.surface_flinger.vsync_event_phase_offset_ns is set but expecting " - "duration"); - - LOG_ALWAYS_FATAL_IF(sysprop::vsync_sf_event_phase_offset_ns(-1) != -1, - "ro.surface_flinger.vsync_sf_event_phase_offset_ns is set but expecting " - "duration"); - - const auto validateProperty = [](const char* prop) { - LOG_ALWAYS_FATAL_IF(getProperty(prop).has_value(), - "%s is set to %" PRId64 " but expecting duration", prop, - getProperty(prop).value_or(-1)); - }; - - validateProperty("debug.sf.early_phase_offset_ns"); - validateProperty("debug.sf.early_gl_phase_offset_ns"); - validateProperty("debug.sf.early_app_phase_offset_ns"); - validateProperty("debug.sf.early_gl_app_phase_offset_ns"); - validateProperty("debug.sf.high_fps_late_app_phase_offset_ns"); - validateProperty("debug.sf.high_fps_late_sf_phase_offset_ns"); - validateProperty("debug.sf.high_fps_early_phase_offset_ns"); - validateProperty("debug.sf.high_fps_early_gl_phase_offset_ns"); - validateProperty("debug.sf.high_fps_early_app_phase_offset_ns"); - validateProperty("debug.sf.high_fps_early_gl_app_phase_offset_ns"); -} - -namespace { -nsecs_t sfDurationToOffset(std::chrono::nanoseconds sfDuration, nsecs_t vsyncDuration) { - return vsyncDuration - sfDuration.count() % vsyncDuration; -} - -nsecs_t appDurationToOffset(std::chrono::nanoseconds appDuration, - std::chrono::nanoseconds sfDuration, nsecs_t vsyncDuration) { - return vsyncDuration - (appDuration + sfDuration).count() % vsyncDuration; -} -} // namespace - -WorkDuration::VsyncConfigSet WorkDuration::constructOffsets(nsecs_t vsyncDuration) const { - const auto sfDurationFixup = [vsyncDuration](nsecs_t duration) { - return duration == -1 ? std::chrono::nanoseconds(vsyncDuration) - 1ms - : std::chrono::nanoseconds(duration); - }; - - const auto appDurationFixup = [vsyncDuration](nsecs_t duration) { - return duration == -1 ? std::chrono::nanoseconds(vsyncDuration) - : std::chrono::nanoseconds(duration); - }; - - const auto sfEarlyDuration = sfDurationFixup(mSfEarlyDuration); - const auto appEarlyDuration = appDurationFixup(mAppEarlyDuration); - const auto sfEarlyGpuDuration = sfDurationFixup(mSfEarlyGpuDuration); - const auto appEarlyGpuDuration = appDurationFixup(mAppEarlyGpuDuration); - const auto sfDuration = sfDurationFixup(mSfDuration); - const auto appDuration = appDurationFixup(mAppDuration); - - return { - .early = - { - - .sfOffset = sfEarlyDuration.count() < vsyncDuration - ? sfDurationToOffset(sfEarlyDuration, vsyncDuration) - : sfDurationToOffset(sfEarlyDuration, vsyncDuration) - - vsyncDuration, - - .appOffset = appDurationToOffset(appEarlyDuration, sfEarlyDuration, - vsyncDuration), - - .sfWorkDuration = sfEarlyDuration, - .appWorkDuration = appEarlyDuration, - }, - .earlyGpu = - { - - .sfOffset = sfEarlyGpuDuration.count() < vsyncDuration - - ? sfDurationToOffset(sfEarlyGpuDuration, vsyncDuration) - : sfDurationToOffset(sfEarlyGpuDuration, vsyncDuration) - - vsyncDuration, - - .appOffset = appDurationToOffset(appEarlyGpuDuration, - sfEarlyGpuDuration, vsyncDuration), - .sfWorkDuration = sfEarlyGpuDuration, - .appWorkDuration = appEarlyGpuDuration, - }, - .late = - { - - .sfOffset = sfDuration.count() < vsyncDuration - - ? sfDurationToOffset(sfDuration, vsyncDuration) - : sfDurationToOffset(sfDuration, vsyncDuration) - vsyncDuration, - - .appOffset = - appDurationToOffset(appDuration, sfDuration, vsyncDuration), - - .sfWorkDuration = sfDuration, - .appWorkDuration = appDuration, - }, - .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration), - }; -} - -WorkDuration::WorkDuration(Fps currentRefreshRate) - : WorkDuration(currentRefreshRate, getProperty("debug.sf.late.sf.duration").value_or(-1), - getProperty("debug.sf.late.app.duration").value_or(-1), - getProperty("debug.sf.early.sf.duration").value_or(mSfDuration), - getProperty("debug.sf.early.app.duration").value_or(mAppDuration), - getProperty("debug.sf.earlyGl.sf.duration").value_or(mSfDuration), - getProperty("debug.sf.earlyGl.app.duration").value_or(mAppDuration), - getProperty("debug.sf.hwc.min.duration").value_or(0)) { - validateSysprops(); -} - -WorkDuration::WorkDuration(Fps currentRefreshRate, nsecs_t sfDuration, nsecs_t appDuration, - nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, - nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration, - nsecs_t hwcMinWorkDuration) - : VsyncConfiguration(currentRefreshRate), - mSfDuration(sfDuration), - mAppDuration(appDuration), - mSfEarlyDuration(sfEarlyDuration), - mAppEarlyDuration(appEarlyDuration), - mSfEarlyGpuDuration(sfEarlyGpuDuration), - mAppEarlyGpuDuration(appEarlyGpuDuration), - mHwcMinWorkDuration(hwcMinWorkDuration) {} - -} // namespace android::scheduler::impl |