diff --git a/rosen/modules/composer/hdi_backend/include/hdi_layer.h b/rosen/modules/composer/hdi_backend/include/hdi_layer.h index adc869fb81..611e474014 100644 --- a/rosen/modules/composer/hdi_backend/include/hdi_layer.h +++ b/rosen/modules/composer/hdi_backend/include/hdi_layer.h @@ -34,6 +34,8 @@ public: explicit HdiLayer(uint32_t screenId); virtual ~HdiLayer(); + static constexpr int FRAME_RECORDS_NUM = 128; + /* output create and set layer info */ static std::shared_ptr CreateHdiLayer(uint32_t screenId); @@ -49,6 +51,8 @@ public: void UpdateLayerInfo(const LayerInfoPtr &layerInfo); void SetHdiLayerInfo(); uint32_t GetLayerId() const; + void RecordPresentTime(const sptr &fbFence); + void Dump(std::string &result); int32_t SetLayerColorTransform(const float *matrix) const; int32_t SetLayerColorDataSpace(ColorDataSpace colorSpace) const; @@ -67,6 +71,13 @@ private: sptr releaseFence_ = SyncFence::INVALID_FENCE; }; + struct PresentTimeRecord { + int64_t presentTime = 0; + sptr presentFence = SyncFence::INVALID_FENCE; + }; + + PresentTimeRecord presentTimeRecords[FRAME_RECORDS_NUM]; + uint32_t count = 0; uint32_t screenId_ = INT_MAX; uint32_t layerId_ = INT_MAX; bool isInUsing_ = false; diff --git a/rosen/modules/composer/hdi_backend/include/hdi_output.h b/rosen/modules/composer/hdi_backend/include/hdi_output.h index c9ba5c313a..a48201e38a 100644 --- a/rosen/modules/composer/hdi_backend/include/hdi_output.h +++ b/rosen/modules/composer/hdi_backend/include/hdi_output.h @@ -52,6 +52,7 @@ public: int32_t ReleaseFramebuffer(const sptr &releaseFence); void FramebufferSemWait(); void Dump(std::string &result) const; + void DumpFps(std::string &result, const std::string &arg) const; private: sptr fbSurface_ = nullptr; diff --git a/rosen/modules/composer/hdi_backend/src/hdi_backend.cpp b/rosen/modules/composer/hdi_backend/src/hdi_backend.cpp index 1b0ce71597..fd8b4c5b8a 100644 --- a/rosen/modules/composer/hdi_backend/src/hdi_backend.cpp +++ b/rosen/modules/composer/hdi_backend/src/hdi_backend.cpp @@ -122,6 +122,11 @@ void HdiBackend::Repaint(std::vector &outputs) // return } + for (auto iter = layersMap.begin(); iter != layersMap.end(); ++iter) { + const LayerPtr &layer = iter->second; + layer->RecordPresentTime(fbFence); + } + ReleaseLayerBuffer(screenId, layersMap); // wrong check diff --git a/rosen/modules/composer/hdi_backend/src/hdi_layer.cpp b/rosen/modules/composer/hdi_backend/src/hdi_layer.cpp index a244c44873..c482ebad87 100644 --- a/rosen/modules/composer/hdi_backend/src/hdi_layer.cpp +++ b/rosen/modules/composer/hdi_backend/src/hdi_layer.cpp @@ -279,6 +279,14 @@ SurfaceError HdiLayer::ReleasePrevBuffer() return ret; } +void HdiLayer::RecordPresentTime(const sptr &fbFence) +{ + if (currSbuffer_->sbuffer_ != prevSbuffer_->sbuffer_) { + presentTimeRecords[count].presentFence = fbFence; + count = (count + 1) % FRAME_RECORDS_NUM; + } +} + void HdiLayer::MergeWithFramebufferFence(const sptr &fbAcquireFence) { if (fbAcquireFence != nullptr) { @@ -315,5 +323,16 @@ void HdiLayer::CheckRet(int32_t ret, const char* func) } } +void HdiLayer::Dump(std::string &result) +{ + for (int i = 0; i < FRAME_RECORDS_NUM; i++) { + if (presentTimeRecords[i].presentFence != SyncFence::INVALID_FENCE) { + presentTimeRecords[i].presentTime = presentTimeRecords[i].presentFence->SyncFileReadTimestamp(); + presentTimeRecords[i].presentFence = SyncFence::INVALID_FENCE; + } + result += std::to_string(presentTimeRecords[i].presentTime) + "\n"; + } +} + } // 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 925530165b..94ba87cdd5 100644 --- a/rosen/modules/composer/hdi_backend/src/hdi_output.cpp +++ b/rosen/modules/composer/hdi_backend/src/hdi_output.cpp @@ -206,10 +206,27 @@ void HdiOutput::Dump(std::string &result) const for (auto iter = surfaceIdMap_.begin(); iter != surfaceIdMap_.end(); ++iter) { iter->second->SetLayerStatus(false); const LayerPtr &layer = iter->second; + std::string name; + layer->GetLayerInfo()->GetSurface()->GetName(name); const LayerInfoPtr &info = layer->GetLayerInfo(); - result += " surfaceId[" + std::to_string(iter->first) + "]:\n"; + result += " surface [" + name + "] Id[" + std::to_string(iter->first) + "]:\n"; info->Dump(result); } } + +void HdiOutput::DumpFps(std::string &result, const std::string &arg) const +{ + result.append("\n"); + for (auto iter = surfaceIdMap_.begin(); iter != surfaceIdMap_.end(); ++iter) { + iter->second->SetLayerStatus(false); + const LayerPtr &layer = iter->second; + std::string name; + layer->GetLayerInfo()->GetSurface()->GetName(name); + if (name == arg) { + result += " surface [" + name + "] Id[" + std::to_string(iter->first) + "]:\n"; + layer->Dump(result); + } + } +} } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service/core/pipeline/rs_render_service.cpp b/rosen/modules/render_service/core/pipeline/rs_render_service.cpp index 974617399b..07e3c35a23 100644 --- a/rosen/modules/render_service/core/pipeline/rs_render_service.cpp +++ b/rosen/modules/render_service/core/pipeline/rs_render_service.cpp @@ -107,10 +107,12 @@ int RSRenderService::Dump(int fd, const std::vector& args) std::unordered_set argSets; std::u16string arg1(u"display"); std::u16string arg2(u"surface"); + std::u16string arg3(u"fps"); for (decltype(args.size()) index = 0; index < args.size(); ++index) { argSets.insert(args[index]); } std::string dumpString; + std::string layerArg; if (screenManager_ == nullptr) { return OHOS::INVALID_OPERATION; } @@ -122,6 +124,16 @@ int RSRenderService::Dump(int fd, const std::vector& args) return screenManager_->SurfaceDump(dumpString); }).wait(); } + auto iter = argSets.find(arg3); + if (iter != argSets.end()) { + argSets.erase(iter); + if (!argSets.empty()) { + layerArg = std::wstring_convert, char16_t> {}.to_bytes(*argSets.begin()); + } + mainThread_->ScheduleTask([this, &dumpString, &layerArg]() { + return screenManager_->FpsDump(dumpString, layerArg); + }).wait(); + } if (dumpString.size() == 0) { return OHOS::INVALID_OPERATION; } diff --git a/rosen/modules/render_service/core/screen_manager/rs_screen.cpp b/rosen/modules/render_service/core/screen_manager/rs_screen.cpp index 5d14791adb..a3f8568ba6 100644 --- a/rosen/modules/render_service/core/screen_manager/rs_screen.cpp +++ b/rosen/modules/render_service/core/screen_manager/rs_screen.cpp @@ -349,6 +349,14 @@ void RSScreen::SurfaceDump(int32_t screenIndex, std::string& dumpString) hdiOutput_->Dump(dumpString); } +void RSScreen::FpsDump(int32_t screenIndex, std::string& dumpString, std::string& arg) +{ + if (hdiOutput_ == nullptr) { + return; + } + hdiOutput_->DumpFps(dumpString, arg); +} + void RSScreen::SetScreenBacklight(uint32_t level) { if (hdiScreen_->SetScreenBacklight(level) < 0) { diff --git a/rosen/modules/render_service/core/screen_manager/rs_screen.h b/rosen/modules/render_service/core/screen_manager/rs_screen.h index 86f1c57b4f..864feb6c08 100644 --- a/rosen/modules/render_service/core/screen_manager/rs_screen.h +++ b/rosen/modules/render_service/core/screen_manager/rs_screen.h @@ -61,6 +61,7 @@ public: virtual void SetProducerSurface(sptr producerSurface) = 0; virtual void DisplayDump(int32_t screenIndex, std::string& dumpString) = 0; virtual void SurfaceDump(int32_t screenIndex, std::string& dumpString) = 0; + virtual void FpsDump(int32_t screenIndex, std::string& dumpString, std::string& arg) = 0; virtual void SetScreenBacklight(uint32_t level) = 0; virtual int32_t GetScreenBacklight() const = 0; virtual int32_t GetScreenSupportedColorGamuts(std::vector &mode) const = 0; @@ -105,6 +106,7 @@ public: void SetProducerSurface(sptr producerSurface) override; void DisplayDump(int32_t screenIndex, std::string& dumpString) override; void SurfaceDump(int32_t screenIndex, std::string& dumpString) override; + void FpsDump(int32_t screenIndex, std::string& dumpString, std::string& arg) override; void SetScreenBacklight(uint32_t level) override; int32_t GetScreenBacklight() const override; int32_t GetScreenSupportedColorGamuts(std::vector &mode) const override; 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 849ec296bf..172758d136 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 @@ -591,6 +591,15 @@ void RSScreenManager::SurfaceDump(std::string& dumpString) } } +void RSScreenManager::FpsDump(std::string& dumpString, std::string& arg) +{ + int32_t index = 0; + for (const auto &[id, screen] : screens_) { + screen->FpsDump(index, dumpString, arg); + index++; + } +} + int32_t RSScreenManager::GetScreenSupportedColorGamutsLocked(ScreenId id, std::vector& mode) const { if (screens_.count(id) == 0) { diff --git a/rosen/modules/render_service/core/screen_manager/rs_screen_manager.h b/rosen/modules/render_service/core/screen_manager/rs_screen_manager.h index 7476006852..be54ed9d2b 100644 --- a/rosen/modules/render_service/core/screen_manager/rs_screen_manager.h +++ b/rosen/modules/render_service/core/screen_manager/rs_screen_manager.h @@ -109,6 +109,8 @@ public: virtual void SurfaceDump(std::string& dumpString) = 0; + virtual void FpsDump(std::string& dumpString, std::string& arg) = 0; + virtual int32_t GetScreenBacklight(ScreenId id) = 0; virtual void SetScreenBacklight(ScreenId id, uint32_t level) = 0; @@ -197,6 +199,8 @@ public: void SurfaceDump(std::string& dumpString) override; + void FpsDump(std::string& dumpString, std::string& arg) override; + int32_t GetScreenBacklight(ScreenId id) override; void SetScreenBacklight(ScreenId id, uint32_t level) override;