1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "base/log/ace_performance_monitor.h"
17
18 #include "base/json/json_util.h"
19 #include "base/log/ace_trace.h"
20
21 namespace OHOS::Ace {
22 using namespace std;
23 using namespace std::chrono;
24 namespace {
GetTimePoint(TimePoint & now)25 void GetTimePoint(TimePoint& now)
26 {
27 if (SystemProperties::GetAcePerformanceMonitorEnabled()) {
28 now = steady_clock::now();
29 }
30 }
31 } // namespace
32
ScopedMonitor(MonitorTag tag)33 ScopedMonitor::ScopedMonitor(MonitorTag tag) : tag_(tag)
34 {
35 GetTimePoint(begin_);
36 ArkUIPerfMonitor::GetInstance().SetRecordingStatus(tag_, MonitorStatus::RUNNING);
37 }
38
~ScopedMonitor()39 ScopedMonitor::~ScopedMonitor()
40 {
41 GetTimePoint(end_);
42 ArkUIPerfMonitor::GetInstance().RecordTimeSlice(tag_, duration_cast<nanoseconds>(end_ - begin_).count());
43 }
44
GetInstance()45 ArkUIPerfMonitor& ArkUIPerfMonitor::GetInstance()
46 {
47 static ArkUIPerfMonitor instance;
48 return instance;
49 }
50
ArkUIPerfMonitor()51 ArkUIPerfMonitor::ArkUIPerfMonitor()
52 {
53 InitPerfMonitor();
54 }
55
StartPerf()56 void ArkUIPerfMonitor::StartPerf()
57 {
58 GetTimePoint(begin_);
59 ClearPerfMonitor();
60 }
61
FinishPerf()62 void ArkUIPerfMonitor::FinishPerf()
63 {
64 GetTimePoint(end_);
65 FlushPerfMonitor();
66 ClearPerfMonitor();
67 }
68
RecordTimeSlice(MonitorTag tag,int64_t duration)69 void ArkUIPerfMonitor::RecordTimeSlice(MonitorTag tag, int64_t duration)
70 {
71 SetRecordingStatus(tag, MonitorStatus::IDLE);
72 if (tag == MonitorTag::STATIC_API) {
73 propertyNum_++;
74 if (!monitorStatus_) {
75 return;
76 }
77 timeSlice_[tag] += duration;
78 return;
79 }
80 if (monitorStatus_ == 0) {
81 timeSlice_[tag] += duration;
82 }
83 }
84
RecordStateMgmtNode(int64_t num)85 void ArkUIPerfMonitor::RecordStateMgmtNode(int64_t num)
86 {
87 stateMgmtNodeNum_ += num;
88 }
89
RecordLayoutNode(int64_t num)90 void ArkUIPerfMonitor::RecordLayoutNode(int64_t num)
91 {
92 layoutNodeNum_ += num;
93 }
94
RecordRenderNode(int64_t num)95 void ArkUIPerfMonitor::RecordRenderNode(int64_t num)
96 {
97 renderNodeNum_ += num;
98 }
99
RecordDisplaySyncRate(int32_t displaySyncRate)100 void ArkUIPerfMonitor::RecordDisplaySyncRate(int32_t displaySyncRate)
101 {
102 displaySyncRate_ = displaySyncRate;
103 }
104
SetRecordingStatus(MonitorTag tag,MonitorStatus status)105 void ArkUIPerfMonitor::SetRecordingStatus(MonitorTag tag, MonitorStatus status)
106 {
107 if (tag == MonitorTag::STATIC_API) {
108 return;
109 }
110 switch (status) {
111 case MonitorStatus::RUNNING:
112 ++monitorStatus_;
113 break;
114 case MonitorStatus::IDLE:
115 --monitorStatus_;
116 break;
117 }
118 }
119
InitPerfMonitor()120 void ArkUIPerfMonitor::InitPerfMonitor()
121 {
122 monitorStatus_ = 0;
123 ClearPerfMonitor();
124 }
125
ClearPerfMonitor()126 void ArkUIPerfMonitor::ClearPerfMonitor()
127 {
128 timeSlice_[MonitorTag::COMPONENT_CREATION] = 0;
129 timeSlice_[MonitorTag::COMPONENT_LIFECYCLE] = 0;
130 timeSlice_[MonitorTag::COMPONENT_UPDATE] = 0;
131 timeSlice_[MonitorTag::JS_CALLBACK] = 0;
132 timeSlice_[MonitorTag::STATIC_API] = 0;
133 timeSlice_[MonitorTag::OTHER] = 0;
134 propertyNum_ = 0;
135 stateMgmtNodeNum_ = 0;
136 layoutNodeNum_ = 0;
137 renderNodeNum_ = 0;
138 displaySyncRate_ = 0;
139 }
140
FlushPerfMonitor()141 void ArkUIPerfMonitor::FlushPerfMonitor()
142 {
143 auto total = static_cast<int64_t>(duration_cast<nanoseconds>(end_ - begin_).count());
144 auto frameWork = total - timeSlice_[MonitorTag::COMPONENT_CREATION] - timeSlice_[MonitorTag::COMPONENT_LIFECYCLE] -
145 timeSlice_[MonitorTag::COMPONENT_UPDATE] - timeSlice_[MonitorTag::JS_CALLBACK] +
146 timeSlice_[MonitorTag::STATIC_API] - timeSlice_[MonitorTag::OTHER];
147 auto json = JsonUtil::Create(true);
148 json->Put("state_mgmt", stateMgmtNodeNum_);
149 json->Put("layout", layoutNodeNum_);
150 json->Put("render", renderNodeNum_);
151 json->Put("property", propertyNum_);
152 json->Put("total", total);
153 json->Put("framework", frameWork);
154 json->Put("display_sync_rate", displaySyncRate_);
155 ACE_SCOPED_TRACE("ArkUIPerfMonitor %s", json->ToString().c_str());
156 }
157 } // namespace OHOS::Ace
158