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

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

SurfaceFlinger: only focused layers can use appRequestRange

When DisplayManager sets the DisplayConfigsSpecs with a policy
that the appRequestRange is broader than the primaryRange,
it means that an app can choose a refresh rate from the
appRequestRange and not from the primaryRange only if that app
explicitly specified a frame rate using setFrameRate API. However,
to avoid cases where we switch the refresh rate back and forth from
the two ranges, we are allowing only applications that their window
is focused from WindowManager's perspective to select refresh rate out
the primaryRange. This matches the behavior of an application that sets
the preferredDisplayModeId.

Bug: 144307188
Bug: 159940172
Test: adb shell /data/nativetest64/libsurfaceflinger_unittest/libsurfaceflinger_unittest
Test: YouTube in PIP mode while device is restricted by primaryRange

Change-Id: I26a9690210bb5771bd8aae2bff301031617f7c8f
parent f4facf26
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -1325,6 +1325,10 @@ int32_t Layer::getFrameRateSelectionPriority() const {
    return Layer::PRIORITY_UNSET;
}

bool Layer::isLayerFocusedBasedOnPriority(int32_t priority) {
    return priority == PRIORITY_FOCUSED_WITH_MODE || priority == PRIORITY_FOCUSED_WITHOUT_MODE;
};

uint32_t Layer::getLayerStack() const {
    auto p = mDrawingParent.promote();
    if (p == nullptr) {
@@ -1558,7 +1562,7 @@ void Layer::miniDumpHeader(std::string& result) {
    result.append("-------------------------------");
    result.append("-------------------------------");
    result.append("-------------------------------");
    result.append("---------\n");
    result.append("-------------------\n");
    result.append(" Layer name\n");
    result.append("           Z | ");
    result.append(" Window Type | ");
@@ -1566,12 +1570,12 @@ void Layer::miniDumpHeader(std::string& result) {
    result.append(" Transform | ");
    result.append("  Disp Frame (LTRB) | ");
    result.append("         Source Crop (LTRB) | ");
    result.append("    Frame Rate (Explicit)\n");
    result.append("    Frame Rate (Explicit) [Focused]\n");
    result.append("-------------------------------");
    result.append("-------------------------------");
    result.append("-------------------------------");
    result.append("-------------------------------");
    result.append("---------\n");
    result.append("-------------------\n");
}

std::string Layer::frameRateCompatibilityString(Layer::FrameRateCompatibility compatibility) {
@@ -1622,17 +1626,20 @@ void Layer::miniDump(std::string& result, const DisplayDevice& display) const {
                  crop.bottom);
    if (layerState.frameRate.rate != 0 ||
        layerState.frameRate.type != FrameRateCompatibility::Default) {
        StringAppendF(&result, "% 6.2ffps %15s\n", layerState.frameRate.rate,
        StringAppendF(&result, "% 6.2ffps %15s", layerState.frameRate.rate,
                      frameRateCompatibilityString(layerState.frameRate.type).c_str());
    } else {
        StringAppendF(&result, "\n");
        StringAppendF(&result, "                         ");
    }

    const auto focused = isLayerFocusedBasedOnPriority(getFrameRateSelectionPriority());
    StringAppendF(&result, "    [%s]\n", focused ? "*" : " ");

    result.append("- - - - - - - - - - - - - - - - ");
    result.append("- - - - - - - - - - - - - - - - ");
    result.append("- - - - - - - - - - - - - - - - ");
    result.append("- - - - - - - - - - - - - - - - ");
    result.append("- - -\n");
    result.append("- - - - - - - -\n");
}

void Layer::dumpFrameStats(std::string& result) const {
+10 −0
Original line number Diff line number Diff line
@@ -94,7 +94,16 @@ struct LayerCreationArgs {

class Layer : public virtual RefBase, compositionengine::LayerFE {
    static std::atomic<int32_t> sSequence;
    // The following constants represent priority of the window. SF uses this information when
    // deciding which window has a priority when deciding about the refresh rate of the screen.
    // Priority 0 is considered the highest priority. -1 means that the priority is unset.
    static constexpr int32_t PRIORITY_UNSET = -1;
    // Windows that are in focus and voted for the preferred mode ID
    static constexpr int32_t PRIORITY_FOCUSED_WITH_MODE = 0;
    // // Windows that are in focus, but have not requested a specific mode ID.
    static constexpr int32_t PRIORITY_FOCUSED_WITHOUT_MODE = 1;
    // Windows that are not in focus, but voted for a specific mode ID.
    static constexpr int32_t PRIORITY_NOT_FOCUSED_WITH_MODE = 2;

public:
    mutable bool contentDirty{false};
@@ -400,6 +409,7 @@ public:
    //  If the variable is not set on the layer, it traverses up the tree to inherit the frame
    //  rate priority from its parent.
    virtual int32_t getFrameRateSelectionPriority() const;
    static bool isLayerFocusedBasedOnPriority(int32_t priority);

    virtual ui::Dataspace getDataSpace() const { return ui::Dataspace::UNKNOWN; }

+5 −2
Original line number Diff line number Diff line
@@ -109,6 +109,8 @@ LayerHistory::Summary LayerHistory::summarize(nsecs_t now) {
        auto layer = weakLayer.promote();
        // Only use the layer if the reference still exists.
        if (layer || CC_UNLIKELY(mTraceEnabled)) {
            const auto layerFocused =
                    Layer::isLayerFocusedBasedOnPriority(layer->getFrameRateSelectionPriority());
            // Check if frame rate was set on layer.
            const auto frameRate = layer->getFrameRateForLayerTree();
            if (frameRate.rate > 0.f) {
@@ -122,11 +124,12 @@ LayerHistory::Summary LayerHistory::summarize(nsecs_t now) {
                            return LayerVoteType::NoVote;
                    }
                }();
                summary.push_back({layer->getName(), voteType, frameRate.rate, /* weight */ 1.0f});
                summary.push_back({layer->getName(), voteType, frameRate.rate, /* weight */ 1.0f,
                                   layerFocused});
            } else if (recent) {
                summary.push_back({layer->getName(), LayerVoteType::Heuristic,
                                   info->getRefreshRate(now),
                                   /* weight */ 1.0f});
                                   /* weight */ 1.0f, layerFocused});
            }

            if (CC_UNLIKELY(mTraceEnabled)) {
+5 −4
Original line number Diff line number Diff line
@@ -125,9 +125,10 @@ LayerHistoryV2::Summary LayerHistoryV2::summarize(nsecs_t now) {
            continue;
        }

        // TODO(b/144307188): This needs to be plugged into layer summary as
        //  an additional parameter.
        ALOGV("Layer has priority: %d", strong->getFrameRateSelectionPriority());
        const auto frameRateSelectionPriority = strong->getFrameRateSelectionPriority();
        const auto layerFocused = Layer::isLayerFocusedBasedOnPriority(frameRateSelectionPriority);
        ALOGV("%s has priority: %d %s focused", strong->getName().c_str(),
              frameRateSelectionPriority, layerFocused ? "" : "not");

        const auto [type, refreshRate] = info->getRefreshRate(now);
        // Skip NoVote layer as those don't have any requirements
@@ -143,7 +144,7 @@ LayerHistoryV2::Summary LayerHistoryV2::summarize(nsecs_t now) {

        const float layerArea = transformed.getWidth() * transformed.getHeight();
        float weight = mDisplayArea ? layerArea / mDisplayArea : 0.0f;
        summary.push_back({strong->getName(), type, refreshRate, weight});
        summary.push_back({strong->getName(), type, refreshRate, weight, layerFocused});

        if (CC_UNLIKELY(mTraceEnabled)) {
            trace(layer, *info, type, static_cast<int>(std::round(refreshRate)));
+5 −4
Original line number Diff line number Diff line
@@ -212,10 +212,11 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate(
            bool inPrimaryRange =
                    scores[i].first->inPolicy(policy->primaryRange.min, policy->primaryRange.max);
            if ((primaryRangeIsSingleRate || !inPrimaryRange) &&
                layer.vote != LayerVoteType::ExplicitDefault &&
                layer.vote != LayerVoteType::ExplicitExactOrMultiple) {
                // Only layers with explicit frame rate settings are allowed to score refresh rates
                // outside the primary range.
                !(layer.focused &&
                  (layer.vote == LayerVoteType::ExplicitDefault ||
                   layer.vote == LayerVoteType::ExplicitExactOrMultiple))) {
                // Only focused layers with explicit frame rate settings are allowed to score
                // refresh rates outside the primary range.
                continue;
            }

Loading