diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..04efe2e0041cd5d32f032ea02cf6d90f3747bb9a --- /dev/null +++ b/README.md @@ -0,0 +1,90 @@ +# The Part of Frame Aware Sched + +- [ Introduction](#section_introduction) +- [ Directory Structure](#section_catalogue) +- [Framework](#section_framework) + - [The component of Frame Information Collection ](#section_collection) + - [The component of Frame Aware Policy](#section_policy) +- [ Usage Guidelines](#section_usage) +- [ Repositories Involved](#section_projects) + +## Introduction + +The part of Frame Aware Sched belongs to subsystem named *Resource Schedule Subsystem*. + +In order to ensure the cpu scheduling supply, it updates the process scheduling groups and adjust the kernel schedule parameters to influence the kernel scheduling behavior according to the information of the application frame drawing and the application life cycle status. + +## Directory Structure + +``` +//foundation/resourceschedule/frame_aware_sched +├── common # 部件通用工具类 +│ └── include +│ ├── frame_info_const.h # 绘帧过程信息 +│ ├── frame_aware_constants.h # 通用参数配置 +│ ├── frame_aware_log_domain.h # 封装hilog,用于日志打印 +│ └── single_instance.h # 封装了单例模式的类模板 +│ +├── interfaces +│ └── innerkits # 对内接口目录 +│ +├── frameworks +│ └── core +│ ├── frame_aware_collector # 应用绘帧信息收集组件 +│ └── frame_aware_policy # 帧感知调度机制组件 +│ +├── profiles # 组件配置文件 +└── test # 自测试用例目录 +``` +## Framework + +According to the thread it belongs to during execution, the *Farme Aware Sched* is devided into two parts, which are *Frame Aware Collector* and *Frame Aware Policy*. The framework is shown in the following picture. + +- *Frame Aware Collector*: which is the core strategy of drawing frames, including frame event processing module, slide scene strategy module, and model processing module. + + Module-frame event processing : responsible for coordinating and dispatching the message information of the frame drawing sub-process of the JS-UI subsystem and the Graphic subsystem. + + Module-slide scene strategy: responsible for the sliding scene recognize and provide the scenario-based fine scheduling by the interface of the model processing module. + + Module-model processing module: responsible for providing the adjustment and scheduling algorithm of each sub-process. + +- *Frame Aware Policy*: which is consists of four part: event processing module, application management module, and RTG (Related-Thread-Group) management module and scheduling parameter control module. + + Module-Application state event processing: which is responsible for registering and receiving messages from the global resource management and control subsystem, such as application state switch, window focus state change, etc, and distributing messages to the application management and control module and RTG grouping module. + + Module-Application management: responsible for the unified management of the application messages of the event processing module. + + Module-RTG Managerment: the kernel interface set, sets the RTG accoding to the application state to realize thread scheduling management. + + Module-Scheduling Parameter Control:responsible for reading the default scheduling prameter configuration. + +![](figures/zh-cn_image_fwk.png) + +### The component of Frame Information Collection + +The *frame information collection* is mainly responsible for adjusting the parameters of kernel scheduling and scaling the thread load. When the user slides on the application, it recognizes the key threads (such as draw frame thread and render thread) , perceives the sub-process of the application frame drawing, and adjust the kernel scheduling parameters according to the task timeout status to perform real-time resources. + +- According to the screen refresh rate, it analyze the current frame rate information. The resource supply of key threads is increased according to the time to end of the drawing frame. +- Adjust resource supply according to the duration of each sub-process during graphics rendering process. +- Adjust resource supply for frame sub-process task with high frame loss rate. + +### The component of Frame Aware Policy + +As the basis for the realization of application frame perception, the *frame aware policy* is mainly reposible for controlling thread groups and thread priorities, realizing the unified management of application threads and ensuring the performance of the entire system. + +### Usage Guidelines + +System developers can add or remove this part by configuring the product definition JSON file under **/productdefine/common/products** to enable or disable this part: + +` "resourceschedule:frame_aware_sched":{} ` + +## Repositories Involved + +- [resource_schedule_service](https://gitee.com/openharmony/resourceschedule_resource_schedule_service) +- [ace_ace_engine]( https://gitee.com/openharmony/ace_ace_engine) +- [graphic_standard](https://gitee.com/openharmony/graphic_standard) +- [aafwk_standard](https://gitee.com/openharmony/aafwk_standard ) +- **frame_aware_sched** + + + diff --git a/README_ZH.md b/README_ZH.md index c092e6c91f7bd20ad76802a38b007465f655a7c9..3407d7e84c2305d8916c19e0db534106479af3db 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -11,7 +11,7 @@ ## 目录 ``` -//foundation/resourceschedule/plugins/frame_aware_sched +//foundation/resourceschedule/frame_aware_sched ├── common # 部件通用工具类 │ └── include │ ├── frame_info_const.h # 绘帧过程信息 diff --git a/common/include/single_instance.h b/common/include/single_instance.h index 087f4a2140cddeac23e01757b93d4ddbf14ca7a9..a586551ee963e4b937ff21a93ad49558829446bd 100644 --- a/common/include/single_instance.h +++ b/common/include/single_instance.h @@ -18,7 +18,6 @@ namespace OHOS { namespace RME { - #define DECLARE_SINGLE_INSTANCE_BASE(className) \ public: \ static className& GetInstance(); \ @@ -28,13 +27,11 @@ private: \ className(className&&) = delete; \ className& operator=(className&&) = delete; \ - -#define DECLARE_SINGLE_INSTANCE(className) \ - DECLARE_SINGLE_INSTANCE_BASE(className) \ -private: \ - className() = default; \ - ~className() = default; \ - +#define DECLARE_SINGLE_INSTANCE(className) \ + DECLARE_SINGLE_INSTANCE_BASE(className) \ +private: \ + className() = default; \ + ~className() = default; \ #define IMPLEMENT_SINGLE_INSTANCE(className) \ className& className::GetInstance() \ diff --git a/frameworks/core/frame_aware_policy/include/intellisense_server.h b/frameworks/core/frame_aware_policy/include/intellisense_server.h index 6d55c0f5b158e7c6f34ad7af6c822d11c4205688..79e1bbe1e7364393a1409557804ad3f9dac35372 100644 --- a/frameworks/core/frame_aware_policy/include/intellisense_server.h +++ b/frameworks/core/frame_aware_policy/include/intellisense_server.h @@ -48,6 +48,7 @@ private: std::vector m_renderTypeList {}; bool m_readXmlSuc = false; bool m_needReadXml = true; + bool m_switch = false; }; } // namespace RME } // namesapce OHOS diff --git a/frameworks/core/frame_aware_policy/src/app_info_mgr.cpp b/frameworks/core/frame_aware_policy/src/app_info_mgr.cpp index cd0821ea2dda697072bcdf858e42f12de1ad8497..3fc6dc43c1b06ab4da34efb24be086bf3eb40a2f 100644 --- a/frameworks/core/frame_aware_policy/src/app_info_mgr.cpp +++ b/frameworks/core/frame_aware_policy/src/app_info_mgr.cpp @@ -49,7 +49,9 @@ void AppInfoMgr::OnBackgroundChanged(const int pid, const std::string appName) mBackgroundAppList[pid] = mForegroundAppList[pid]; mForegroundAppList.erase(pid); } else { - RME_LOGE("[OnBackgroundChanged]:unfind app in foreground app when go to background! pid:%{public}d", pid); + RME_LOGI("[OnBackgroundChanged]: fore No! pid:%{public}d", pid); + auto appInfo = std::make_shared(appName, pid, INIT_VAL, INIT_VAL, INIT_VAL, AppState::APP_BACKGROUND); + mBackgroundAppList[pid] = appInfo; } mBackgroundAppList[pid]->SetRtgrp(INIT_VAL); RME_LOGI("[OnBackgroundChanged]:pid:%{public}d, appName:%{public}s", pid, appName.c_str()); diff --git a/frameworks/core/frame_aware_policy/src/intellisense_server.cpp b/frameworks/core/frame_aware_policy/src/intellisense_server.cpp index 3abc88aa7a31fed25d2accf614327a4f12ebfb18..f7335dea5c45a49b87bc83def3b6cf7d55dfb025 100644 --- a/frameworks/core/frame_aware_policy/src/intellisense_server.cpp +++ b/frameworks/core/frame_aware_policy/src/intellisense_server.cpp @@ -35,6 +35,15 @@ IMPLEMENT_SINGLE_INSTANCE(IntelliSenseServer); void IntelliSenseServer::Init() { + if (!ReadXml()) { + RME_LOGI("[Init]: readXml failed!"); + return; + } + m_switch = std::stoi(m_generalPara["enable"]); + if (!m_switch) { + RME_LOGI("[Init]:xml switch close!"); + return; + } RtgMsgMgr::GetInstance().Init(); RME_LOGI("[Init]:Init rtg and readXml finish!"); } @@ -51,9 +60,9 @@ bool IntelliSenseServer::ReadXml() m_fpsList = ParaConfig::GetFpsList(); m_renderTypeList = ParaConfig::GetRenderTypeList(); if (!m_generalPara.empty() && !m_subEventPara.empty() && !m_fpsList.empty() && !m_renderTypeList.empty()) { - m_readXmlSuc = true; - RME_LOGI("[ReadXml]: read slide scene xml success!"); - return true; + m_readXmlSuc = true; + RME_LOGI("[ReadXml]: read slide scene xml success!"); + return true; } } RME_LOGE("[ReadXml]: read slide scene xml not success!"); @@ -63,6 +72,9 @@ bool IntelliSenseServer::ReadXml() void IntelliSenseServer::ReportMessage(std::string appName, std::string processName, int pid, AppStateUpdateReason reason) { + if (!m_switch) { + return; + } RME_FUNCTION_TRACE(); int rtGrp = AppInfoMgr::GetInstance().GetAppRtgrp(pid); switch (reason) { @@ -96,6 +108,9 @@ void IntelliSenseServer::ReportMessage(std::string appName, std::string processN void IntelliSenseServer::ReportWindowFocus(const int pid, int isFocus) { + if (!m_switch) { + return; + } RME_FUNCTION_TRACE(); int rtGrp = AppInfoMgr::GetInstance().GetAppRtgrp(pid); switch (isFocus) { @@ -123,6 +138,9 @@ void IntelliSenseServer::ReportWindowFocus(const int pid, int isFocus) void IntelliSenseServer::ReportProcessInfo(const int pid, const int tid, ThreadState state) { + if (!m_switch) { + return; + } RME_FUNCTION_TRACE(); switch (state) { case ThreadState::DIED: @@ -151,6 +169,9 @@ void IntelliSenseServer::ReportProcessInfo(const int pid, const int tid, ThreadS void IntelliSenseServer::SetPara(const int32_t currentFps, const int32_t currentRenderType) { + if (!m_switch) { + return; + } RME_LOGI("[SetPara]:ioctl SetPara!\n"); std::string key = std::to_string(currentRenderType) + " " + std::to_string(currentFps); map tempMap = m_subEventPara[key]; diff --git a/frameworks/core/frame_aware_policy/src/para_config.cpp b/frameworks/core/frame_aware_policy/src/para_config.cpp index 1ac54cc89ee2bd3aed64b1849752cf25986c89a3..a08687255a1ffd7f83d151d81a0f826fd34ffb4b 100644 --- a/frameworks/core/frame_aware_policy/src/para_config.cpp +++ b/frameworks/core/frame_aware_policy/src/para_config.cpp @@ -31,7 +31,6 @@ std::vector ParaConfig::m_renderTypeList; bool ParaConfig::IsXmlPrepared(const std::string& filePath) { - RME_LOGI("[IsXmlPrepared]:begin!"); xmlDocPtr docPtr = xmlReadFile(filePath.c_str(), nullptr, XML_PARSE_NOBLANKS); RME_LOGI("[IsXmlPrepared]:filePath:%{public}s", filePath.c_str()); if (docPtr == nullptr) { @@ -50,12 +49,12 @@ bool ParaConfig::IsXmlPrepared(const std::string& filePath) RME_LOGE("[IsXmlPrepared]: invalid node!"); continue; } - auto nodeName = curNodePtr->name; // char* to string + auto nodeName = curNodePtr->name; if (!xmlStrcmp(nodeName, reinterpret_cast("log_open")) || !xmlStrcmp(nodeName, reinterpret_cast("enable")) || !xmlStrcmp(nodeName, reinterpret_cast("SOC")) || !xmlStrcmp(nodeName, reinterpret_cast("frame_sched_reset_count"))) { - ReadConfigInfo(curNodePtr); // is this transform ok? + ReadConfigInfo(curNodePtr); continue; } if (!xmlStrcmp(nodeName, reinterpret_cast("fps_list"))) { @@ -63,7 +62,7 @@ bool ParaConfig::IsXmlPrepared(const std::string& filePath) continue; } if (!xmlStrcmp(nodeName, reinterpret_cast("render_type"))) { - ReadFpsConfig(curNodePtr); + ReadRenderType(curNodePtr); continue; } if (!xmlStrcmp(nodeName, reinterpret_cast("framedetect"))) { @@ -131,14 +130,16 @@ void ParaConfig::SplitString(const std::string& context, const std::string& char while (pos != toSplitStr.npos) { int curVal = atoi(toSplitStr.substr(0, pos).c_str()); - if (curVal <= 0 && curVal > maxVal) { - RME_LOGI("[SplitString]:get data error! attr name:%{public}s", attrName.c_str()); - return; + if (curVal <= 0 && curVal > maxVal) { + RME_LOGE("[SplitString]:get data error! attr name:%{public}s", attrName.c_str()); + return; + } + mList.push_back(curVal); + toSplitStr = toSplitStr.substr(pos + 1, toSplitStr.size()); + pos = toSplitStr.find(character); } - mList.push_back(curVal); - - toSplitStr = toSplitStr.substr(pos + 1, toSplitStr.size()); - pos = toSplitStr.find(character); + for (auto m : mList) { + RME_LOGI("[SplitString]: attrName: %{public}s, list_val:%{public}d", attrName.c_str(), m); } RME_LOGI("[SplitString]:get data success!attr name:%{public}s", attrName.c_str()); } @@ -153,10 +154,10 @@ void ParaConfig::ReadFrameConfig(const xmlNodePtr& root) } std::string key1 = ""; std::string key2 = ""; - ReadAttr(curNode, "renderType", key1); + ReadAttr(curNode, "render_type", key1); ReadAttr(curNode, "fps_list", key2); std::string key = key1 + " " + key2; - + RME_LOGI("ReadFrameConfig-key:%{public}s", key.c_str()); std::map frameConfigTmp; xmlNodePtr curSubNode = curNode->xmlChildrenNode; for (; curSubNode != nullptr; curSubNode = curSubNode->next) { @@ -180,13 +181,16 @@ void ParaConfig::ReadFrameConfig(const xmlNodePtr& root) void ParaConfig::ReadAttr(xmlNodePtr& root, const std::string& attrName, std::string& res) { - xmlChar* attr = xmlGetProp(root, reinterpret_cast(attrName.c_str())); - if (attr == nullptr) { - RME_LOGE("[ReadAttr]: attr <%{public}s> read error!", attrName.c_str()); + xmlAttrPtr attrPtr = root->properties; + while (attrPtr != nullptr) { + if (!xmlStrcmp(attrPtr->name, reinterpret_cast(attrName.c_str()))) { + xmlChar* resAttr = xmlGetProp(root, reinterpret_cast(attrName.c_str())); + res = std::to_string(atoi((char*)resAttr)); + RME_LOGI("[ReadAttr]: attr <%{public}s> read res: %{public}s!", attrName.c_str(), res.c_str()); + xmlFree(resAttr); + } + attrPtr = attrPtr->next; } - const char* tmp = reinterpret_cast(attr); // char* to string - res = tmp; - xmlFree(attr); } std::map ParaConfig::GetGeneralConfig() diff --git a/interfaces/innerkits/frameintf/frame_msg_intf.cpp b/interfaces/innerkits/frameintf/frame_msg_intf.cpp index b827b835a4367199c8a98fbb18a3c45cd24be340..70e2feea0fa420ef09767e44bb7bfd87c2219773 100644 --- a/interfaces/innerkits/frameintf/frame_msg_intf.cpp +++ b/interfaces/innerkits/frameintf/frame_msg_intf.cpp @@ -30,6 +30,7 @@ FrameMsgIntf& FrameMsgIntf::GetInstance() bool FrameMsgIntf::Init() { + std::lock_guard autoLock(frameMsgIntfMutex_); RME_LOGI("init begin!"); if (!GetThreadHandler()) { return false; @@ -43,9 +44,14 @@ bool FrameMsgIntf::Init() bool FrameMsgIntf::GetThreadHandler() { if (threadHandler_ == nullptr) { - threadHandler_ = std::make_shared(AppExecFwk::EventRunner::Create()); + runner_ = AppExecFwk::EventRunner::Create("frame_aware_sched_msg"); + if (runner_ == nullptr) { + RME_LOGE("failed to create eventRunner!"); + return false; + } + threadHandler_ = std::make_shared(runner_); if (threadHandler_ == nullptr) { - RME_LOGI("failed to create thread handler!"); + RME_LOGE("failed to create thread handler!"); return false; } } @@ -56,6 +62,7 @@ bool FrameMsgIntf::GetThreadHandler() void FrameMsgIntf::ReportAppInfo(std::string appName, std::string processName, int pid, AppStateUpdateReason reason) { + std::lock_guard autoLock(frameMsgIntfMutex_); if (threadHandler_ == nullptr) { RME_LOGI("[ReportAppInfo]:threandHandler none!"); return; @@ -67,8 +74,9 @@ void FrameMsgIntf::ReportAppInfo(std::string appName, std::string processName, i void FrameMsgIntf::ReportWindowFocus(const int pid, const int isFocus) { + std::lock_guard autoLock(frameMsgIntfMutex_); if (threadHandler_ == nullptr) { - RME_LOGI("[ReportWindowFocus]:threandHandler none!"); + RME_LOGE("[ReportWindowFocus]:threandHandler none!"); return; } threadHandler_->PostTask([pid, isFocus] { @@ -78,8 +86,9 @@ void FrameMsgIntf::ReportWindowFocus(const int pid, const int isFocus) void FrameMsgIntf::ReportProcessInfo(const int pid, const int tid, ThreadState state) { + std::lock_guard autoLock(frameMsgIntfMutex_); if (threadHandler_ == nullptr) { - RME_LOGI("[ReportWindowFocus]:threandHandler none!"); + RME_LOGI("[ReportProcessInfo]:threandHandler none!"); return; } threadHandler_->PostTask([pid, tid, state] { @@ -89,10 +98,15 @@ void FrameMsgIntf::ReportProcessInfo(const int pid, const int tid, ThreadState s void FrameMsgIntf::Stop() { + std::lock_guard autoLock(frameMsgIntfMutex_); if (threadHandler_ != nullptr) { threadHandler_->RemoveAllEvents(); threadHandler_ = nullptr; } + if (runner_ != nullptr) { + runner_->Stop(); + runner_ = nullptr; + } RME_LOGI("stop eventRunner success!"); } } // namespace RME diff --git a/interfaces/innerkits/frameintf/frame_msg_intf.h b/interfaces/innerkits/frameintf/frame_msg_intf.h index a417fa35f0cf764552bc1dc57f1339607a95a8a6..3f60508df1105258d89ce8e91ff0dff463c2f3b6 100644 --- a/interfaces/innerkits/frameintf/frame_msg_intf.h +++ b/interfaces/innerkits/frameintf/frame_msg_intf.h @@ -34,8 +34,10 @@ public: protected: FrameMsgIntf() = default; virtual ~FrameMsgIntf() = default; - std::shared_ptr threadHandler_; private: + std::mutex frameMsgIntfMutex_; + std::shared_ptr runner_; + std::shared_ptr threadHandler_; DISALLOW_COPY_AND_MOVE(FrameMsgIntf); }; } // namespace RME diff --git a/profiles/hwrme.xml b/profiles/hwrme.xml index a41326e2215def1ff6c36db526ee4ebf14bef1db..4398e58e83fabe721ff5cb468d11c575c5d46bdc 100644 --- a/profiles/hwrme.xml +++ b/profiles/hwrme.xml @@ -21,7 +21,7 @@ 60 90 0 1 2 - + 600