From 409a7af450a6a692f649f23eafa067dbe7e3cf29 Mon Sep 17 00:00:00 2001 From: shegangbin Date: Wed, 20 Nov 2024 15:56:00 +0800 Subject: [PATCH 1/2] start vsync sample when idle callback Signed-off-by: shegangbin --- .../composer/hdi_backend/include/hdi_output.h | 1 - .../composer/hdi_backend/src/hdi_output.cpp | 29 ++++++++---------- .../test/unittest/hdioutput_test.cpp | 4 +-- .../composer/vsync/include/vsync_sampler.h | 7 +++++ .../composer/vsync/src/vsync_sampler.cpp | 30 +++++++++++++++++++ .../core/screen_manager/rs_screen_manager.cpp | 1 + 6 files changed, 52 insertions(+), 20 deletions(-) diff --git a/rosen/modules/composer/hdi_backend/include/hdi_output.h b/rosen/modules/composer/hdi_backend/include/hdi_output.h index 1ea86d9786..42f5f8783f 100644 --- a/rosen/modules/composer/hdi_backend/include/hdi_output.h +++ b/rosen/modules/composer/hdi_backend/include/hdi_output.h @@ -145,7 +145,6 @@ private: void ClearBufferCache(); std::map> GetLayersReleaseFenceLocked(); - std::atomic enableVsyncSample_ = true; }; } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/composer/hdi_backend/src/hdi_output.cpp b/rosen/modules/composer/hdi_backend/src/hdi_output.cpp index 003b079fbc..0999e4a19d 100644 --- a/rosen/modules/composer/hdi_backend/src/hdi_output.cpp +++ b/rosen/modules/composer/hdi_backend/src/hdi_output.cpp @@ -516,7 +516,7 @@ int32_t HdiOutput::UpdateInfosAfterCommit(sptr fbFence) int64_t timestamp = thirdFrameAheadPresentFence_->SyncFileReadTimestamp(); bool startSample = false; if (timestamp != SyncFence::FENCE_PENDING_TIMESTAMP) { - startSample = enableVsyncSample_.load() && sampler_->AddPresentFenceTime(timestamp); + startSample = sampler_->GetVsyncSamplerEnabled() && sampler_->AddPresentFenceTime(timestamp); RecordCompositionTime(timestamp); bool presentTimeUpdated = false; LayerPtr uniRenderLayer = nullptr; @@ -550,14 +550,18 @@ int32_t HdiOutput::UpdateInfosAfterCommit(sptr fbFence) void HdiOutput::SetVsyncSamplerEnabled(bool enabled) { - RS_TRACE_NAME_FMT("HdiOutput::SetVsyncSamplerEnabled, enableVsyncSample_:%d", enabled); - HLOGI("Change enableVsyncSample_, value is %{public}d", enabled); - enableVsyncSample_.store(enabled); + if (sampler_ == nullptr) { + sampler_ = CreateVSyncSampler(); + } + sampler_->SetVsyncSamplerEnabled(enabled); } bool HdiOutput::GetVsyncSamplerEnabled() { - return enableVsyncSample_.load(); + if (sampler_ == nullptr) { + sampler_ = CreateVSyncSampler(); + } + return sampler_->GetVsyncSamplerEnabled(); } int32_t HdiOutput::ReleaseFramebuffer(const sptr& releaseFence) @@ -688,23 +692,14 @@ std::map> HdiOutput::GetLayersReleaseFenceLocked() int32_t HdiOutput::StartVSyncSampler(bool forceReSample) { - ScopedBytrace func("HdiOutput::StartVSyncSampler, forceReSample:" + std::to_string(forceReSample)); - if (!enableVsyncSample_.load()) { - ScopedBytrace func("disabled vsyncSample"); - return GRAPHIC_DISPLAY_FAILURE; - } if (sampler_ == nullptr) { sampler_ = CreateVSyncSampler(); } - bool alreadyStartSample = sampler_->GetHardwareVSyncStatus(); - if (!forceReSample && alreadyStartSample) { - HLOGD("Already Start Sample."); + if (sampler_->StartSample(forceReSample) == VSYNC_ERROR_OK) { return GRAPHIC_DISPLAY_SUCCESS; + } else { + return GRAPHIC_DISPLAY_FAILURE; } - HLOGD("Enable Screen Vsync"); - sampler_->SetScreenVsyncEnabledInRSMainThread(true); - sampler_->BeginSample(); - return GRAPHIC_DISPLAY_SUCCESS; } void HdiOutput::SetPendingMode(int64_t period, int64_t timestamp) diff --git a/rosen/modules/composer/hdi_backend/test/unittest/hdioutput_test.cpp b/rosen/modules/composer/hdi_backend/test/unittest/hdioutput_test.cpp index 4e0406f8d9..2bf1731dc8 100644 --- a/rosen/modules/composer/hdi_backend/test/unittest/hdioutput_test.cpp +++ b/rosen/modules/composer/hdi_backend/test/unittest/hdioutput_test.cpp @@ -528,11 +528,11 @@ HWTEST_F(HdiOutputTest, GetBufferCacheSize001, Function | MediumTest | Level1) HWTEST_F(HdiOutputTest, StartVSyncSampler001, Function | MediumTest | Level1) { auto hdiOutput = HdiOutputTest::hdiOutput_; - hdiOutput->enableVsyncSample_.store(false); + hdiOutput->SetVsyncSamplerEnabled(false); int32_t res = hdiOutput->StartVSyncSampler(true); EXPECT_EQ(res, GRAPHIC_DISPLAY_FAILURE); - hdiOutput->enableVsyncSample_.store(true); + hdiOutput->SetVsyncSamplerEnabled(true); hdiOutput->sampler_ = nullptr; res = hdiOutput->StartVSyncSampler(false); EXPECT_EQ(res, GRAPHIC_DISPLAY_SUCCESS); diff --git a/rosen/modules/composer/vsync/include/vsync_sampler.h b/rosen/modules/composer/vsync/include/vsync_sampler.h index 2a1c3f9b4f..e947b7d19b 100644 --- a/rosen/modules/composer/vsync/include/vsync_sampler.h +++ b/rosen/modules/composer/vsync/include/vsync_sampler.h @@ -45,6 +45,9 @@ public: virtual void SetPendingPeriod(int64_t period) = 0; virtual void Dump(std::string &result) = 0; virtual void ClearAllSamples() = 0; + virtual void SetVsyncSamplerEnabled(bool enabled) = 0; + virtual bool GetVsyncSamplerEnabled() = 0; + virtual int32_t StartSample(bool forceReSample) = 0; protected: SetScreenVsyncEnabledCallback setScreenVsyncEnabledCallback_ = nullptr; }; @@ -74,6 +77,9 @@ public: virtual void SetPendingPeriod(int64_t period) override; virtual void Dump(std::string &result) override; virtual void ClearAllSamples() override; + virtual void SetVsyncSamplerEnabled(bool enabled) override; + virtual bool GetVsyncSamplerEnabled() override; + virtual int32_t StartSample(bool forceReSample) override; private: friend class OHOS::Rosen::VSyncSampler; @@ -111,6 +117,7 @@ private: static sptr instance_; bool hardwareVSyncStatus_ = true; int64_t pendingPeriod_ = 0; + std::atomic enableVsyncSample_ = true; }; } // impl } // namespace Rosen diff --git a/rosen/modules/composer/vsync/src/vsync_sampler.cpp b/rosen/modules/composer/vsync/src/vsync_sampler.cpp index 20d6a2b714..3ab075bbac 100644 --- a/rosen/modules/composer/vsync/src/vsync_sampler.cpp +++ b/rosen/modules/composer/vsync/src/vsync_sampler.cpp @@ -77,6 +77,36 @@ void VSyncSampler::ResetErrorLocked() } } +void VSyncSampler::SetVsyncSamplerEnabled(bool enabled) +{ + RS_TRACE_NAME_FMT("HdiOutput::SetVsyncSamplerEnabled, enableVsyncSample_:%d", enabled); + VLOGI("Change enableVsyncSample_, value is %{public}d", enabled); + enableVsyncSample_.store(enabled); +} + +bool VSyncSampler::GetVsyncSamplerEnabled() +{ + return enableVsyncSample_.load(); +} + +int32_t VSyncSampler::StartSample(bool forceReSample) +{ + RS_TRACE_NAME_FMT("HdiOutput::StartVSyncSampler, forceReSample:%d", forceReSample); + if (!enableVsyncSample_.load()) { + RS_TRACE_NAME_FMT("disabled vsyncSample"); + return VSYNC_ERROR_API_FAILED; + } + bool alreadyStartSample = GetHardwareVSyncStatus(); + if (!forceReSample && alreadyStartSample) { + VLOGD("Already Start Sample."); + return VSYNC_ERROR_OK; + } + VLOGD("Enable Screen Vsync"); + SetScreenVsyncEnabledInRSMainThread(true); + BeginSample(); + return VSYNC_ERROR_OK; +} + void VSyncSampler::BeginSample() { ScopedBytrace func("BeginSample"); diff --git a/rosen/modules/render_service/core/screen_manager/rs_screen_manager.cpp b/rosen/modules/render_service/core/screen_manager/rs_screen_manager.cpp index fe98506ea3..c3f615240a 100644 --- a/rosen/modules/render_service/core/screen_manager/rs_screen_manager.cpp +++ b/rosen/modules/render_service/core/screen_manager/rs_screen_manager.cpp @@ -422,6 +422,7 @@ void RSScreenManager::OnHwcDeadEvent() void RSScreenManager::OnScreenVBlankIdle(uint32_t devId, uint64_t ns, void *data) { + CreateVSyncSampler()->StartSample(true); RSScreenManager *screenManager = static_cast(RSScreenManager::GetInstance().GetRefPtr()); if (screenManager == nullptr) { RS_LOGE("RSScreenManager %{public}s: Failed to find RSScreenManager instance.", __func__); From 233c12358269b0784b5ce89fbcfb64b6a6bdde43 Mon Sep 17 00:00:00 2001 From: shegangbin Date: Thu, 21 Nov 2024 17:23:35 +0800 Subject: [PATCH 2/2] add vsync offset Signed-off-by: shegangbin --- .../composer/hdi_backend/test/unittest/BUILD.gn | 5 ++++- .../hdi_backend/test/unittest/hdibackend_test.cpp | 1 + .../hdi_backend/test/unittest/hdioutput_test.cpp | 4 ++-- .../composer/vsync/include/vsync_generator.h | 3 +++ .../composer/vsync/src/vsync_generator.cpp | 15 ++++++++++++++- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/rosen/modules/composer/hdi_backend/test/unittest/BUILD.gn b/rosen/modules/composer/hdi_backend/test/unittest/BUILD.gn index 3206b37659..e9425874ad 100644 --- a/rosen/modules/composer/hdi_backend/test/unittest/BUILD.gn +++ b/rosen/modules/composer/hdi_backend/test/unittest/BUILD.gn @@ -89,7 +89,10 @@ ohos_unittest("hdioutput_unit_test") { "mock_hdi_device.cpp", ] - deps = [ ":hdibackend_test_common" ] + deps = [ + ":hdibackend_test_common", + "../../../vsync:libvsync", + ] } ## UnitTest hdioutput_unit_test }}} diff --git a/rosen/modules/composer/hdi_backend/test/unittest/hdibackend_test.cpp b/rosen/modules/composer/hdi_backend/test/unittest/hdibackend_test.cpp index 912d85be73..5e41cdb03b 100644 --- a/rosen/modules/composer/hdi_backend/test/unittest/hdibackend_test.cpp +++ b/rosen/modules/composer/hdi_backend/test/unittest/hdibackend_test.cpp @@ -247,6 +247,7 @@ HWTEST_F(HdiBackendTest, StartSample001, Function | MediumTest | Level3) OutputPtr output = HdiOutput::CreateHdiOutput(0); hdiBackend_->SetPendingMode(output, 0, 0); output->sampler_->SetHardwareVSyncStatus(false); + output->sampler_->SetVsyncSamplerEnabled(true); hdiBackend_->StartSample(output); EXPECT_TRUE(output->sampler_->GetHardwareVSyncStatus()); } diff --git a/rosen/modules/composer/hdi_backend/test/unittest/hdioutput_test.cpp b/rosen/modules/composer/hdi_backend/test/unittest/hdioutput_test.cpp index 2bf1731dc8..72caaa433e 100644 --- a/rosen/modules/composer/hdi_backend/test/unittest/hdioutput_test.cpp +++ b/rosen/modules/composer/hdi_backend/test/unittest/hdioutput_test.cpp @@ -528,11 +528,11 @@ HWTEST_F(HdiOutputTest, GetBufferCacheSize001, Function | MediumTest | Level1) HWTEST_F(HdiOutputTest, StartVSyncSampler001, Function | MediumTest | Level1) { auto hdiOutput = HdiOutputTest::hdiOutput_; - hdiOutput->SetVsyncSamplerEnabled(false); + CreateVSyncSampler()->SetVsyncSamplerEnabled(false); int32_t res = hdiOutput->StartVSyncSampler(true); EXPECT_EQ(res, GRAPHIC_DISPLAY_FAILURE); - hdiOutput->SetVsyncSamplerEnabled(true); + CreateVSyncSampler()->SetVsyncSamplerEnabled(true); hdiOutput->sampler_ = nullptr; res = hdiOutput->StartVSyncSampler(false); EXPECT_EQ(res, GRAPHIC_DISPLAY_SUCCESS); diff --git a/rosen/modules/composer/vsync/include/vsync_generator.h b/rosen/modules/composer/vsync/include/vsync_generator.h index 61a472cf92..ea51383882 100644 --- a/rosen/modules/composer/vsync/include/vsync_generator.h +++ b/rosen/modules/composer/vsync/include/vsync_generator.h @@ -80,6 +80,7 @@ public: virtual void SetRSDistributor(sptr &rsVSyncDistributor) = 0; virtual void SetFrameRateChangingStatus(bool frameRateChanging) = 0; virtual void SetAppDistributor(sptr &appVSyncDistributor) = 0; + virtual int64_t GetVSyncOffset() = 0; }; sptr CreateVSyncGenerator(); @@ -122,6 +123,7 @@ public: void SetRSDistributor(sptr &rsVSyncDistributor) override; void SetFrameRateChangingStatus(bool frameRateChanging) override; void SetAppDistributor(sptr &appVSyncDistributor) override; + int64_t GetVSyncOffset() override; private: friend class OHOS::Rosen::VSyncGenerator; @@ -207,6 +209,7 @@ private: int64_t targetPeriod_ = 0; bool clearAllSamplesFlag_ = false; uint32_t vsyncMaxRefreshRate_ = 360; // default max TE + int64_t vsyncOffset_ = 0; }; } // impl } // namespace Rosen diff --git a/rosen/modules/composer/vsync/src/vsync_generator.cpp b/rosen/modules/composer/vsync/src/vsync_generator.cpp index 072cd755df..717e6afa09 100644 --- a/rosen/modules/composer/vsync/src/vsync_generator.cpp +++ b/rosen/modules/composer/vsync/src/vsync_generator.cpp @@ -90,8 +90,10 @@ uint32_t CalculateRefreshRate(int64_t period) } rateSections[] = { {30000000, 35000000, 30}, // 30000000ns, 35000000ns {15000000, 18000000, 60}, // 15000000ns, 18000000ns + {13000000, 15000000, 72}, // 13000000ns, 15000000ns {10000000, 12000000, 90}, // 10000000ns, 12000000ns - {7500000, 9000000, 120}}; // 7500000ns, 9000000ns + {7500000, 9000000, 120}, // 7500000ns, 9000000ns + {6000000, 7500000, 144}}; // 6000000ns, 7500000ns for (const auto& rateSection : rateSections) { if (period > rateSection.min && period < rateSection.max) { return rateSection.refreshRate; @@ -828,6 +830,12 @@ void VSyncGenerator::CalculateReferenceTimeOffsetPulseNumLocked(int64_t referenc startRefresh_, pendingPeriod_); } +int64_t VSyncGenerator::GetVSyncOffset() +{ + std::lock_guard locker(mutex_); + return vsyncOffset_; +} + VsyncError VSyncGenerator::CheckAndUpdateReferenceTime(int64_t hardwareVsyncInterval, int64_t referenceTime) { if (hardwareVsyncInterval < 0 || referenceTime < 0) { @@ -855,6 +863,11 @@ VsyncError VSyncGenerator::CheckAndUpdateReferenceTime(int64_t hardwareVsyncInte bool needNotify = true; uint32_t periodRefreshRate = CalculateRefreshRate(period_); uint32_t pendingPeriodRefreshRate = CalculateRefreshRate(pendingPeriod_); + if (pendingPeriodRefreshRate != 0) { + int32_t periodPulseNum = vsyncMaxRefreshRate_ / pendingPeriodRefreshRate; + vsyncOffset_ = (referenceTimeOffsetPulseNum_ % periodPulseNum) * pulse_; + RS_TRACE_NAME_FMT("vsyncOffset_:%ld", vsyncOffset_); + } // 120hz, 90hz, 60hz if (((periodRefreshRate == 120) || (periodRefreshRate == 90)) && (pendingPeriodRefreshRate == 60)) { needNotify = false;