Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8dc3dd2b authored by Ana Krulec's avatar Ana Krulec
Browse files

SF: Use content detection flag to protect the content detection policy

Somewhere in the process of migration we forgot to include the
use_content_detection_for_refresh_rate sysprop flag. This CL guards
the content detection policy with this guard.

Test: Turn the flag off. No content detection. Turn the flag on.
      Observe content detection.
Test: On Cuttlefish.
Test: Added unit test in RefreshRateConfigs.
Test: atest libsurfaceflinger tests
Bug: 150003390
Bug: 150212108
Change-Id: Icff9ab9ffd3604049dfe36efd5d3939e1d77b091
parent 3770556d
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -107,6 +107,12 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2(
        return *mAvailableRefreshRates.back();
        return *mAvailableRefreshRates.back();
    }
    }


    // If there are not layers, there is not content detection, so return the current
    // refresh rate.
    if (layers.empty()) {
        return getCurrentRefreshRateByPolicyLocked();
    }

    int noVoteLayers = 0;
    int noVoteLayers = 0;
    int minVoteLayers = 0;
    int minVoteLayers = 0;
    int maxVoteLayers = 0;
    int maxVoteLayers = 0;
@@ -272,6 +278,10 @@ const RefreshRate& RefreshRateConfigs::getCurrentRefreshRate() const {


const RefreshRate& RefreshRateConfigs::getCurrentRefreshRateByPolicy() const {
const RefreshRate& RefreshRateConfigs::getCurrentRefreshRateByPolicy() const {
    std::lock_guard lock(mLock);
    std::lock_guard lock(mLock);
    return getCurrentRefreshRateByPolicyLocked();
}

const RefreshRate& RefreshRateConfigs::getCurrentRefreshRateByPolicyLocked() const {
    if (std::find(mAvailableRefreshRates.begin(), mAvailableRefreshRates.end(),
    if (std::find(mAvailableRefreshRates.begin(), mAvailableRefreshRates.end(),
                  mCurrentRefreshRate) != mAvailableRefreshRates.end()) {
                  mCurrentRefreshRate) != mAvailableRefreshRates.end()) {
        return *mCurrentRefreshRate;
        return *mCurrentRefreshRate;
+4 −0
Original line number Original line Diff line number Diff line
@@ -199,6 +199,10 @@ private:
    // display refresh period.
    // display refresh period.
    std::pair<nsecs_t, nsecs_t> getDisplayFrames(nsecs_t layerPeriod, nsecs_t displayPeriod) const;
    std::pair<nsecs_t, nsecs_t> getDisplayFrames(nsecs_t layerPeriod, nsecs_t displayPeriod) const;


    // Returns the current refresh rate, if allowed. Otherwise the default that is allowed by
    // the policy.
    const RefreshRate& getCurrentRefreshRateByPolicyLocked() const REQUIRES(mLock);

    // The list of refresh rates, indexed by display config ID. This must not change after this
    // The list of refresh rates, indexed by display config ID. This must not change after this
    // object is initialized.
    // object is initialized.
    AllRefreshRatesMapType mRefreshRates;
    AllRefreshRatesMapType mRefreshRates;
+21 −3
Original line number Original line Diff line number Diff line
@@ -99,12 +99,14 @@ std::unique_ptr<DispSync> createDispSync() {


Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function,
Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function,
                     const scheduler::RefreshRateConfigs& refreshRateConfig,
                     const scheduler::RefreshRateConfigs& refreshRateConfig,
                     ISchedulerCallback& schedulerCallback, bool useContentDetectionV2)
                     ISchedulerCallback& schedulerCallback, bool useContentDetectionV2,
                     bool useContentDetection)
      : mPrimaryDispSync(createDispSync()),
      : mPrimaryDispSync(createDispSync()),
        mEventControlThread(new impl::EventControlThread(std::move(function))),
        mEventControlThread(new impl::EventControlThread(std::move(function))),
        mSupportKernelTimer(sysprop::support_kernel_idle_timer(false)),
        mSupportKernelTimer(sysprop::support_kernel_idle_timer(false)),
        mSchedulerCallback(schedulerCallback),
        mSchedulerCallback(schedulerCallback),
        mRefreshRateConfigs(refreshRateConfig),
        mRefreshRateConfigs(refreshRateConfig),
        mUseContentDetection(useContentDetection),
        mUseContentDetectionV2(useContentDetectionV2) {
        mUseContentDetectionV2(useContentDetectionV2) {
    using namespace sysprop;
    using namespace sysprop;


@@ -147,12 +149,14 @@ Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function,
Scheduler::Scheduler(std::unique_ptr<DispSync> primaryDispSync,
Scheduler::Scheduler(std::unique_ptr<DispSync> primaryDispSync,
                     std::unique_ptr<EventControlThread> eventControlThread,
                     std::unique_ptr<EventControlThread> eventControlThread,
                     const scheduler::RefreshRateConfigs& configs,
                     const scheduler::RefreshRateConfigs& configs,
                     ISchedulerCallback& schedulerCallback, bool useContentDetectionV2)
                     ISchedulerCallback& schedulerCallback, bool useContentDetectionV2,
                     bool useContentDetection)
      : mPrimaryDispSync(std::move(primaryDispSync)),
      : mPrimaryDispSync(std::move(primaryDispSync)),
        mEventControlThread(std::move(eventControlThread)),
        mEventControlThread(std::move(eventControlThread)),
        mSupportKernelTimer(false),
        mSupportKernelTimer(false),
        mSchedulerCallback(schedulerCallback),
        mSchedulerCallback(schedulerCallback),
        mRefreshRateConfigs(configs),
        mRefreshRateConfigs(configs),
        mUseContentDetection(useContentDetection),
        mUseContentDetectionV2(useContentDetectionV2) {}
        mUseContentDetectionV2(useContentDetectionV2) {}


Scheduler::~Scheduler() {
Scheduler::~Scheduler() {
@@ -381,6 +385,17 @@ nsecs_t Scheduler::getDispSyncExpectedPresentTime() {
void Scheduler::registerLayer(Layer* layer) {
void Scheduler::registerLayer(Layer* layer) {
    if (!mLayerHistory) return;
    if (!mLayerHistory) return;


    // If the content detection feature is off, all layers are registered at NoVote. We still
    // keep the layer history, since we use it for other features (like Frame Rate API), so layers
    // still need to be registered.
    if (!mUseContentDetection) {
        mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
                                     mRefreshRateConfigs.getMaxRefreshRate().fps,
                                     scheduler::LayerHistory::LayerVoteType::NoVote);
        return;
    }

    // In V1 of content detection, all layers are registered as Heuristic (unless it's wallpaper).
    if (!mUseContentDetectionV2) {
    if (!mUseContentDetectionV2) {
        const auto lowFps = mRefreshRateConfigs.getMinRefreshRate().fps;
        const auto lowFps = mRefreshRateConfigs.getMinRefreshRate().fps;
        const auto highFps = layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER
        const auto highFps = layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER
@@ -391,6 +406,7 @@ void Scheduler::registerLayer(Layer* layer) {
                                     scheduler::LayerHistory::LayerVoteType::Heuristic);
                                     scheduler::LayerHistory::LayerVoteType::Heuristic);
    } else {
    } else {
        if (layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER) {
        if (layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER) {
            // Running Wallpaper at Min is considered as part of content detection.
            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
                                         mRefreshRateConfigs.getMaxRefreshRate().fps,
                                         mRefreshRateConfigs.getMaxRefreshRate().fps,
                                         scheduler::LayerHistory::LayerVoteType::Min);
                                         scheduler::LayerHistory::LayerVoteType::Min);
@@ -537,8 +553,10 @@ void Scheduler::dump(std::string& result) const {


    StringAppendF(&result, "+  Idle timer: %s\n",
    StringAppendF(&result, "+  Idle timer: %s\n",
                  mIdleTimer ? mIdleTimer->dump().c_str() : states[0]);
                  mIdleTimer ? mIdleTimer->dump().c_str() : states[0]);
    StringAppendF(&result, "+  Touch timer: %s\n\n",
    StringAppendF(&result, "+  Touch timer: %s\n",
                  mTouchTimer ? mTouchTimer->dump().c_str() : states[0]);
                  mTouchTimer ? mTouchTimer->dump().c_str() : states[0]);
    StringAppendF(&result, "+  Use content detection: %s\n\n",
                  sysprop::use_content_detection_for_refresh_rate(false) ? "on" : "off");
}
}


template <class T>
template <class T>
+5 −2
Original line number Original line Diff line number Diff line
@@ -63,7 +63,7 @@ public:


    Scheduler(impl::EventControlThread::SetVSyncEnabledFunction,
    Scheduler(impl::EventControlThread::SetVSyncEnabledFunction,
              const scheduler::RefreshRateConfigs&, ISchedulerCallback& schedulerCallback,
              const scheduler::RefreshRateConfigs&, ISchedulerCallback& schedulerCallback,
              bool useContentDetectionV2);
              bool useContentDetectionV2, bool useContentDetection);


    virtual ~Scheduler();
    virtual ~Scheduler();


@@ -159,7 +159,7 @@ private:
    // Used by tests to inject mocks.
    // Used by tests to inject mocks.
    Scheduler(std::unique_ptr<DispSync>, std::unique_ptr<EventControlThread>,
    Scheduler(std::unique_ptr<DispSync>, std::unique_ptr<EventControlThread>,
              const scheduler::RefreshRateConfigs&, ISchedulerCallback& schedulerCallback,
              const scheduler::RefreshRateConfigs&, ISchedulerCallback& schedulerCallback,
              bool useContentDetectionV2);
              bool useContentDetectionV2, bool useContentDetection);


    std::unique_ptr<VSyncSource> makePrimaryDispSyncSource(const char* name, nsecs_t phaseOffsetNs);
    std::unique_ptr<VSyncSource> makePrimaryDispSyncSource(const char* name, nsecs_t phaseOffsetNs);


@@ -245,6 +245,9 @@ private:
            GUARDED_BY(mVsyncTimelineLock);
            GUARDED_BY(mVsyncTimelineLock);
    static constexpr std::chrono::nanoseconds MAX_VSYNC_APPLIED_TIME = 200ms;
    static constexpr std::chrono::nanoseconds MAX_VSYNC_APPLIED_TIME = 200ms;


    // This variable indicates whether to use the content detection feature at all.
    const bool mUseContentDetection;
    // This variable indicates whether to use V2 version of the content detection.
    const bool mUseContentDetectionV2;
    const bool mUseContentDetectionV2;
};
};


+3 −2
Original line number Original line Diff line number Diff line
@@ -33,6 +33,7 @@
#include "NativeWindowSurface.h"
#include "NativeWindowSurface.h"
#include "StartPropertySetThread.h"
#include "StartPropertySetThread.h"
#include "SurfaceFlingerDefaultFactory.h"
#include "SurfaceFlingerDefaultFactory.h"
#include "SurfaceFlingerProperties.h"
#include "SurfaceInterceptor.h"
#include "SurfaceInterceptor.h"


#include "DisplayHardware/ComposerHal.h"
#include "DisplayHardware/ComposerHal.h"
@@ -76,8 +77,8 @@ std::unique_ptr<Scheduler> DefaultFactory::createScheduler(
        SetVSyncEnabled setVSyncEnabled, const scheduler::RefreshRateConfigs& configs,
        SetVSyncEnabled setVSyncEnabled, const scheduler::RefreshRateConfigs& configs,
        ISchedulerCallback& schedulerCallback) {
        ISchedulerCallback& schedulerCallback) {
    return std::make_unique<Scheduler>(std::move(setVSyncEnabled), configs, schedulerCallback,
    return std::make_unique<Scheduler>(std::move(setVSyncEnabled), configs, schedulerCallback,
                                       property_get_bool("debug.sf.use_content_detection_v2",
                                       property_get_bool("debug.sf.use_content_detection_v2", true),
                                                         true));
                                       sysprop::use_content_detection_for_refresh_rate(false));
}
}


std::unique_ptr<SurfaceInterceptor> DefaultFactory::createSurfaceInterceptor(
std::unique_ptr<SurfaceInterceptor> DefaultFactory::createSurfaceInterceptor(
Loading