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