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

Commit 7c689339 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Loosen requirement that getVsyncSchedule returns an object" into udc-dev am: 52ff89f0

parents 52e27b2c 52ff89f0
Loading
Loading
Loading
Loading
+22 −5
Original line number Diff line number Diff line
@@ -406,11 +406,13 @@ void Scheduler::setVsyncConfig(const VsyncConfig& config, Period vsyncPeriod) {

void Scheduler::enableHardwareVsync(PhysicalDisplayId id) {
    auto schedule = getVsyncSchedule(id);
    LOG_ALWAYS_FATAL_IF(!schedule);
    schedule->enableHardwareVsync(mSchedulerCallback);
}

void Scheduler::disableHardwareVsync(PhysicalDisplayId id, bool disallow) {
    auto schedule = getVsyncSchedule(id);
    LOG_ALWAYS_FATAL_IF(!schedule);
    schedule->disableHardwareVsync(mSchedulerCallback, disallow);
}

@@ -427,7 +429,10 @@ void Scheduler::resyncAllToHardwareVsync(bool allowToEnable) {
void Scheduler::resyncToHardwareVsyncLocked(PhysicalDisplayId id, bool allowToEnable,
                                            std::optional<Fps> refreshRate) {
    const auto displayOpt = mDisplays.get(id);
    LOG_ALWAYS_FATAL_IF(!displayOpt);
    if (!displayOpt) {
        ALOGW("%s: Invalid display %s!", __func__, to_string(id).c_str());
        return;
    }
    const Display& display = *displayOpt;

    if (display.schedulePtr->isHardwareVsyncAllowed(allowToEnable)) {
@@ -446,7 +451,10 @@ void Scheduler::setRenderRate(PhysicalDisplayId id, Fps renderFrameRate) {
    ftl::FakeGuard guard(kMainThreadContext);

    const auto displayOpt = mDisplays.get(id);
    LOG_ALWAYS_FATAL_IF(!displayOpt);
    if (!displayOpt) {
        ALOGW("%s: Invalid display %s!", __func__, to_string(id).c_str());
        return;
    }
    const Display& display = *displayOpt;
    const auto mode = display.selectorPtr->getActiveMode();

@@ -478,12 +486,18 @@ bool Scheduler::addResyncSample(PhysicalDisplayId id, nsecs_t timestamp,
    const auto hwcVsyncPeriod = ftl::Optional(hwcVsyncPeriodIn).transform([](nsecs_t nanos) {
        return Period::fromNs(nanos);
    });
    return getVsyncSchedule(id)->addResyncSample(mSchedulerCallback, TimePoint::fromNs(timestamp),
    auto schedule = getVsyncSchedule(id);
    if (!schedule) {
        ALOGW("%s: Invalid display %s!", __func__, to_string(id).c_str());
        return false;
    }
    return schedule->addResyncSample(mSchedulerCallback, TimePoint::fromNs(timestamp),
                                     hwcVsyncPeriod);
}

void Scheduler::addPresentFence(PhysicalDisplayId id, std::shared_ptr<FenceTime> fence) {
    auto schedule = getVsyncSchedule(id);
    LOG_ALWAYS_FATAL_IF(!schedule);
    const bool needMoreSignals = schedule->getController().addPresentFence(std::move(fence));
    if (needMoreSignals) {
        schedule->enableHardwareVsync(mSchedulerCallback);
@@ -553,6 +567,7 @@ void Scheduler::setDisplayPowerMode(PhysicalDisplayId id, hal::PowerMode powerMo
    {
        std::scoped_lock lock(mDisplayLock);
        auto vsyncSchedule = getVsyncScheduleLocked(id);
        LOG_ALWAYS_FATAL_IF(!vsyncSchedule);
        vsyncSchedule->getController().setDisplayPowerMode(powerMode);
    }
    if (!isPacesetter) return;
@@ -582,7 +597,9 @@ auto Scheduler::getVsyncScheduleLocked(std::optional<PhysicalDisplayId> idOpt) c
    }

    const auto displayOpt = mDisplays.get(*idOpt);
    LOG_ALWAYS_FATAL_IF(!displayOpt);
    if (!displayOpt) {
        return nullptr;
    }
    return displayOpt->get().schedulePtr;
}

+4 −3
Original line number Diff line number Diff line
@@ -196,8 +196,8 @@ public:
    // Sets the render rate for the scheduler to run at.
    void setRenderRate(PhysicalDisplayId, Fps);

    void enableHardwareVsync(PhysicalDisplayId);
    void disableHardwareVsync(PhysicalDisplayId, bool disallow);
    void enableHardwareVsync(PhysicalDisplayId) REQUIRES(kMainThreadContext);
    void disableHardwareVsync(PhysicalDisplayId, bool disallow) REQUIRES(kMainThreadContext);

    // Resyncs the scheduler to hardware vsync.
    // If allowToEnable is true, then hardware vsync will be turned on.
@@ -219,7 +219,8 @@ public:
    // otherwise.
    bool addResyncSample(PhysicalDisplayId, nsecs_t timestamp,
                         std::optional<nsecs_t> hwcVsyncPeriod);
    void addPresentFence(PhysicalDisplayId, std::shared_ptr<FenceTime>) EXCLUDES(mDisplayLock);
    void addPresentFence(PhysicalDisplayId, std::shared_ptr<FenceTime>) EXCLUDES(mDisplayLock)
            REQUIRES(kMainThreadContext);

    // Layers are registered on creation, and unregistered when the weak reference expires.
    void registerLayer(Layer*);
+19 −8
Original line number Diff line number Diff line
@@ -1146,17 +1146,26 @@ status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& displayToken,
    std::optional<PhysicalDisplayId> displayIdOpt;
    {
        Mutex::Autolock lock(mStateLock);
        if (displayToken) {
            displayIdOpt = getPhysicalDisplayIdLocked(displayToken);
            if (!displayIdOpt) {
                ALOGW("%s: Invalid physical display token %p", __func__, displayToken.get());
                return NAME_NOT_FOUND;
            }

        } else {
            // TODO (b/277364366): Clients should be updated to pass in the display they
    // want, rather than us picking an arbitrary one (the pacesetter, in this
            // want, rather than us picking an arbitrary one (the active display, in this
            // case).
    if (displayToken && !displayIdOpt) {
        ALOGE("%s: Invalid physical display token %p", __func__, displayToken.get());
        return NAME_NOT_FOUND;
            displayIdOpt = mActiveDisplayId;
        }
    }

    const auto schedule = mScheduler->getVsyncSchedule(displayIdOpt);
    if (!schedule) {
        ALOGE("%s: Missing VSYNC schedule for display %s!", __func__,
              to_string(*displayIdOpt).c_str());
        return NAME_NOT_FOUND;
    }
    outStats->vsyncTime = schedule->vsyncDeadlineAfter(TimePoint::now()).ns();
    outStats->vsyncPeriod = schedule->period().ns();
    return NO_ERROR;
@@ -2136,7 +2145,9 @@ void SurfaceFlinger::setVsyncEnabled(PhysicalDisplayId id, bool enabled) {
    static_cast<void>(mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) {
        {
            ftl::FakeGuard guard(kMainThreadContext);
            mScheduler->getVsyncSchedule(id)->setPendingHardwareVsyncState(enabled);
            if (auto schedule = mScheduler->getVsyncSchedule(id)) {
                schedule->setPendingHardwareVsyncState(enabled);
            }
        }

        ATRACE_FORMAT("%s (%d) for %" PRIu64 " (main thread)", whence, enabled, id.value);
+1 −0
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@ cc_test {
        "SurfaceFlinger_DisplayTransactionCommitTest.cpp",
        "SurfaceFlinger_ExcludeDolbyVisionTest.cpp",
        "SurfaceFlinger_GetDisplayNativePrimariesTest.cpp",
        "SurfaceFlinger_GetDisplayStatsTest.cpp",
        "SurfaceFlinger_HdrOutputControlTest.cpp",
        "SurfaceFlinger_HotplugTest.cpp",
        "SurfaceFlinger_InitializeDisplaysTest.cpp",
+116 −0
Original line number Diff line number Diff line
/*
 * Copyright 2023 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.
 */

#undef LOG_TAG
#define LOG_TAG "SurfaceFlingerGetDisplayStatsTest"

#include <compositionengine/Display.h>
#include <compositionengine/mock/DisplaySurface.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <renderengine/mock/RenderEngine.h>
#include <ui/DisplayStatInfo.h>
#include "TestableSurfaceFlinger.h"
#include "mock/DisplayHardware/MockComposer.h"
#include "mock/DisplayHardware/MockPowerAdvisor.h"
#include "mock/MockTimeStats.h"
#include "mock/system/window/MockNativeWindow.h"

using namespace android;
using namespace testing;

namespace android {
namespace {
using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;

constexpr hal::HWDisplayId HWC_DISPLAY = FakeHwcDisplayInjector::DEFAULT_HWC_DISPLAY_ID;
constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(42u);
constexpr int DEFAULT_DISPLAY_WIDTH = 1920;
constexpr int DEFAULT_DISPLAY_HEIGHT = 1024;

class SurfaceFlingerGetDisplayStatsTest : public Test {
public:
    void SetUp() override;

protected:
    TestableSurfaceFlinger mFlinger;
    renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
    sp<DisplayDevice> mDisplay;
    sp<compositionengine::mock::DisplaySurface> mDisplaySurface =
            sp<compositionengine::mock::DisplaySurface>::make();
    sp<mock::NativeWindow> mNativeWindow = sp<mock::NativeWindow>::make();
    mock::TimeStats* mTimeStats = new mock::TimeStats();
    Hwc2::mock::PowerAdvisor* mPowerAdvisor = nullptr;
    Hwc2::mock::Composer* mComposer = nullptr;
};

void SurfaceFlingerGetDisplayStatsTest::SetUp() {
    mFlinger.setupMockScheduler({.displayId = DEFAULT_DISPLAY_ID});
    mComposer = new Hwc2::mock::Composer();
    mPowerAdvisor = new Hwc2::mock::PowerAdvisor();
    mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
    mFlinger.setupTimeStats(std::shared_ptr<TimeStats>(mTimeStats));
    mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
    mFlinger.setupPowerAdvisor(std::unique_ptr<Hwc2::PowerAdvisor>(mPowerAdvisor));
    static constexpr bool kIsPrimary = true;
    FakeHwcDisplayInjector(DEFAULT_DISPLAY_ID, hal::DisplayType::PHYSICAL, kIsPrimary)
            .setPowerMode(hal::PowerMode::ON)
            .inject(&mFlinger, mComposer);
    auto compostionEngineDisplayArgs =
            compositionengine::DisplayCreationArgsBuilder()
                    .setId(DEFAULT_DISPLAY_ID)
                    .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT})
                    .setPowerAdvisor(mPowerAdvisor)
                    .setName("injected display")
                    .build();
    auto compositionDisplay =
            compositionengine::impl::createDisplay(mFlinger.getCompositionEngine(),
                                                   std::move(compostionEngineDisplayArgs));
    mDisplay =
            FakeDisplayDeviceInjector(mFlinger, compositionDisplay,
                                      ui::DisplayConnectionType::Internal, HWC_DISPLAY, kIsPrimary)
                    .setDisplaySurface(mDisplaySurface)
                    .setNativeWindow(mNativeWindow)
                    .setPowerMode(hal::PowerMode::ON)
                    .setRefreshRateSelector(mFlinger.scheduler()->refreshRateSelector())
                    .skipRegisterDisplay()
                    .inject();
}

// TODO (b/277364366): Clients should be updated to pass in the display they want.
TEST_F(SurfaceFlingerGetDisplayStatsTest, nullptrSucceeds) {
    DisplayStatInfo info;
    status_t status = mFlinger.getDisplayStats(nullptr, &info);
    EXPECT_EQ(status, NO_ERROR);
}

TEST_F(SurfaceFlingerGetDisplayStatsTest, explicitToken) {
    DisplayStatInfo info;
    status_t status = mFlinger.getDisplayStats(mDisplay->getDisplayToken().promote(), &info);
    EXPECT_EQ(status, NO_ERROR);
}

TEST_F(SurfaceFlingerGetDisplayStatsTest, invalidToken) {
    const String8 displayName("fakeDisplay");
    sp<IBinder> displayToken = mFlinger.createDisplay(displayName, false);
    DisplayStatInfo info;
    status_t status = mFlinger.getDisplayStats(displayToken, &info);
    EXPECT_EQ(status, NAME_NOT_FOUND);
}

} // namespace
} // namespace android
Loading