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