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

Commit 35018763 authored by Ady Abraham's avatar Ady Abraham
Browse files

SurfaceFlinger: handle high refresh rate deny list

Add visibility to SurfaceFlinger into the high refresh rate deny list
and let SurfaceFlinger handle it. Previously WM was setting the
preferredDisplayModeId on the denied app's window. The old way prevented
SurfaceFlinger to use the frame rate override feature as it didn't
know that a specific app is causing the refresh rate spec to be limited.

With this change, SurfaceFlinger will limit the display refresh rate based
on the high refresh rate deny list, and if possible, will use the frame
rate override feature to change the display rate to a multiple, allowing
other animations to be smooth while the denied app remains in the low
refresh rate.

Bug: 170502573
Test: SF unit tests
Change-Id: Idc8a5fe6bc12dbd949ad5e09ff50e339ffaeac36
parent 20dcde8e
Loading
Loading
Loading
Loading
+7 −3
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


#define LOG_TAG "LayerState"
#define LOG_TAG "LayerState"


#include <apex/window.h>
#include <inttypes.h>
#include <inttypes.h>


#include <binder/Parcel.h>
#include <binder/Parcel.h>
@@ -620,7 +621,8 @@ status_t InputWindowCommands::read(const Parcel& input) {
    return NO_ERROR;
    return NO_ERROR;
}
}


bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* inFunctionName) {
bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* inFunctionName,
                       bool privileged) {
    const char* functionName = inFunctionName != nullptr ? inFunctionName : "call";
    const char* functionName = inFunctionName != nullptr ? inFunctionName : "call";
    int floatClassification = std::fpclassify(frameRate);
    int floatClassification = std::fpclassify(frameRate);
    if (frameRate < 0 || floatClassification == FP_INFINITE || floatClassification == FP_NAN) {
    if (frameRate < 0 || floatClassification == FP_INFINITE || floatClassification == FP_NAN) {
@@ -629,8 +631,10 @@ bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* inFunc
    }
    }


    if (compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT &&
    if (compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT &&
        compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE) {
        compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE &&
        ALOGE("%s failed - invalid compatibility value %d", functionName, compatibility);
        (!privileged || compatibility != ANATIVEWINDOW_FRAME_RATE_EXACT)) {
        ALOGE("%s failed - invalid compatibility value %d privileged: %s", functionName,
              compatibility, privileged ? "yes" : "no");
        return false;
        return false;
    }
    }


+4 −1
Original line number Original line Diff line number Diff line
@@ -1518,7 +1518,10 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrame
        mStatus = BAD_INDEX;
        mStatus = BAD_INDEX;
        return *this;
        return *this;
    }
    }
    if (!ValidateFrameRate(frameRate, compatibility, "Transaction::setFrameRate")) {
    // Allow privileged values as well here, those will be ignored by SF if
    // the caller is not privileged
    if (!ValidateFrameRate(frameRate, compatibility, "Transaction::setFrameRate",
                           /*privileged=*/true)) {
        mStatus = BAD_VALUE;
        mStatus = BAD_VALUE;
        return *this;
        return *this;
    }
    }
+8 −5
Original line number Original line Diff line number Diff line
@@ -309,11 +309,14 @@ static inline int compare_type(const DisplayState& lhs, const DisplayState& rhs)
    return compare_type(lhs.token, rhs.token);
    return compare_type(lhs.token, rhs.token);
}
}


// Returns true if the frameRate and compatibility are valid values, false
// Returns true if the frameRate is valid.
// othwerise. If either of the params are invalid, an error log is printed, and
//
// functionName is added to the log to indicate which function call failed.
// @param frameRate the frame rate in Hz
// functionName can be null.
// @param compatibility a ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_*
bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* functionName);
// @param functionName calling function or nullptr. Used for logging
// @param privileged whether caller has unscoped surfaceflinger access
bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* functionName,
                       bool privileged = false);


struct CaptureArgs {
struct CaptureArgs {
    const static int32_t UNSET_UID = -1;
    const static int32_t UNSET_UID = -1;
+13 −0
Original line number Original line Diff line number Diff line
@@ -39,6 +39,19 @@ enum ANativeWindowPerform {
    // clang-format on
    // clang-format on
};
};


/*
 * Internal extension of compatibility value for ANativeWindow_setFrameRate. */
enum ANativeWindow_FrameRateCompatibilityInternal {
    /**
     * This surface belongs to an app on the High Refresh Rate Deny list, and needs the display
     * to operate at the exact frame rate.
     *
     * This is used internally by the platform and should not be used by apps.
     * @hide
     */
    ANATIVEWINDOW_FRAME_RATE_EXACT = 100,
};

/**
/**
 * Prototype of the function that an ANativeWindow implementation would call
 * Prototype of the function that an ANativeWindow implementation would call
 * when ANativeWindow_cancelBuffer is called.
 * when ANativeWindow_cancelBuffer is called.
+8 −1
Original line number Original line Diff line number Diff line
@@ -1441,11 +1441,14 @@ void Layer::updateTreeHasFrameRateVote() {
                layer->mCurrentState.frameRate.type == FrameRateCompatibility::Default;
                layer->mCurrentState.frameRate.type == FrameRateCompatibility::Default;
        const auto layerVotedWithNoVote =
        const auto layerVotedWithNoVote =
                layer->mCurrentState.frameRate.type == FrameRateCompatibility::NoVote;
                layer->mCurrentState.frameRate.type == FrameRateCompatibility::NoVote;
        const auto layerVotedWithExactCompatibility =
                layer->mCurrentState.frameRate.type == FrameRateCompatibility::Exact;


        // We do not count layers that are ExactOrMultiple for the same reason
        // We do not count layers that are ExactOrMultiple for the same reason
        // we are allowing touch boost for those layers. See
        // we are allowing touch boost for those layers. See
        // RefreshRateConfigs::getBestRefreshRate for more details.
        // RefreshRateConfigs::getBestRefreshRate for more details.
        if (layerVotedWithDefaultCompatibility || layerVotedWithNoVote) {
        if (layerVotedWithDefaultCompatibility || layerVotedWithNoVote ||
            layerVotedWithExactCompatibility) {
            layersWithVote++;
            layersWithVote++;
        }
        }


@@ -1662,6 +1665,8 @@ std::string Layer::frameRateCompatibilityString(Layer::FrameRateCompatibility co
            return "ExactOrMultiple";
            return "ExactOrMultiple";
        case FrameRateCompatibility::NoVote:
        case FrameRateCompatibility::NoVote:
            return "NoVote";
            return "NoVote";
        case FrameRateCompatibility::Exact:
            return "Exact";
    }
    }
}
}


@@ -2763,6 +2768,8 @@ Layer::FrameRateCompatibility Layer::FrameRate::convertCompatibility(int8_t comp
            return FrameRateCompatibility::Default;
            return FrameRateCompatibility::Default;
        case ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE:
        case ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE:
            return FrameRateCompatibility::ExactOrMultiple;
            return FrameRateCompatibility::ExactOrMultiple;
        case ANATIVEWINDOW_FRAME_RATE_EXACT:
            return FrameRateCompatibility::Exact;
        default:
        default:
            LOG_ALWAYS_FATAL("Invalid frame rate compatibility value %d", compatibility);
            LOG_ALWAYS_FATAL("Invalid frame rate compatibility value %d", compatibility);
            return FrameRateCompatibility::Default;
            return FrameRateCompatibility::Default;
Loading