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 uint8_t depth = 0; 97 for (size_t i = 0; i < callStackNames.size(); i++) { 98 std::optional<uint64_t> parentId = 0; 99 CallStackInternalRow callStackInternalRow = {INVALID_TIME, INVALID_TIME, INVALID_UINT32, 100 INVALID_UINT64, callStackNames[i], ++depth}; 101 callStackSlice->AppendInternalSlice(callStackInternalRow, parentId); 102 point.funcPrefix_ = funcPrefixs[1]; 103 auto res = stream_.streamFilters_->animationFilter_->BeginDynamicFrameEvent(point, CALLSTACK_SLICE_ID); 104 EXPECT_FALSE(res); 105 } 106 // the current or the parent callStackNames haven't WindowScene_ 107 uint64_t index = INVALID_UINT64; 108 depth = 0; 109 for (size_t i = 0; i < callStackNames.size(); i++) { 110 std::optional<uint64_t> parentId; 111 if (index != INVALID_UINT64) { 112 parentId = index; 113 } 114 depth = i + 1; 115 CallStackInternalRow callStackInternalRow1 = {INVALID_TIME, INVALID_TIME, INVALID_UINT32, 116 INVALID_UINT64, callStackNames[i], depth}; 117 index = callStackSlice->AppendInternalSlice(callStackInternalRow1, parentId); 118 } 119 point.funcPrefix_ = funcPrefixs[2]; 120 point.name_ = invalidName; 121 auto curStackRow = 1; 122 auto res = stream_.streamFilters_->animationFilter_->BeginDynamicFrameEvent(point, curStackRow); 123 EXPECT_FALSE(res); 124 // valid callStack 125 point.funcPrefix_ = funcPrefixs[0]; 126 point.name_ = validName; 127 curStackRow = 2; 128 res = stream_.streamFilters_->animationFilter_->BeginDynamicFrameEvent(point, curStackRow); 129 EXPECT_TRUE(res); 130 point.funcPrefix_ = funcPrefixs[1]; 131 point.name_ = newValidName; 132 curStackRow = 3; 133 res = stream_.streamFilters_->animationFilter_->BeginDynamicFrameEvent(point, curStackRow); 134 EXPECT_TRUE(res); 135 } 136 137 /** 138 * @tc.name: UpdateDevicePos 139 * @tc.desc: update device pos 140 * @tc.type: FUNC 141 */ 142 HWTEST_F(AnimationFilterTest, UpdateDevicePos, TestSize.Level1) 143 { 144 TS_LOGI("test36-3"); 145 TracePoint point; 146 BytraceLine line; 147 std::string validFuncPrefix{"H:RSUniRender::Process:[SCBDesktop2]"}; 148 std::vector<std::string> invalidFuncArgs{ 149 "()", 150 "(1,)", 151 "[1,2]", 152 }; 153 stream_.traceDataCache_->GetDeviceInfo()->Clear(); 154 for (size_t i = 0; i < invalidFuncArgs.size(); i++) { 155 point.funcPrefix_ = validFuncPrefix; 156 point.funcArgs_ = invalidFuncArgs[i]; 157 point.name_ = point.funcPrefix_ + " " + point.funcArgs_; 158 point.funcPrefixId_ = stream_.traceDataCache_->GetDataIndex(point.funcPrefix_); 159 auto res = stream_.streamFilters_->animationFilter_->UpdateDeviceInfoEvent(point, line); 160 EXPECT_FALSE(res); 161 } 162 std::vector<std::string> validFuncArgs{ 163 "(0, 0, 1024, 1920)", 164 "(0,0, 628, 720)", 165 "(0,0, 628, 720)", 166 }; 167 for (size_t i = 0; i < validFuncArgs.size(); i++) { 168 stream_.traceDataCache_->GetDeviceInfo()->Clear(); 169 point.funcPrefix_ = validFuncPrefix; 170 point.funcArgs_ = validFuncArgs[i]; 171 point.name_ = point.funcPrefix_ + " " + point.funcArgs_; 172 point.funcPrefixId_ = stream_.traceDataCache_->GetDataIndex(point.funcPrefix_); 173 auto res = stream_.streamFilters_->animationFilter_->UpdateDeviceInfoEvent(point, line); 174 EXPECT_TRUE(res); 175 } 176 } 177 /** 178 * @tc.name: UpdateDeviceFps 179 * @tc.desc: update device fps 180 * @tc.type: FUNC 181 */ 182 HWTEST_F(AnimationFilterTest, UpdateDeviceFps, TestSize.Level1) 183 { 184 TS_LOGI("test36-4"); 185 TracePoint point; 186 BytraceLine line; 187 std::string validName{"H:GenerateVsyncCount:1"}; 188 auto timeDiffFps60 = BILLION_NANOSECONDS / FPS_60; 189 line.ts = 59557002299000; 190 for (uint8_t i = 0; i < GENERATE_VSYNC_EVENT_MAX; i++) { 191 point.name_ = validName; 192 point.funcPrefixId_ = stream_.traceDataCache_->GetDataIndex(point.name_); 193 line.ts += timeDiffFps60; 194 auto res = stream_.streamFilters_->animationFilter_->UpdateDeviceInfoEvent(point, line); 195 EXPECT_TRUE(res); 196 } 197 auto fps = stream_.traceDataCache_->GetDeviceInfo()->PhysicalFrameRate(); 198 EXPECT_EQ(fps, FPS_60); 199 200 stream_.traceDataCache_->GetDeviceInfo()->Clear(); 201 stream_.streamFilters_->animationFilter_->Clear(); 202 auto timeDiffFps90 = BILLION_NANOSECONDS / FPS_90; 203 for (uint8_t i = 0; i < GENERATE_VSYNC_EVENT_MAX; i++) { 204 point.name_ = validName; 205 point.funcPrefixId_ = stream_.traceDataCache_->GetDataIndex(point.name_); 206 line.ts += timeDiffFps90; 207 auto res = stream_.streamFilters_->animationFilter_->UpdateDeviceInfoEvent(point, line); 208 EXPECT_TRUE(res); 209 } 210 fps = stream_.traceDataCache_->GetDeviceInfo()->PhysicalFrameRate(); 211 EXPECT_EQ(fps, FPS_90); 212 213 stream_.traceDataCache_->GetDeviceInfo()->Clear(); 214 stream_.streamFilters_->animationFilter_->Clear(); 215 auto timeDiffFps120 = BILLION_NANOSECONDS / FPS_120; 216 for (uint8_t i = 0; i < GENERATE_VSYNC_EVENT_MAX; i++) { 217 point.name_ = validName; 218 point.funcPrefixId_ = stream_.traceDataCache_->GetDataIndex(point.name_); 219 line.ts += timeDiffFps120; 220 auto res = stream_.streamFilters_->animationFilter_->UpdateDeviceInfoEvent(point, line); 221 EXPECT_TRUE(res); 222 } 223 fps = stream_.traceDataCache_->GetDeviceInfo()->PhysicalFrameRate(); 224 EXPECT_EQ(fps, FPS_120); 225 } 226 /** 227 * @tc.name: UpdateDynamicFrameInfo 228 * @tc.desc: update Dynamic Frame pos and endTime 229 * @tc.type: FUNC 230 */ 231 HWTEST_F(AnimationFilterTest, UpdateDynamicFrameInfo, TestSize.Level1) 232 { 233 TS_LOGI("test36-5"); 234 TracePoint point; 235 CallStack *callStackSlice = stream_.traceDataCache_->GetInternalSlicesData(); 236 std::vector<DataIndex> callStackNames{ 237 stream_.traceDataCache_->GetDataIndex("H:RSMainThread::DoComposition"), 238 stream_.traceDataCache_->GetDataIndex("H:ProcessDisplayRenderNode[0](0,0,0,0)"), 239 stream_.traceDataCache_->GetDataIndex( 240 "H:RSUniRender::Process:[WindowScene_xxx] (0, 0, 1344, 2772) Alpha: 1.00"), 241 242 }; 243 std::string funcPrefix("H:RSUniRender::Process:[WindowScene_xxx]"); 244 uint64_t index = INVALID_UINT64; 245 uint64_t startTime = 59557002299000; 246 uint64_t dur = ONE_MILLION_NANOSECONDS; 247 uint8_t depth = 0; 248 for (size_t i = 0; i < callStackNames.size(); i++) { 249 std::optional<uint64_t> parentId; 250 if (index != INVALID_UINT64) { 251 parentId = index; 252 } 253 depth = i + 1; 254 CallStackInternalRow callStackInternalRow2 = {startTime, dur, INVALID_UINT32, INVALID_UINT64, 255 callStackNames[i], depth}; 256 index = callStackSlice->AppendInternalSlice(callStackInternalRow2, parentId); 257 } 258 point.funcPrefix_ = funcPrefix; 259 point.name_ = stream_.traceDataCache_->GetDataFromDict(callStackNames.back()); 260 auto res = stream_.streamFilters_->animationFilter_->BeginDynamicFrameEvent(point, index); // for WindowScene_xxx 261 EXPECT_TRUE(res); 262 stream_.streamFilters_->animationFilter_->UpdateDynamicFrameInfo(); 263 for (size_t i = 0; i < stream_.traceDataCache_->GetDynamicFrame()->Size(); i++) { 264 EXPECT_TRUE(stream_.traceDataCache_->GetDynamicFrame()->EndTimes()[i] != INVALID_TIME); 265 EXPECT_TRUE(stream_.traceDataCache_->GetDynamicFrame()->Xs()[i] != INVALID_UINT32); 266 } 267 } 268 /** 269 * @tc.name: AnimationStartAndEnd 270 * @tc.desc: update Animation startPoint and endPoint 271 * @tc.type: FUNC 272 */ 273 HWTEST_F(AnimationFilterTest, AnimationStartAndEnd, TestSize.Level1) 274 { 275 TS_LOGI("test36-6"); 276 BytraceLine line; 277 line.ts = 59557002299000; 278 279 CallStack *callStackSlice = stream_.traceDataCache_->GetInternalSlicesData(); 280 uint8_t depth = 1; 281 uint64_t dur = ONE_MILLION_NANOSECONDS; 282 std::optional<uint64_t> parentId; 283 DataIndex callStackName = stream_.traceDataCache_->GetDataIndex( 284 "H:RSUniRender::Process:[WindowScene_xxx] (0, 0, 1344, 2772) Alpha: 1.00"); 285 CallStackInternalRow callStackInternalRow3 = {line.ts, dur, INVALID_UINT32, INVALID_UINT64, callStackName, depth}; 286 auto callStackRow = callStackSlice->AppendInternalSlice(callStackInternalRow3, parentId); 287 288 TracePoint point; 289 point.name_ = "H:APP_LIST_FLING, com.taobao.taobao, pages/Index, 1693876205590."; 290 stream_.streamFilters_->animationFilter_->StartAnimationEvent(line, point, callStackRow); 291 EXPECT_TRUE(!stream_.streamFilters_->animationFilter_->animationCallIds_.empty()); 292 stream_.streamFilters_->animationFilter_->FinishAnimationEvent(line, callStackRow); 293 EXPECT_TRUE(stream_.streamFilters_->animationFilter_->animationCallIds_.empty()); 294 } 295 } // namespace TraceStreamer 296 } // namespace SysTuning 297