• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cstdint>
17 #include <sys/types.h>
18 #include <parameters.h>
19 
20 #include "rs_dirty_rects_dfx.h"
21 #include "rs_trace.h"
22 
23 #include "drawable/rs_render_node_drawable.h"
24 #include "drawable/rs_surface_render_node_drawable.h"
25 #include "params/rs_display_render_params.h"
26 #include "params/rs_surface_render_params.h"
27 #include "platform/common/rs_log.h"
28 #include "screen_manager/rs_screen_manager.h"
29 
30 // fresh rate
31 #include "hgm_core.h"
32 
33 #include "pipeline/rs_realtime_refresh_rate_manager.h"
34 
35 namespace OHOS::Rosen {
36 namespace {
37 // DFX drawing alpha
38 constexpr float DFXFillAlpha = 0.2f;
39 constexpr float DFXFontSize = 24.f;
40 }
41 
42 static const std::map<DirtyRegionType, std::string> DIRTY_REGION_TYPE_MAP {
43     { DirtyRegionType::UPDATE_DIRTY_REGION, "UPDATE_DIRTY_REGION" },
44     { DirtyRegionType::OVERLAY_RECT, "OVERLAY_RECT" },
45     { DirtyRegionType::FILTER_RECT, "FILTER_RECT" },
46     { DirtyRegionType::SHADOW_RECT, "SHADOW_RECT" },
47     { DirtyRegionType::PREPARE_CLIP_RECT, "PREPARE_CLIP_RECT" },
48     { DirtyRegionType::REMOVE_CHILD_RECT, "REMOVE_CHILD_RECT" },
49     { DirtyRegionType::RENDER_PROPERTIES_RECT, "RENDER_PROPERTIES_RECT" },
50     { DirtyRegionType::CANVAS_NODE_SKIP_RECT, "CANVAS_NODE_SKIP_RECT" },
51     { DirtyRegionType::OUTLINE_RECT, "OUTLINE_RECT" },
52     { DirtyRegionType::SUBTREE_SKIP_OUT_OF_PARENT_RECT, "SUBTREE_SKIP_OUT_OF_PARENT_RECT" },
53 };
54 
OnDraw(RSPaintFilterCanvas & canvas)55 void RSDirtyRectsDfx::OnDraw(RSPaintFilterCanvas& canvas)
56 {
57     auto& renderThreadParams = RSUniRenderThread::Instance().GetRSRenderThreadParams();
58     if (UNLIKELY(!renderThreadParams)) {
59         RS_LOGE("RSDirtyRectsDfx::OnDraw render thread params is nullptr!");
60         return;
61     }
62 
63     // the following code makes DirtyRegion visible, enable this method by turning on the dirtyregiondebug property
64     if (renderThreadParams->isPartialRenderEnabled_) {
65         if (renderThreadParams->isDirtyRegionDfxEnabled_) {
66             DrawAllSurfaceDirtyRegionForDFX(canvas);
67         }
68         if (renderThreadParams->isTargetDirtyRegionDfxEnabled_) {
69             DrawTargetSurfaceDirtyRegionForDFX(canvas);
70         }
71         if (renderThreadParams->isDisplayDirtyDfxEnabled_) {
72             DrawDirtyRegionForDFX(canvas, targetDrawable_.GetSyncDirtyManager()->GetMergedDirtyRegions());
73         }
74     }
75 
76     if (renderThreadParams->isOpaqueRegionDfxEnabled_) {
77         DrawAllSurfaceOpaqueRegionForDFX(canvas);
78     }
79     if (renderThreadParams->isVisibleRegionDfxEnabled_) {
80         DrawTargetSurfaceVisibleRegionForDFX(canvas);
81     }
82 
83     if (RSRealtimeRefreshRateManager::Instance().GetShowRefreshRateEnabled()) {
84         DrawCurrentRefreshRate(canvas);
85     }
86 
87     DrawableV2::RSRenderNodeDrawable::DrawDfxForCacheInfo(canvas);
88 }
89 
OnDrawVirtual(RSPaintFilterCanvas & canvas)90 void RSDirtyRectsDfx::OnDrawVirtual(RSPaintFilterCanvas& canvas)
91 {
92     auto& renderThreadParams = RSUniRenderThread::Instance().GetRSRenderThreadParams();
93     if (UNLIKELY(!renderThreadParams)) {
94         RS_LOGE("RSDirtyRectsDfx::OnDraw render thread params is nullptr!");
95         return;
96     }
97 
98     if (renderThreadParams->isVirtualDirtyDfxEnabled_) {
99         DrawDirtyRegionInVirtual(canvas);
100     }
101 }
102 
DrawDirtyRegionInVirtual(RSPaintFilterCanvas & canvas) const103 void RSDirtyRectsDfx::DrawDirtyRegionInVirtual(RSPaintFilterCanvas& canvas) const
104 {
105     for (const auto& subRect : virtualDirtyRects_) {
106         RectI tmpRect;
107 #ifdef RS_ENABLE_VK
108         if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
109             RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
110             tmpRect = subRect;
111         } else {
112             tmpRect = RectI(subRect.GetLeft(),
113                 static_cast<int32_t>(screenInfo_.GetRotatedHeight()) - subRect.GetTop() - subRect.GetHeight(),
114                 subRect.GetWidth(), subRect.GetHeight());
115         }
116 #else
117         tmpRect = RectI(subRect.GetLeft(),
118             static_cast<int32_t>(screenInfo_.GetRotatedHeight()) - subRect.GetTop() - subRect.GetHeight(),
119             subRect.GetWidth(), subRect.GetHeight());
120 #endif
121         DrawDirtyRectForDFX(canvas, tmpRect, Drawing::Color::COLOR_BLUE, RSPaintStyle::STROKE);
122     }
123 }
124 
RefreshRateRotationProcess(RSPaintFilterCanvas & canvas,ScreenRotation rotation,uint64_t screenId)125 bool RSDirtyRectsDfx::RefreshRateRotationProcess(RSPaintFilterCanvas& canvas,
126     ScreenRotation rotation, uint64_t screenId)
127 {
128     if (rotation != ScreenRotation::ROTATION_0) {
129         auto screenManager = CreateOrGetScreenManager();
130         auto mainScreenInfo = screenManager->QueryScreenInfo(screenId);
131         if (rotation == ScreenRotation::ROTATION_90) {
132             canvas.Rotate(-90, 0, 0); // 90 degree for text draw
133             canvas.Translate(-(static_cast<float>(mainScreenInfo.height)), 0);
134         } else if (rotation == ScreenRotation::ROTATION_180) {
135             // 180 degree for text draw
136             canvas.Rotate(-180, static_cast<float>(mainScreenInfo.width) / 2, // 2 half of screen width
137                 static_cast<float>(mainScreenInfo.height) / 2);                 // 2 half of screen height
138         } else if (rotation == ScreenRotation::ROTATION_270) {
139             canvas.Rotate(-270, 0, 0); // 270 degree for text draw
140             canvas.Translate(0, -(static_cast<float>(mainScreenInfo.width)));
141         } else {
142             return false;
143         }
144     }
145     return true;
146 }
147 
DrawCurrentRefreshRate(RSPaintFilterCanvas & canvas)148 void RSDirtyRectsDfx::DrawCurrentRefreshRate(RSPaintFilterCanvas& canvas)
149 {
150     RS_TRACE_FUNC();
151     if (UNLIKELY(!displayParams_)) {
152         return;
153     }
154     auto screenId = displayParams_->GetScreenId();
155     static const std::string FOLD_SCREEN_TYPE = system::GetParameter("const.window.foldscreen.type", "0,0,0,0");
156     const char dualDisplay = '2';
157     // fold device with two logic screens
158     if (FOLD_SCREEN_TYPE[0] == dualDisplay && screenId != 0) {
159         return;
160     }
161     uint32_t currentRefreshRate = OHOS::Rosen::HgmCore::Instance().GetScreenCurrentRefreshRate(screenId);
162     uint32_t realtimeRefreshRate = RSRealtimeRefreshRateManager::Instance().GetRealtimeRefreshRate();
163     if (realtimeRefreshRate > currentRefreshRate) {
164         realtimeRefreshRate = currentRefreshRate;
165     }
166 
167     std::string info = std::to_string(currentRefreshRate) + " " + std::to_string(realtimeRefreshRate);
168     std::shared_ptr<Drawing::Typeface> tf = Drawing::Typeface::MakeFromName("HarmonyOS Sans SC", Drawing::FontStyle());
169     Drawing::Font font;
170     font.SetSize(100); // 100:Scalar of setting font size
171     font.SetTypeface(tf);
172     std::shared_ptr<Drawing::TextBlob> textBlob = Drawing::TextBlob::MakeFromString(info.c_str(), font);
173 
174     Drawing::Brush brush;
175     brush.SetColor(currentRefreshRate <= 60 ? SK_ColorRED : SK_ColorGREEN); // low refresh rate 60
176     brush.SetAntiAlias(true);
177     RSAutoCanvasRestore acr(&canvas);
178     canvas.AttachBrush(brush);
179     auto rotation = displayParams_->GetScreenRotation();
180     // fold device with one logic screen
181     if (RSSystemProperties::IsFoldScreenFlag() && FOLD_SCREEN_TYPE[0] != dualDisplay
182         && screenId == 0) {
183         rotation =
184             (rotation == ScreenRotation::ROTATION_270 ? ScreenRotation::ROTATION_0
185                                                       : static_cast<ScreenRotation>(static_cast<int>(rotation) + 1));
186     }
187     auto saveCount = canvas.Save();
188     if (!RefreshRateRotationProcess(canvas, rotation, screenId)) {
189         return;
190     }
191     // 100.f:Scalar x of drawing TextBlob; 200.f:Scalar y of drawing TextBlob
192     canvas.DrawTextBlob(textBlob.get(), 100.f, 200.f);
193     canvas.RestoreToCount(saveCount);
194     canvas.DetachBrush();
195 }
196 
DrawDirtyRectForDFX(RSPaintFilterCanvas & canvas,RectI dirtyRect,const Drawing::Color color,const RSPaintStyle fillType,int edgeWidth,bool isTextOutsideRect) const197 void RSDirtyRectsDfx::DrawDirtyRectForDFX(RSPaintFilterCanvas& canvas, RectI dirtyRect, const Drawing::Color color,
198     const RSPaintStyle fillType, int edgeWidth, bool isTextOutsideRect) const
199 {
200     if (dirtyRect.width_ <= 0 || dirtyRect.height_ <= 0) {
201         ROSEN_LOGD("DrawDirtyRectForDFX dirty rect is invalid.");
202         return;
203     }
204     ROSEN_LOGD("DrawDirtyRectForDFX current dirtyRect = %{public}s", dirtyRect.ToString().c_str());
205     auto rect = Drawing::Rect(
206         dirtyRect.left_, dirtyRect.top_, dirtyRect.left_ + dirtyRect.width_, dirtyRect.top_ + dirtyRect.height_);
207     RSAutoCanvasRestore acr(&canvas);
208     Drawing::Matrix invertMatrix;
209     if (displayParams_ && displayParams_->GetMatrix().Invert(invertMatrix)) {
210         // Modifying the drawing origin does not affect the actual drawing content
211         canvas.ConcatMatrix(displayParams_->GetMatrix());
212         invertMatrix.MapRect(rect, rect);
213         dirtyRect.SetAll(rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight());
214     }
215     std::string position = std::to_string(dirtyRect.left_) + ',' + std::to_string(dirtyRect.top_) + ',' +
216                            std::to_string(dirtyRect.width_) + ',' + std::to_string(dirtyRect.height_);
217     const int defaultTextOffsetX = edgeWidth;
218     const int defaultTextOffsetY = 30; // text position has 30 pixelSize under the Rect
219     Drawing::Pen rectPen;
220     Drawing::Brush rectBrush;
221     // font size: 24
222     std::shared_ptr<Drawing::TextBlob> textBlob =
223         Drawing::TextBlob::MakeFromString(position.c_str(), Drawing::Font(nullptr, DFXFontSize, 1.0f, 0.0f));
224     if (fillType == RSPaintStyle::STROKE) {
225         rectPen.SetColor(color);
226         rectPen.SetAntiAlias(true);
227         rectPen.SetAlphaF(DFXFillAlpha);
228         rectPen.SetWidth(edgeWidth);
229         rectPen.SetJoinStyle(Drawing::Pen::JoinStyle::ROUND_JOIN);
230         canvas.AttachPen(rectPen);
231     } else {
232         rectBrush.SetColor(color);
233         rectBrush.SetAntiAlias(true);
234         rectBrush.SetAlphaF(DFXFillAlpha);
235         canvas.AttachBrush(rectBrush);
236     }
237     canvas.DrawRect(rect);
238     canvas.DetachPen();
239     canvas.DetachBrush();
240     canvas.AttachBrush(Drawing::Brush());
241     if (isTextOutsideRect) {
242         canvas.DrawTextBlob(textBlob.get(), dirtyRect.left_ + defaultTextOffsetX, dirtyRect.top_ - edgeWidth);
243     } else {
244         canvas.DrawTextBlob(textBlob.get(), dirtyRect.left_ + defaultTextOffsetX, dirtyRect.top_ + defaultTextOffsetY);
245     }
246     canvas.DetachBrush();
247 }
248 
DrawDirtyRegionForDFX(RSPaintFilterCanvas & canvas,const std::vector<RectI> & dirtyRects) const249 void RSDirtyRectsDfx::DrawDirtyRegionForDFX(RSPaintFilterCanvas& canvas, const std::vector<RectI>& dirtyRects) const
250 {
251     for (const auto& subRect : dirtyRects) {
252         DrawDirtyRectForDFX(canvas, subRect, Drawing::Color::COLOR_BLUE, RSPaintStyle::STROKE);
253     }
254 }
255 
DrawAndTraceSingleDirtyRegionTypeForDFX(RSPaintFilterCanvas & canvas,DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable,DirtyRegionType dirtyType,bool isDrawn) const256 void RSDirtyRectsDfx::DrawAndTraceSingleDirtyRegionTypeForDFX(RSPaintFilterCanvas& canvas,
257     DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable, DirtyRegionType dirtyType, bool isDrawn) const
258 {
259     auto dirtyManager = surfaceDrawable.GetSyncDirtyManager();
260     auto matchType = DIRTY_REGION_TYPE_MAP.find(dirtyType);
261     if (matchType == DIRTY_REGION_TYPE_MAP.end()) {
262         return;
263     }
264     std::map<NodeId, RectI> dirtyInfo;
265     std::map<RSRenderNodeType, std::pair<std::string, SkColor>> nodeConfig = {
266         { RSRenderNodeType::CANVAS_NODE, std::make_pair("canvas", SK_ColorRED) },
267         { RSRenderNodeType::SURFACE_NODE, std::make_pair("surface", SK_ColorGREEN) },
268     };
269 
270     std::string subInfo;
271     for (const auto& [nodeType, info] : nodeConfig) {
272         dirtyManager->GetDirtyRegionInfo(dirtyInfo, nodeType, dirtyType);
273         subInfo += (" " + info.first + "node amount: " + std::to_string(dirtyInfo.size()));
274         for (const auto& [nid, rect] : dirtyInfo) {
275             if (isDrawn) {
276                 DrawDirtyRectForDFX(canvas, rect, info.second, RSPaintStyle::STROKE);
277             }
278         }
279     }
280     RS_TRACE_NAME_FMT("DrawAndTraceSingleDirtyRegionTypeForDFX target surface node %s - id[%" PRIu64 "]"
281         " has dirtytype %s %s", surfaceDrawable.GetName().c_str(), surfaceDrawable.GetId(),
282         matchType->second.c_str(), subInfo.c_str());
283     ROSEN_LOGD("DrawAndTraceSingleDirtyRegionTypeForDFX target surface node %{public}s, id[%{public}" PRIu64 "]"
284         "has dirtytype %{public}s%{public}s",
285         surfaceDrawable.GetName().c_str(), surfaceDrawable.GetId(), matchType->second.c_str(), subInfo.c_str());
286 }
287 
DrawDetailedTypesOfDirtyRegionForDFX(RSPaintFilterCanvas & canvas,DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable) const288 bool RSDirtyRectsDfx::DrawDetailedTypesOfDirtyRegionForDFX(RSPaintFilterCanvas& canvas,
289     DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable) const
290 {
291     auto dirtyRegionDebugType = RSUniRenderThread::Instance().GetRSRenderThreadParams()->dirtyRegionDebugType_;
292     if (dirtyRegionDebugType < DirtyRegionDebugType::CUR_DIRTY_DETAIL_ONLY_TRACE) {
293         return false;
294     }
295     if (dirtyRegionDebugType == DirtyRegionDebugType::CUR_DIRTY_DETAIL_ONLY_TRACE) {
296         auto i = DirtyRegionType::UPDATE_DIRTY_REGION;
297         for (; i < DirtyRegionType::TYPE_AMOUNT; i = static_cast<DirtyRegionType>(i + 1)) {
298             DrawAndTraceSingleDirtyRegionTypeForDFX(canvas, surfaceDrawable, i, false);
299         }
300         return true;
301     }
302     static const std::map<DirtyRegionDebugType, DirtyRegionType> DIRTY_REGION_DEBUG_TYPE_MAP {
303         { DirtyRegionDebugType::UPDATE_DIRTY_REGION, DirtyRegionType::UPDATE_DIRTY_REGION },
304         { DirtyRegionDebugType::OVERLAY_RECT, DirtyRegionType::OVERLAY_RECT },
305         { DirtyRegionDebugType::FILTER_RECT, DirtyRegionType::FILTER_RECT },
306         { DirtyRegionDebugType::SHADOW_RECT, DirtyRegionType::SHADOW_RECT },
307         { DirtyRegionDebugType::PREPARE_CLIP_RECT, DirtyRegionType::PREPARE_CLIP_RECT },
308         { DirtyRegionDebugType::REMOVE_CHILD_RECT, DirtyRegionType::REMOVE_CHILD_RECT },
309         { DirtyRegionDebugType::RENDER_PROPERTIES_RECT, DirtyRegionType::RENDER_PROPERTIES_RECT },
310         { DirtyRegionDebugType::CANVAS_NODE_SKIP_RECT, DirtyRegionType::CANVAS_NODE_SKIP_RECT },
311         { DirtyRegionDebugType::OUTLINE_RECT, DirtyRegionType::OUTLINE_RECT },
312         { DirtyRegionDebugType::SUBTREE_SKIP_OUT_OF_PARENT_RECT, DirtyRegionType::SUBTREE_SKIP_OUT_OF_PARENT_RECT },
313     };
314     auto matchType = DIRTY_REGION_DEBUG_TYPE_MAP.find(dirtyRegionDebugType);
315     if (matchType != DIRTY_REGION_DEBUG_TYPE_MAP.end()) {
316         DrawAndTraceSingleDirtyRegionTypeForDFX(canvas, surfaceDrawable, matchType->second);
317     }
318     return true;
319 }
320 
DrawSurfaceOpaqueRegionForDFX(RSPaintFilterCanvas & canvas,RSSurfaceRenderParams & surfaceParams) const321 void RSDirtyRectsDfx::DrawSurfaceOpaqueRegionForDFX(RSPaintFilterCanvas& canvas,
322     RSSurfaceRenderParams& surfaceParams) const
323 {
324     const auto& opaqueRegionRects = surfaceParams.GetOpaqueRegion().GetRegionRects();
325     for (const auto& subRect : opaqueRegionRects) {
326         DrawDirtyRectForDFX(canvas, subRect.ToRectI(), Drawing::Color::COLOR_GREEN, RSPaintStyle::FILL, 0);
327     }
328 }
329 
DrawAllSurfaceDirtyRegionForDFX(RSPaintFilterCanvas & canvas) const330 void RSDirtyRectsDfx::DrawAllSurfaceDirtyRegionForDFX(RSPaintFilterCanvas& canvas) const
331 {
332     const auto& visibleDirtyRects = dirtyRegion_.GetRegionRects();
333     std::vector<RectI> rects;
334     for (auto& rect : visibleDirtyRects) {
335         rects.emplace_back(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_);
336     }
337     DrawDirtyRegionForDFX(canvas, rects);
338 
339     // draw expanded dirtyregion with cyan color
340     constexpr int edgeWidth = 6;
341     for (const auto& subRect : expandedDirtyRegion_.GetRegionRectIs()) {
342         DrawDirtyRectForDFX(canvas, subRect, Drawing::Color::COLOR_CYAN, RSPaintStyle::STROKE, edgeWidth, true);
343     }
344 
345     // draw display dirtyregion with red color
346     RectI dirtySurfaceRect = targetDrawable_.GetSyncDirtyManager()->GetDirtyRegion();
347     DrawDirtyRectForDFX(canvas, dirtySurfaceRect, Drawing::Color::COLOR_RED, RSPaintStyle::STROKE);
348 }
349 
DrawAllSurfaceOpaqueRegionForDFX(RSPaintFilterCanvas & canvas) const350 void RSDirtyRectsDfx::DrawAllSurfaceOpaqueRegionForDFX(RSPaintFilterCanvas& canvas) const
351 {
352     if (!displayParams_) {
353         RS_LOGE("RSDirtyRectsDfx::DrawAllSurfaceOpaqueRegionForDFX displayParams is null ptr.");
354         return;
355     }
356     auto& curAllSurfacesDrawables = displayParams_->GetAllMainAndLeashSurfaceDrawables();
357     for (auto it = curAllSurfacesDrawables.rbegin(); it != curAllSurfacesDrawables.rend(); ++it) {
358         auto surfaceParams = static_cast<RSSurfaceRenderParams*>((*it)->GetRenderParams().get());
359         if (surfaceParams && surfaceParams->IsMainWindowType()) {
360             DrawSurfaceOpaqueRegionForDFX(canvas, *surfaceParams);
361         }
362     }
363 }
364 
DrawTargetSurfaceDirtyRegionForDFX(RSPaintFilterCanvas & canvas) const365 void RSDirtyRectsDfx::DrawTargetSurfaceDirtyRegionForDFX(RSPaintFilterCanvas& canvas) const
366 {
367     if (UNLIKELY(!displayParams_)) {
368         return;
369     }
370     const auto& curAllSurfaceDrawables = displayParams_->GetAllMainAndLeashSurfaceDrawables();
371     for (const auto& drawable : curAllSurfaceDrawables) {
372         if (UNLIKELY(!drawable)) {
373             continue;
374         }
375         auto surfaceDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable);
376         auto& surfaceParams = surfaceDrawable->GetRenderParams();
377         if (UNLIKELY(!surfaceParams) || !surfaceParams->IsAppWindow()) {
378             continue;
379         }
380         if (CheckIfSurfaceTargetedForDFX(surfaceDrawable->GetName())) {
381             if (DrawDetailedTypesOfDirtyRegionForDFX(canvas, *surfaceDrawable)) {
382                 continue;
383             }
384             auto dirtyManager = targetDrawable_.GetSyncDirtyManager();
385             const auto& visibleDirtyRects = surfaceDrawable->GetVisibleDirtyRegion().GetRegionRects();
386             std::vector<RectI> rects;
387             for (auto& rect : visibleDirtyRects) {
388                 rects.emplace_back(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_);
389             }
390             const auto visibleRects = surfaceParams->GetVisibleRegion().GetRegionRects();
391             auto displayDirtyRegion = dirtyManager->GetDirtyRegion();
392             for (auto& rect : visibleRects) {
393                 auto visibleRect = RectI(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_);
394                 auto intersectRegion = displayDirtyRegion.IntersectRect(visibleRect);
395                 rects.emplace_back(intersectRegion);
396             }
397             DrawDirtyRegionForDFX(canvas, rects);
398         }
399     }
400 }
401 
DrawTargetSurfaceVisibleRegionForDFX(RSPaintFilterCanvas & canvas) const402 void RSDirtyRectsDfx::DrawTargetSurfaceVisibleRegionForDFX(RSPaintFilterCanvas& canvas) const
403 {
404     if (!displayParams_) {
405         RS_LOGE("RSDirtyRectsDfx: displayParams is null ptr.");
406         return;
407     }
408     auto& curAllSurfacesDrawables = displayParams_->GetAllMainAndLeashSurfaceDrawables();
409     for (auto it = curAllSurfacesDrawables.rbegin(); it != curAllSurfacesDrawables.rend(); ++it) {
410         auto surfaceParams = static_cast<RSSurfaceRenderParams*>((*it)->GetRenderParams().get());
411         if (surfaceParams == nullptr || !surfaceParams->IsAppWindow()) {
412             continue;
413         }
414         if (CheckIfSurfaceTargetedForDFX(surfaceParams->GetName())) {
415             const auto visibleRects = surfaceParams->GetVisibleRegion().GetRegionRects();
416             std::vector<RectI> rects;
417             for (auto& rect : visibleRects) {
418                 rects.emplace_back(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_);
419             }
420             DrawDirtyRegionForDFX(canvas, rects);
421         }
422     }
423 }
424 
425 } // namespace OHOS::Rosen