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, Hardware
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 "gtest/gtest.h"
17 #include "drawable/dfx/rs_dirty_rects_dfx.h"
18 #include "drawable/rs_display_render_node_drawable.h"
19 #include "params/rs_render_thread_params.h"
20 #include "pipeline/rs_display_render_node.h"
21 #include "pipeline/rs_realtime_refresh_rate_manager.h"
22 #include "pipeline/rs_render_node.h"
23 #include "pipeline/rs_uni_render_thread.h"
24
25 using namespace testing;
26 using namespace testing::ext;
27 using namespace OHOS::Rosen::DrawableV2;
28
29 namespace OHOS::Rosen {
30 constexpr int32_t DEFAULT_CANVAS_SIZE = 100;
31 constexpr NodeId DEFAULT_ID = 0xFFFF;
32
33 class RSDirtyRectsDFXTest : public testing::Test {
34 public:
35 std::shared_ptr<RSSurfaceRenderNode> renderNode_;
36 std::shared_ptr<RSDisplayRenderNode> displayRenderNode_;
37 RSRenderNodeDrawableAdapter* drawable_ = nullptr;
38 std::shared_ptr<RSDisplayRenderNodeDrawable> displayDrawable_ = nullptr;
39 std::shared_ptr<RSDirtyRectsDfx> rsDirtyRectsDfx_;
40 std::shared_ptr<RSPaintFilterCanvas> canvas_;
41 std::shared_ptr<Drawing::Canvas> drawingCanvas_;
42
43 static void SetUpTestCase();
44 static void TearDownTestCase();
45 void SetUp() override;
46 void TearDown() override;
47 };
48
SetUpTestCase()49 void RSDirtyRectsDFXTest::SetUpTestCase() {}
TearDownTestCase()50 void RSDirtyRectsDFXTest::TearDownTestCase() {}
SetUp()51 void RSDirtyRectsDFXTest::SetUp()
52 {
53 renderNode_ = std::make_shared<RSSurfaceRenderNode>(DEFAULT_ID);
54 RSDisplayNodeConfig config;
55 displayRenderNode_ = std::make_shared<RSDisplayRenderNode>(DEFAULT_ID, config);
56 if (!renderNode_) {
57 RS_LOGE("RSSurfaceRenderNodeDrawableTest: failed to create surface node.");
58 return;
59 }
60 displayDrawable_ = std::static_pointer_cast<RSDisplayRenderNodeDrawable>(
61 DrawableV2::RSRenderNodeDrawableAdapter::OnGenerate(displayRenderNode_));
62 if (!displayDrawable_->renderParams_) {
63 RS_LOGE("RSSurfaceRenderNodeDrawableTest: failed to init displayDrawable_.");
64 return;
65 }
66 auto displayRenderParams = static_cast<RSDisplayRenderParams*>(displayDrawable_->GetRenderParams().get());
67 if (!displayRenderParams) {
68 RS_LOGE("RSSurfaceRenderNodeDrawableTest: failed to init displayRenderParams.");
69 return;
70 }
71 rsDirtyRectsDfx_ = std::make_shared<RSDirtyRectsDfx>(*displayDrawable_);
72 if (!rsDirtyRectsDfx_) {
73 RS_LOGE("RSSurfaceRenderNodeDrawableTest: failed to create RSDirtyRectsDfx.");
74 return;
75 }
76 drawingCanvas_ = std::make_unique<Drawing::Canvas>(DEFAULT_CANVAS_SIZE, DEFAULT_CANVAS_SIZE);
77 if (drawingCanvas_) {
78 canvas_ = std::make_shared<RSPaintFilterCanvas>(drawingCanvas_.get());
79 }
80 auto& rtThread = RSUniRenderThread::Instance();
81 if (!rtThread.GetRSRenderThreadParams()) {
82 RSRenderThreadParamsManager::Instance().renderThreadParams_ = std::make_unique<RSRenderThreadParams>();
83 }
84 }
TearDown()85 void RSDirtyRectsDFXTest::TearDown() {}
86
87 /**
88 * @tc.name: OnDrawest
89 * @tc.desc: Test If OnDraw Can Run
90 * @tc.type: FUNC
91 * @tc.require: #I9NVOG
92 */
93 HWTEST_F(RSDirtyRectsDFXTest, OnDraw, TestSize.Level1)
94 {
95 ASSERT_NE(rsDirtyRectsDfx_, nullptr);
96 std::shared_ptr<RSPaintFilterCanvas> canvas = nullptr;
97 rsDirtyRectsDfx_->OnDraw(*canvas);
98 ASSERT_NE(canvas_, nullptr);
99 rsDirtyRectsDfx_->OnDraw(*canvas_);
100
101 RSUniRenderThread::Instance().GetRSRenderThreadParams()->isPartialRenderEnabled_ = true;
102 RSUniRenderThread::Instance().GetRSRenderThreadParams()->isOpaqueRegionDfxEnabled_ = true;
103 RSUniRenderThread::Instance().GetRSRenderThreadParams()->isVisibleRegionDfxEnabled_ = true;
104 RSRealtimeRefreshRateManager::Instance().enableState_ = true;
105 rsDirtyRectsDfx_->OnDraw(*canvas_);
106
107 RSUniRenderThread::Instance().GetRSRenderThreadParams()->isDirtyRegionDfxEnabled_ = true;
108 RSUniRenderThread::Instance().GetRSRenderThreadParams()->isTargetDirtyRegionDfxEnabled_ = true;
109 RSUniRenderThread::Instance().GetRSRenderThreadParams()->isDisplayDirtyDfxEnabled_ = true;
110 rsDirtyRectsDfx_->OnDraw(*canvas_);
111 RSUniRenderThread::Instance().GetRSRenderThreadParams()->isPartialRenderEnabled_ = false;
112 RSUniRenderThread::Instance().GetRSRenderThreadParams()->isOpaqueRegionDfxEnabled_ = false;
113 RSUniRenderThread::Instance().GetRSRenderThreadParams()->isVisibleRegionDfxEnabled_ = false;
114 RSRealtimeRefreshRateManager::Instance().enableState_ = false;
115 RSUniRenderThread::Instance().GetRSRenderThreadParams()->isDirtyRegionDfxEnabled_ = false;
116 RSUniRenderThread::Instance().GetRSRenderThreadParams()->isTargetDirtyRegionDfxEnabled_ = false;
117 RSUniRenderThread::Instance().GetRSRenderThreadParams()->isDisplayDirtyDfxEnabled_ = false;
118 ASSERT_TRUE(RSUniRenderThread::Instance().GetRSRenderThreadParams());
119 }
120
121 /**
122 * @tc.name: OnDrawVirtualTest
123 * @tc.desc: Test If OnDrawVirtual Can Run
124 * @tc.type: FUNC
125 * @tc.require: #I9NVOG
126 */
127 HWTEST_F(RSDirtyRectsDFXTest, OnDrawVirtual, TestSize.Level1)
128 {
129 ASSERT_NE(rsDirtyRectsDfx_, nullptr);
130 std::shared_ptr<RSPaintFilterCanvas> canvas = nullptr;
131 rsDirtyRectsDfx_->OnDraw(*canvas);
132 ASSERT_NE(canvas_, nullptr);
133 rsDirtyRectsDfx_->OnDrawVirtual(*canvas_);
134 ASSERT_FALSE(RSUniRenderThread::Instance().GetRSRenderThreadParams()->isVirtualDirtyDfxEnabled_);
135
136 RSUniRenderThread::Instance().GetRSRenderThreadParams()->isVirtualDirtyDfxEnabled_ = true;
137 rsDirtyRectsDfx_->OnDrawVirtual(*canvas_);
138 RSUniRenderThread::Instance().GetRSRenderThreadParams()->isVirtualDirtyDfxEnabled_ = false;
139 }
140
141 /**
142 * @tc.name: DrawDirtyRegionInVirtual
143 * @tc.desc: Test If DrawCurrentRefreshRate Can Run
144 * @tc.type: FUNC
145 * @tc.require: #I9NVOG
146 */
147 HWTEST_F(RSDirtyRectsDFXTest, DrawDirtyRegionInVirtual, TestSize.Level1)
148 {
149 ASSERT_NE(rsDirtyRectsDfx_, nullptr);
150 rsDirtyRectsDfx_->DrawDirtyRegionInVirtual(*canvas_);
151 }
152
153 /**
154 * @tc.name: DrawCurrentRefreshRate
155 * @tc.desc: Test If DrawCurrentRefreshRate Can Run
156 * @tc.type: FUNC
157 * @tc.require: issueIAGR5V
158 */
159 HWTEST_F(RSDirtyRectsDFXTest, DrawCurrentRefreshRate, TestSize.Level1)
160 {
161 ASSERT_NE(rsDirtyRectsDfx_, nullptr);
162 auto drawingCanvas = std::make_unique<Drawing::Canvas>();
163 auto canvas = std::make_shared<RSPaintFilterCanvas>(drawingCanvas.get());
164 rsDirtyRectsDfx_->DrawCurrentRefreshRate(*canvas);
165 ASSERT_TRUE(canvas);
166 }
167
168 /**
169 * @tc.name: DrawDirtyRegionForDFX
170 * @tc.desc: Test If DrawDirtyRegionForDFX Can Run
171 * @tc.type: FUNC
172 * @tc.require: #I9NVOG
173 */
174 HWTEST_F(RSDirtyRectsDFXTest, DrawDirtyRegionForDFX, TestSize.Level1)
175 {
176 ASSERT_NE(rsDirtyRectsDfx_, nullptr);
177 const auto& visibleDirtyRects = rsDirtyRectsDfx_->dirtyRegion_.GetRegionRects();
178 std::vector<RectI> rects;
179 for (auto& rect : visibleDirtyRects) {
180 rects.emplace_back(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_);
181 }
182 rsDirtyRectsDfx_->DrawDirtyRegionForDFX(*canvas_, rects);
183
184 auto& targetDrawable = rsDirtyRectsDfx_->targetDrawable_;
185 auto dirtyManager = targetDrawable.GetSyncDirtyManager();
186 ASSERT_NE(dirtyManager, nullptr);
187 rects = dirtyManager->GetMergedDirtyRegions();
188 rsDirtyRectsDfx_->DrawDirtyRegionForDFX(*canvas_, rects);
189 }
190
191 /**
192 * @tc.name: DrawAllSurfaceOpaqueRegionForDFX
193 * @tc.desc: Test If DrawAllSurfaceOpaqueRegionForDFX Can Run
194 * @tc.type: FUNC
195 * @tc.require: #I9NVOG
196 */
197 HWTEST_F(RSDirtyRectsDFXTest, DrawAllSurfaceOpaqueRegionForDFX, TestSize.Level1)
198 {
199 ASSERT_NE(rsDirtyRectsDfx_, nullptr);
200 rsDirtyRectsDfx_->DrawAllSurfaceOpaqueRegionForDFX(*canvas_);
201 auto& targetDrawable = rsDirtyRectsDfx_->targetDrawable_;
202 ASSERT_NE(targetDrawable.GetRenderParams(), nullptr);
203 }
204
205 /**
206 * @tc.name: DrawTargetSurfaceDirtyRegionForDFX
207 * @tc.desc: Test If DrawTargetSurfaceDirtyRegionForDFX Can Run
208 * @tc.type: FUNC
209 * @tc.require: #I9NVOG
210 */
211 HWTEST_F(RSDirtyRectsDFXTest, DrawTargetSurfaceDirtyRegionForDFX, TestSize.Level1)
212 {
213 ASSERT_NE(rsDirtyRectsDfx_, nullptr);
214 rsDirtyRectsDfx_->DrawTargetSurfaceDirtyRegionForDFX(*canvas_);
215 ASSERT_NE(rsDirtyRectsDfx_->targetDrawable_.GetRenderParams(), nullptr);
216 }
217
218 /**
219 * @tc.name: DrawTargetSurfaceVisibleRegionForDFX
220 * @tc.desc: Test If DrawTargetSurfaceVisibleRegionForDFX Can Run
221 * @tc.type: FUNC
222 * @tc.require: #I9NVOG
223 */
224 HWTEST_F(RSDirtyRectsDFXTest, DrawTargetSurfaceVisibleRegionForDFX, TestSize.Level1)
225 {
226 ASSERT_NE(rsDirtyRectsDfx_, nullptr);
227 rsDirtyRectsDfx_->DrawTargetSurfaceVisibleRegionForDFX(*canvas_);
228 }
229
230 /**
231 * @tc.name: RefreshRateRotationProcess
232 * @tc.desc: Test If RefreshRateRotationProcess Can Run
233 * @tc.type: FUNC
234 * @tc.require: issueIAGR5V
235 */
236 HWTEST_F(RSDirtyRectsDFXTest, RefreshRateRotationProcess, TestSize.Level1)
237 {
238 ASSERT_NE(rsDirtyRectsDfx_, nullptr);
239 ScreenRotation rotation = ScreenRotation::ROTATION_0;
240 uint64_t screenId = 0;
241 bool res = rsDirtyRectsDfx_->RefreshRateRotationProcess(*canvas_, rotation, screenId);
242 ASSERT_TRUE(res);
243
244 rotation = ScreenRotation::ROTATION_90;
245 auto drawingCanvas = std::make_unique<Drawing::Canvas>();
246 canvas_ = std::make_shared<RSPaintFilterCanvas>(drawingCanvas.get());
247 res = rsDirtyRectsDfx_->RefreshRateRotationProcess(*canvas_, rotation, screenId);
248 ASSERT_TRUE(res);
249
250 rotation = ScreenRotation::ROTATION_180;
251 res = rsDirtyRectsDfx_->RefreshRateRotationProcess(*canvas_, rotation, screenId);
252 ASSERT_TRUE(res);
253
254 rotation = ScreenRotation::ROTATION_270;
255 res = rsDirtyRectsDfx_->RefreshRateRotationProcess(*canvas_, rotation, screenId);
256 ASSERT_TRUE(res);
257
258 rotation = ScreenRotation::INVALID_SCREEN_ROTATION;
259 res = rsDirtyRectsDfx_->RefreshRateRotationProcess(*canvas_, rotation, screenId);
260 ASSERT_FALSE(res);
261 }
262
263 /**
264 * @tc.name: DrawDirtyRectForDFX
265 * @tc.desc: Test If DrawDirtyRectForDFX Can Run
266 * @tc.type: FUNC
267 * @tc.require: issueIAGR5V
268 */
269 HWTEST_F(RSDirtyRectsDFXTest, DrawDirtyRectForDFX, TestSize.Level1)
270 {
271 ASSERT_NE(rsDirtyRectsDfx_, nullptr);
272 RectI dirtyRect(1, 1, 1, 1);
273 Drawing::Color color;
274 RSDirtyRectsDfx::RSPaintStyle fillType = RSDirtyRectsDfx::RSPaintStyle::STROKE;
275 int edgeWidth = 1;
276 auto drawingCanvas = std::make_unique<Drawing::Canvas>();
277 canvas_ = std::make_shared<RSPaintFilterCanvas>(drawingCanvas.get());
278 rsDirtyRectsDfx_->DrawDirtyRectForDFX(*canvas_, dirtyRect, color, fillType, edgeWidth);
279 ASSERT_TRUE(rsDirtyRectsDfx_->displayParams_);
280
281 fillType = RSDirtyRectsDfx::RSPaintStyle::FILL;
282 rsDirtyRectsDfx_->DrawDirtyRectForDFX(*canvas_, dirtyRect, color, fillType, edgeWidth);
283 dirtyRect.height_ = 0;
284 rsDirtyRectsDfx_->DrawDirtyRectForDFX(*canvas_, dirtyRect, color, fillType, edgeWidth);
285 dirtyRect.width_ = 0;
286 rsDirtyRectsDfx_->DrawDirtyRectForDFX(*canvas_, dirtyRect, color, fillType, edgeWidth);
287 ASSERT_TRUE(canvas_);
288 }
289 }
290