Home | History | Annotate | Download | only in Scheduler
      1 /*
      2  * Copyright 2019 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 #include "PhaseOffsets.h"
     18 
     19 #include <cutils/properties.h>
     20 
     21 #include "SurfaceFlingerProperties.h"
     22 
     23 namespace android {
     24 using namespace android::sysprop;
     25 
     26 namespace scheduler {
     27 
     28 PhaseOffsets::~PhaseOffsets() = default;
     29 
     30 namespace impl {
     31 PhaseOffsets::PhaseOffsets() {
     32     int64_t vsyncPhaseOffsetNs = vsync_event_phase_offset_ns(1000000);
     33 
     34     int64_t sfVsyncPhaseOffsetNs = vsync_sf_event_phase_offset_ns(1000000);
     35 
     36     char value[PROPERTY_VALUE_MAX];
     37     property_get("debug.sf.early_phase_offset_ns", value, "-1");
     38     const int earlySfOffsetNs = atoi(value);
     39 
     40     property_get("debug.sf.early_gl_phase_offset_ns", value, "-1");
     41     const int earlyGlSfOffsetNs = atoi(value);
     42 
     43     property_get("debug.sf.early_app_phase_offset_ns", value, "-1");
     44     const int earlyAppOffsetNs = atoi(value);
     45 
     46     property_get("debug.sf.early_gl_app_phase_offset_ns", value, "-1");
     47     const int earlyGlAppOffsetNs = atoi(value);
     48 
     49     property_get("debug.sf.high_fps_early_phase_offset_ns", value, "-1");
     50     const int highFpsEarlySfOffsetNs = atoi(value);
     51 
     52     property_get("debug.sf.high_fps_early_gl_phase_offset_ns", value, "-1");
     53     const int highFpsEarlyGlSfOffsetNs = atoi(value);
     54 
     55     property_get("debug.sf.high_fps_early_app_phase_offset_ns", value, "-1");
     56     const int highFpsEarlyAppOffsetNs = atoi(value);
     57 
     58     property_get("debug.sf.high_fps_early_gl_app_phase_offset_ns", value, "-1");
     59     const int highFpsEarlyGlAppOffsetNs = atoi(value);
     60 
     61     // TODO(b/122905996): Define these in device.mk.
     62     property_get("debug.sf.high_fps_late_app_phase_offset_ns", value, "2000000");
     63     const int highFpsLateAppOffsetNs = atoi(value);
     64 
     65     property_get("debug.sf.high_fps_late_sf_phase_offset_ns", value, "1000000");
     66     const int highFpsLateSfOffsetNs = atoi(value);
     67 
     68     // Below defines the threshold when an offset is considered to be negative, i.e. targeting
     69     // for the N+2 vsync instead of N+1. This means that:
     70     // For offset < threshold, SF wake up (vsync_duration - offset) before HW vsync.
     71     // For offset >= threshold, SF wake up (2 * vsync_duration - offset) before HW vsync.
     72     property_get("debug.sf.phase_offset_threshold_for_next_vsync_ns", value, "-1");
     73     const int phaseOffsetThresholdForNextVsyncNs = atoi(value);
     74 
     75     mDefaultRefreshRateOffsets.early = {earlySfOffsetNs != -1 ? earlySfOffsetNs
     76                                                               : sfVsyncPhaseOffsetNs,
     77                                         earlyAppOffsetNs != -1 ? earlyAppOffsetNs
     78                                                                : vsyncPhaseOffsetNs};
     79     mDefaultRefreshRateOffsets.earlyGl = {earlyGlSfOffsetNs != -1 ? earlyGlSfOffsetNs
     80                                                                   : sfVsyncPhaseOffsetNs,
     81                                           earlyGlAppOffsetNs != -1 ? earlyGlAppOffsetNs
     82                                                                    : vsyncPhaseOffsetNs};
     83     mDefaultRefreshRateOffsets.late = {sfVsyncPhaseOffsetNs, vsyncPhaseOffsetNs};
     84 
     85     mHighRefreshRateOffsets.early = {highFpsEarlySfOffsetNs != -1 ? highFpsEarlySfOffsetNs
     86                                                                   : highFpsLateSfOffsetNs,
     87                                      highFpsEarlyAppOffsetNs != -1 ? highFpsEarlyAppOffsetNs
     88                                                                    : highFpsLateAppOffsetNs};
     89     mHighRefreshRateOffsets.earlyGl = {highFpsEarlyGlSfOffsetNs != -1 ? highFpsEarlyGlSfOffsetNs
     90                                                                       : highFpsLateSfOffsetNs,
     91                                        highFpsEarlyGlAppOffsetNs != -1 ? highFpsEarlyGlAppOffsetNs
     92                                                                        : highFpsLateAppOffsetNs};
     93     mHighRefreshRateOffsets.late = {highFpsLateSfOffsetNs, highFpsLateAppOffsetNs};
     94 
     95     mOffsetThresholdForNextVsync = phaseOffsetThresholdForNextVsyncNs != -1
     96             ? phaseOffsetThresholdForNextVsyncNs
     97             : std::numeric_limits<nsecs_t>::max();
     98 }
     99 
    100 PhaseOffsets::Offsets PhaseOffsets::getOffsetsForRefreshRate(
    101         android::scheduler::RefreshRateConfigs::RefreshRateType refreshRateType) const {
    102     switch (refreshRateType) {
    103         case RefreshRateConfigs::RefreshRateType::PERFORMANCE:
    104             return mHighRefreshRateOffsets;
    105         default:
    106             return mDefaultRefreshRateOffsets;
    107     }
    108 }
    109 
    110 void PhaseOffsets::dump(std::string& result) const {
    111     const auto [early, earlyGl, late] = getCurrentOffsets();
    112     base::StringAppendF(&result,
    113                         "         app phase: %9" PRId64 " ns\t         SF phase: %9" PRId64 " ns\n"
    114                         "   early app phase: %9" PRId64 " ns\t   early SF phase: %9" PRId64 " ns\n"
    115                         "GL early app phase: %9" PRId64 " ns\tGL early SF phase: %9" PRId64 " ns\n",
    116                         late.app, late.sf, early.app, early.sf, earlyGl.app, earlyGl.sf);
    117 }
    118 
    119 nsecs_t PhaseOffsets::getCurrentAppOffset() {
    120     return getCurrentOffsets().late.app;
    121 }
    122 
    123 nsecs_t PhaseOffsets::getCurrentSfOffset() {
    124     return getCurrentOffsets().late.sf;
    125 }
    126 
    127 } // namespace impl
    128 } // namespace scheduler
    129 } // namespace android
    130