1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. 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 <hwext/gtest-ext.h> 17 #include <hwext/gtest-tag.h> 18 19 #include "animation_filter.h" 20 #include "trace_streamer_selector.h" 21 22 using namespace testing::ext; 23 using namespace SysTuning::TraceStreamer; 24 namespace SysTuning { 25 namespace TraceStreamer { 26 constexpr uint8_t GENERATE_VSYNC_EVENT_MAX = 6; 27 constexpr uint16_t FPS_60 = 60; 28 constexpr uint16_t FPS_90 = 90; 29 constexpr uint16_t FPS_120 = 120; 30 class AnimationFilterTest : public ::testing::Test { 31 public: SetUp()32 void SetUp() 33 { 34 stream_.InitFilter(); 35 } 36 TearDown()37 void TearDown() {} 38 39 public: 40 TraceStreamerSelector stream_; 41 }; 42 43 /** 44 * @tc.name: NonRsUniProcessEvent 45 * @tc.desc: the current event isn't RsUniProcessEvent 46 * @tc.type: FUNC 47 */ 48 HWTEST_F(AnimationFilterTest, NonRsUniProcessEvent, TestSize.Level1) 49 { 50 TS_LOGI("test36-1"); 51 TracePoint point; 52 const size_t CALLSTACK_SLICE_ID = 1; 53 std::vector<std::string> nonRsUniProcessEvents{ 54 "H:RSUniRender::Prepare:[xxx]", 55 "H:RSUniRender:DrivenRenderPrepare", 56 "H:RSDrivenRender:DoPrepareRenderTask", 57 "H:ProcessDisplayRenderNode[0](0,", 58 "H:RSBaseRenderEngine::RequestFrame(RSSurface)", 59 "H:DisplayNode:4", 60 "H:AddContainerDirtyToGlobalDirty", 61 }; 62 for (size_t i = 0; i < nonRsUniProcessEvents.size(); i++) { 63 point.funcPrefix_ = nonRsUniProcessEvents[i]; 64 auto res = stream_.streamFilters_->animationFilter_->BeginDynamicFrameEvent(point, CALLSTACK_SLICE_ID); 65 EXPECT_FALSE(res); 66 } 67 } 68 69 /** 70 * @tc.name: InvalidCallStack 71 * @tc.desc: the current event isn't RsUniProcessEvent 72 * @tc.type: FUNC 73 */ 74 HWTEST_F(AnimationFilterTest, InvalidCallStack, TestSize.Level1) 75 { 76 TS_LOGI("test36-2"); 77 TracePoint point; 78 std::string validName("H:RSUniRender::Process:[WindowScene_xxx] (0, 0, 1344, 2772) Alpha: 1.00"); 79 std::string newValidName("H:RSSurfaceRenderNodeDrawable::OnDraw:[WindowScene_xxx] (0, 0, 1344, 2772) Alpha: 1.00"); 80 std::string invalidName("H:RSUniRender::Process:[xxx] (0, 0, 1344, 2772) Alpha: 1.00"); 81 const size_t CALLSTACK_SLICE_ID = 1; 82 CallStack *callStackSlice = stream_.traceDataCache_->GetInternalSlicesData(); 83 std::vector<DataIndex> callStackNames{ 84 stream_.traceDataCache_->GetDataIndex("H:RSMainThread::DoComposition"), 85 stream_.traceDataCache_->GetDataIndex("H:ProcessDisplayRenderNode[0](0,0,0,0)"), 86 stream_.traceDataCache_->GetDataIndex(validName), 87 stream_.traceDataCache_->GetDataIndex(newValidName), 88 stream_.traceDataCache_->GetDataIndex(invalidName), 89 }; 90 std::vector<std::string> funcPrefixs{ 91 "H:RSUniRender::Process:[WindowScene_xxx]", 92 "H:RSSurfaceRenderNodeDrawable::OnDraw:[WindowScene_xxx]", 93 "H:RSUniRender::Process:[xxx]", 94 }; 95 // invalid parentId 96 for (size_t i = 0, depth = 0; i < callStackNames.size(); i++) { 97 std::optional<uint64_t> parentId = 0; 98 CallStackInternalRow callStackInternalRow = {INVALID_TIME, INVALID_TIME, INVALID_UINT32, 99 INVALID_UINT64, callStackNames[i], ++depth}; 100 callStackSlice->AppendInternalSlice(callStackInternalRow, parentId); 101 point.funcPrefix_ = funcPrefixs[1]; 102 auto res = stream_.streamFilters_->animationFilter_->BeginDynamicFrameEvent(point, CALLSTACK_SLICE_ID); 103 EXPECT_FALSE(res); 104 } 105 // the current or the parent callStackNames haven't WindowScene_ 106 uint64_t index = INVALID_UINT64; 107 for (size_t i = 0, depth = 0; i < callStackNames.size(); i++) { 108 std::optional<uint64_t> parentId; 109 if (index != INVALID_UINT64) { 110 parentId = index; 111 } 112 depth = i + 1; 113 CallStackInternalRow callStackInternalRow1 = {INVALID_TIME, INVALID_TIME, INVALID_UINT32, 114 INVALID_UINT64, callStackNames[i], depth}; 115 index = callStackSlice->AppendInternalSlice(callStackInternalRow1, parentId); 116 } 117 point.funcPrefix_ = funcPrefixs[2]; 118 point.name_ = invalidName; 119 auto curStackRow = 1; 120 auto res = stream_.streamFilters_->animationFilter_->BeginDynamicFrameEvent(point, curStackRow); 121 EXPECT_FALSE(res); 122 // valid callStack 123 point.funcPrefix_ = funcPrefixs[0]; 124 point.name_ = validName; 125 curStackRow = 2; 126 res = stream_.streamFilters_->animationFilter_->BeginDynamicFrameEvent(point, curStackRow); 127 EXPECT_TRUE(res); 128 point.funcPrefix_ = funcPrefixs[1]; 129 point.name_ = newValidName; 130 curStackRow = 3; 131 res = stream_.streamFilters_->animationFilter_->BeginDynamicFrameEvent(point, curStackRow); 132 EXPECT_TRUE(res); 133 } 134 135 /** 136 * @tc.name: UpdateDevicePos 137 * @tc.desc: update device pos 138 * @tc.type: FUNC 139 */ 140 HWTEST_F(AnimationFilterTest, UpdateDevicePos, TestSize.Level1) 141 { 142 TS_LOGI("test36-3"); 143 TracePoint point; 144 BytraceLine line; 145 std::string validFuncPrefix{"H:RSUniRender::Process:[SCBDesktop2]"}; 146 std::vector<std::string> invalidFuncArgs{ 147 "()", 148 "(1,)", 149 "[1,2]", 150 }; 151 stream_.traceDataCache_->GetDeviceInfo()->Clear(); 152 for (size_t i = 0; i < invalidFuncArgs.size(); i++) { 153 point.funcPrefix_ = validFuncPrefix; 154 point.funcArgs_ = invalidFuncArgs[i]; 155 point.name_ = point.funcPrefix_ + " " + point.funcArgs_; 156 point.funcPrefixId_ = stream_.traceDataCache_->GetDataIndex(point.funcPrefix_); 157 auto res = stream_.streamFilters_->animationFilter_->UpdateDeviceInfoEvent(point, line); 158 EXPECT_FALSE(res); 159 } 160 std::vector<std::string> validFuncArgs{ 161 "(0, 0, 1024, 1920)", 162 "(0,0, 628, 720)", 163 "(0,0, 628, 720)", 164 }; 165 for (size_t i = 0; i < validFuncArgs.size(); i++) { 166 stream_.traceDataCache_->GetDeviceInfo()->Clear(); 167 point.funcPrefix_ = validFuncPrefix; 168 point.funcArgs_ = validFuncArgs[i]; 169 point.name_ = point.funcPrefix_ + " " + point.funcArgs_; 170 point.funcPrefixId_ = stream_.traceDataCache_->GetDataIndex(point.funcPrefix_); 171 auto res = stream_.streamFilters_->animationFilter_->UpdateDeviceInfoEvent(point, line); 172 EXPECT_TRUE(res); 173 } 174 } 175 /** 176 * @tc.name: UpdateDeviceFps 177 * @tc.desc: update device fps 178 * @tc.type: FUNC 179 */ 180 HWTEST_F(AnimationFilterTest, UpdateDeviceFps, TestSize.Level1) 181 { 182 TS_LOGI("test36-4"); 183 TracePoint point; 184 BytraceLine line; 185 std::string validName{"H:GenerateVsyncCount:1"}; 186 auto timeDiffFps60 = BILLION_NANOSECONDS / FPS_60; 187 line.ts = 59557002299000; 188 for (uint8_t i = 0; i < GENERATE_VSYNC_EVENT_MAX; i++) { 189 point.name_ = validName; 190 point.funcPrefixId_ = stream_.traceDataCache_->GetDataIndex(point.name_); 191 line.ts += timeDiffFps60; 192 auto res = stream_.streamFilters_->animationFilter_->UpdateDeviceInfoEvent(point, line); 193 EXPECT_TRUE(res); 194 } 195 auto fps = stream_.traceDataCache_->GetDeviceInfo()->PhysicalFrameRate(); 196 EXPECT_EQ(fps, FPS_60); 197 198 stream_.traceDataCache_->GetDeviceInfo()->Clear(); 199 stream_.streamFilters_->animationFilter_->Clear(); 200 auto timeDiffFps90 = BILLION_NANOSECONDS / FPS_90; 201 for (uint8_t i = 0; i < GENERATE_VSYNC_EVENT_MAX; i++) { 202 point.name_ = validName; 203 point.funcPrefixId_ = stream_.traceDataCache_->GetDataIndex(point.name_); 204 line.ts += timeDiffFps90; 205 auto res = stream_.streamFilters_->animationFilter_->UpdateDeviceInfoEvent(point, line); 206 EXPECT_TRUE(res); 207 } 208 fps = stream_.traceDataCache_->GetDeviceInfo()->PhysicalFrameRate(); 209 EXPECT_EQ(fps, FPS_90); 210 211 stream_.traceDataCache_->GetDeviceInfo()->Clear(); 212 stream_.streamFilters_->animationFilter_->Clear(); 213 auto timeDiffFps120 = BILLION_NANOSECONDS / FPS_120; 214 for (uint8_t i = 0; i < GENERATE_VSYNC_EVENT_MAX; i++) { 215 point.name_ = validName; 216 point.funcPrefixId_ = stream_.traceDataCache_->GetDataIndex(point.name_); 217 line.ts += timeDiffFps120; 218 auto res = stream_.streamFilters_->animationFilter_->UpdateDeviceInfoEvent(point, line); 219 EXPECT_TRUE(res); 220 } 221 fps = stream_.traceDataCache_->GetDeviceInfo()->PhysicalFrameRate(); 222 EXPECT_EQ(fps, FPS_120); 223 } 224 /** 225 * @tc.name: UpdateDynamicFrameInfo 226 * @tc.desc: update Dynamic Frame pos and endTime 227 * @tc.type: FUNC 228 */ 229 HWTEST_F(AnimationFilterTest, UpdateDynamicFrameInfo, TestSize.Level1) 230 { 231 TS_LOGI("test36-5"); 232 TracePoint point; 233 CallStack *callStackSlice = stream_.traceDataCache_->GetInternalSlicesData(); 234 std::vector<DataIndex> callStackNames{ 235 stream_.traceDataCache_->GetDataIndex("H:RSMainThread::DoComposition"), 236 stream_.traceDataCache_->GetDataIndex("H:ProcessDisplayRenderNode[0](0,0,0,0)"), 237 stream_.traceDataCache_->GetDataIndex( 238 "H:RSUniRender::Process:[WindowScene_xxx] (0, 0, 1344, 2772) Alpha: 1.00"), 239 240 }; 241 std::string funcPrefix("H:RSUniRender::Process:[WindowScene_xxx]"); 242 uint64_t index = INVALID_UINT64; 243 uint64_t startTime = 59557002299000; 244 uint64_t dur = ONE_MILLION_NANOSECONDS; 245 for (size_t i = 0, depth = 0; i < callStackNames.size(); i++) { 246 std::optional<uint64_t> parentId; 247 if (index != INVALID_UINT64) { 248 parentId = index; 249 } 250 depth = i + 1; 251 CallStackInternalRow callStackInternalRow2 = {startTime, dur, INVALID_UINT32, INVALID_UINT64, 252 callStackNames[i], depth}; 253 index = callStackSlice->AppendInternalSlice(callStackInternalRow2, parentId); 254 } 255 point.funcPrefix_ = funcPrefix; 256 point.name_ = stream_.traceDataCache_->GetDataFromDict(callStackNames.back()); 257 auto res = stream_.streamFilters_->animationFilter_->BeginDynamicFrameEvent(point, index); // for WindowScene_xxx 258 EXPECT_TRUE(res); 259 stream_.streamFilters_->animationFilter_->UpdateDynamicFrameInfo(); 260 for (size_t i = 0; i < stream_.traceDataCache_->GetDynamicFrame()->Size(); i++) { 261 EXPECT_TRUE(stream_.traceDataCache_->GetDynamicFrame()->EndTimes()[i] != INVALID_TIME); 262 EXPECT_TRUE(stream_.traceDataCache_->GetDynamicFrame()->Xs()[i] != INVALID_UINT32); 263 } 264 } 265 /** 266 * @tc.name: AnimationStartAndEnd 267 * @tc.desc: update Animation startPoint and endPoint 268 * @tc.type: FUNC 269 */ 270 HWTEST_F(AnimationFilterTest, AnimationStartAndEnd, TestSize.Level1) 271 { 272 TS_LOGI("test36-6"); 273 BytraceLine line; 274 line.ts = 59557002299000; 275 276 CallStack *callStackSlice = stream_.traceDataCache_->GetInternalSlicesData(); 277 uint8_t depth = 1; 278 uint64_t dur = ONE_MILLION_NANOSECONDS; 279 std::optional<uint64_t> parentId; 280 DataIndex callStackName = stream_.traceDataCache_->GetDataIndex( 281 "H:RSUniRender::Process:[WindowScene_xxx] (0, 0, 1344, 2772) Alpha: 1.00"); 282 CallStackInternalRow callStackInternalRow3 = {line.ts, dur, INVALID_UINT32, INVALID_UINT64, callStackName, depth}; 283 auto callStackRow = callStackSlice->AppendInternalSlice(callStackInternalRow3, parentId); 284 285 TracePoint point; 286 point.name_ = "H:APP_LIST_FLING, com.taobao.taobao, pages/Index, 1693876205590."; 287 stream_.streamFilters_->animationFilter_->StartAnimationEvent(line, point, callStackRow); 288 EXPECT_TRUE(!stream_.streamFilters_->animationFilter_->animationCallIds_.empty()); 289 stream_.streamFilters_->animationFilter_->FinishAnimationEvent(line, callStackRow); 290 EXPECT_TRUE(stream_.streamFilters_->animationFilter_->animationCallIds_.empty()); 291 } 292 } // namespace TraceStreamer 293 } // namespace SysTuning 294