• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "pipeline/rs_uni_ui_capture.h"
17 
18 #include <functional>
19 
20 #include "include/core/SkRect.h"
21 #include "rs_trace.h"
22 
23 #include "common/rs_common_def.h"
24 #include "common/rs_obj_abs_geometry.h"
25 #include "pipeline/rs_canvas_drawing_render_node.h"
26 #include "pipeline/rs_dirty_region_manager.h"
27 #include "pipeline/rs_divided_render_util.h"
28 #include "pipeline/rs_main_thread.h"
29 #include "pipeline/rs_uni_render_judgement.h"
30 #include "pipeline/rs_uni_render_util.h"
31 #include "platform/common/rs_log.h"
32 #include "render/rs_skia_filter.h"
33 
34 namespace OHOS {
35 namespace Rosen {
36 
37 const int FAKE_WIDTH = 10; // When the width and height of the node are not set, use the fake width
38 const int FAKE_HEIGHT = 10; // When the width and height of the node are not set, use the fake height
39 
TakeLocalCapture()40 std::shared_ptr<Media::PixelMap> RSUniUICapture::TakeLocalCapture()
41 {
42     if (ROSEN_EQ(scaleX_, 0.f) || ROSEN_EQ(scaleY_, 0.f) || scaleX_ < 0.f || scaleY_ < 0.f) {
43         RS_LOGE("RSUniUICapture::TakeLocalCapture: scale is invalid.");
44         return nullptr;
45     }
46     auto node = RSMainThread::Instance()->GetContext().GetNodeMap().GetRenderNode<RSRenderNode>(nodeId_);
47     if (node == nullptr) {
48         RS_LOGE("RSUniUICapture::TakeLocalCapture node is nullptr return");
49         return nullptr;
50     }
51     std::shared_ptr<RSUniUICaptureVisitor> visitor =
52         std::make_shared<RSUniUICaptureVisitor>(nodeId_, scaleX_, scaleY_);
53 #ifndef USE_ROSEN_DRAWING
54     auto recordingCanvas = std::make_shared<RSRecordingCanvas>(FAKE_WIDTH, FAKE_HEIGHT);
55 #else
56     auto recordingCanvas = std::make_shared<Drawing::RecordingCanvas>(FAKE_WIDTH, FAKE_HEIGHT);
57 #endif
58     PostTaskToRSRecord(recordingCanvas, node, visitor);
59     auto drawCallList = recordingCanvas->GetDrawCmdList();
60     std::shared_ptr<Media::PixelMap> pixelmap = CreatePixelMapByNode(node);
61     if (pixelmap == nullptr) {
62         RS_LOGE("RSUniUICapture::TakeLocalCapture: pixelmap == nullptr!");
63         return nullptr;
64     }
65 #ifndef USE_ROSEN_DRAWING
66     auto skSurface = CreateSurface(pixelmap);
67     if (skSurface == nullptr) {
68         return nullptr;
69     }
70     auto canvas = std::make_shared<RSPaintFilterCanvas>(skSurface.get());
71 #else
72     auto drSurface = CreateSurface(pixelmap);
73     if (drSurface == nullptr) {
74         return nullptr;
75     }
76     auto canvas = std::make_shared<RSPaintFilterCanvas>(drSurface.get());
77 #endif
78     drawCallList->Playback(*canvas);
79     return pixelmap;
80 }
81 
CreatePixelMapByNode(std::shared_ptr<RSRenderNode> node) const82 std::shared_ptr<Media::PixelMap> RSUniUICapture::CreatePixelMapByNode(std::shared_ptr<RSRenderNode> node) const
83 {
84     int pixmapWidth = node->GetRenderProperties().GetBoundsWidth();
85     int pixmapHeight = node->GetRenderProperties().GetBoundsHeight();
86     Media::InitializationOptions opts;
87     opts.size.width = ceil(pixmapWidth * scaleX_);
88     opts.size.height = ceil(pixmapHeight * scaleY_);
89     return Media::PixelMap::Create(opts);
90 }
91 
92 #ifndef USE_ROSEN_DRAWING
CreateSurface(const std::shared_ptr<Media::PixelMap> & pixelmap) const93 sk_sp<SkSurface> RSUniUICapture::CreateSurface(const std::shared_ptr<Media::PixelMap>& pixelmap) const
94 {
95     if (pixelmap == nullptr) {
96         RS_LOGE("RSUniUICapture::CreateSurface: pixelmap == nullptr");
97         return nullptr;
98     }
99     auto address = const_cast<uint32_t*>(pixelmap->GetPixel32(0, 0));
100     if (address == nullptr) {
101         RS_LOGE("RSUniUICapture::CreateSurface: address == nullptr");
102         return nullptr;
103     }
104     SkImageInfo info = SkImageInfo::Make(pixelmap->GetWidth(), pixelmap->GetHeight(),
105         kRGBA_8888_SkColorType, kPremul_SkAlphaType);
106     return SkSurface::MakeRasterDirect(info, address, pixelmap->GetRowBytes());
107 }
108 #else
CreateSurface(const std::shared_ptr<Media::PixelMap> & pixelmap) const109 std::shared_ptr<Drawing::Surface> RSUniUICapture::CreateSurface(
110     const std::shared_ptr<Media::PixelMap>& pixelmap) const
111 {
112     if (pixelmap == nullptr) {
113         RS_LOGE("RSUniUICapture::CreateSurface: pixelmap == nullptr");
114         return nullptr;
115     }
116     auto address = const_cast<uint32_t*>(pixelmap->GetPixel32(0, 0));
117     if (address == nullptr) {
118         RS_LOGE("RSUniUICapture::CreateSurface: address == nullptr");
119         return nullptr;
120     }
121 
122     Drawing::Bitmap bitmap;
123     Drawing::BitmapFormat format { Drawing::COLORTYPE_RGBA_8888, Drawing::ALPHATYPE_PREMUL };
124     bitmap.Build(pixelmap->GetWidth(), pixelmap->GetHeight(), format);
125     bitmap.SetPixels(address);
126 
127     std::shared_ptr<Drawing::Surface> surface = std::make_shared<Drawing::Surface>();
128     surface->Bind(bitmap);
129     return surface;
130 }
131 #endif
132 
RSUniUICaptureVisitor(NodeId nodeId,float scaleX,float scaleY)133 RSUniUICapture::RSUniUICaptureVisitor::RSUniUICaptureVisitor(NodeId nodeId, float scaleX, float scaleY)
134     : nodeId_(nodeId), scaleX_(scaleX), scaleY_(scaleY)
135 {
136     renderEngine_ = RSMainThread::Instance()->GetRenderEngine();
137     isUniRender_ = RSUniRenderJudgement::IsUniRender();
138     auto node = RSMainThread::Instance()->GetContext().GetNodeMap().GetRenderNode<RSRenderNode>(nodeId_);
139     if (node == nullptr) {
140         RS_LOGE("RSUniUICapture::TakeLocalCapture node is nullptr return");
141         return;
142     }
143     const auto& targetNodeProperty = node->GetRenderProperties();
144     auto targetNodeGeoPtr = (targetNodeProperty.GetBoundsGeometry());
145 #ifndef USE_ROSEN_DRAWING
146     captureMatrix_.setScaleX(scaleX_);
147     captureMatrix_.setScaleY(scaleY_);
148     SkMatrix invertMatrix;
149     if (targetNodeGeoPtr->GetAbsMatrix().invert(&invertMatrix)) {
150         captureMatrix_.preConcat(invertMatrix);
151     }
152 #else
153     captureMatrix_.Set(Drawing::Matrix::Index::SCALE_X, scaleX_);
154     captureMatrix_.Set(Drawing::Matrix::Index::SCALE_X, scaleY_);
155     Drawing::Matrix invertMatrix;
156     if (targetNodeGeoPtr->GetAbsMatrix().Invert(invertMatrix)) {
157         captureMatrix_.PreConcat(invertMatrix);
158     }
159 #endif
160 }
161 
162 #ifndef USE_ROSEN_DRAWING
PostTaskToRSRecord(std::shared_ptr<RSRecordingCanvas> canvas,std::shared_ptr<RSRenderNode> node,std::shared_ptr<RSUniUICaptureVisitor> visitor)163 void RSUniUICapture::PostTaskToRSRecord(std::shared_ptr<RSRecordingCanvas> canvas,
164 #else
165 void RSUniUICapture::PostTaskToRSRecord(std::shared_ptr<Drawing::RecordingCanvas> canvas,
166 #endif
167     std::shared_ptr<RSRenderNode> node, std::shared_ptr<RSUniUICaptureVisitor> visitor)
168 {
169     std::function<void()> recordingDrawCall = [canvas, node, visitor]() -> void {
170         visitor->SetCanvas(canvas);
171         if (!node->IsOnTheTree()) {
172             node->ApplyModifiers();
173             node->Prepare(visitor);
174         }
175         node->Process(visitor);
176     };
177     RSMainThread::Instance()->PostSyncTask(recordingDrawCall);
178 }
179 
180 #ifndef USE_ROSEN_DRAWING
SetCanvas(std::shared_ptr<RSRecordingCanvas> canvas)181 void RSUniUICapture::RSUniUICaptureVisitor::SetCanvas(std::shared_ptr<RSRecordingCanvas> canvas)
182 {
183     if (canvas == nullptr) {
184         RS_LOGE("RSUniUICaptureVisitor::SetCanvas: canvas == nullptr");
185         return;
186     }
187     canvas_ = std::make_shared<RSPaintFilterCanvas>(canvas.get());
188     canvas_->scale(scaleX_, scaleY_);
189 }
190 #else
SetCanvas(std::shared_ptr<Drawing::RecordingCanvas> canvas)191 void RSUniUICapture::RSUniUICaptureVisitor::SetCanvas(std::shared_ptr<Drawing::RecordingCanvas> canvas)
192 {
193     if (canvas == nullptr) {
194         RS_LOGE("RSUniUICaptureVisitor::SetCanvas: canvas == nullptr");
195         return;
196     }
197     canvas_ = std::make_shared<RSPaintFilterCanvas>(canvas.get());
198     canvas_->Scale(scaleX_, scaleY_);
199 }
200 #endif
201 
ProcessChildren(RSRenderNode & node)202 void RSUniUICapture::RSUniUICaptureVisitor::ProcessChildren(RSRenderNode& node)
203 {
204     for (auto& child : node.GetSortedChildren()) {
205         child->Process(shared_from_this());
206     }
207 }
208 
ProcessRootRenderNode(RSRootRenderNode & node)209 void RSUniUICapture::RSUniUICaptureVisitor::ProcessRootRenderNode(RSRootRenderNode& node)
210 {
211     if (!node.ShouldPaint()) {
212         RS_LOGD("RSUniUICaptureVisitor::ProcessRootRenderNode, no need process");
213         return;
214     }
215 
216     if (!canvas_) {
217         RS_LOGE("RSUniUICaptureVisitor::ProcessRootRenderNode, canvas is nullptr");
218         return;
219     }
220 
221 #ifndef USE_ROSEN_DRAWING
222     canvas_->save();
223     ProcessCanvasRenderNode(node);
224     canvas_->restore();
225 #else
226     canvas_->Save();
227     ProcessCanvasRenderNode(node);
228     canvas_->Restore();
229 #endif
230 }
231 
ProcessCanvasRenderNode(RSCanvasRenderNode & node)232 void RSUniUICapture::RSUniUICaptureVisitor::ProcessCanvasRenderNode(RSCanvasRenderNode& node)
233 {
234     if (!node.ShouldPaint()) {
235         RS_LOGD("RSUniUICaptureVisitor::ProcessCanvasRenderNode, no need process");
236         return;
237     }
238     if (!canvas_) {
239         RS_LOGE("RSUniUICaptureVisitor::ProcessCanvasRenderNode, canvas is nullptr");
240         return;
241     }
242     if (node.GetId() == nodeId_) {
243         // When drawing nodes, canvas will offset the bounds value, so we will move in reverse here first
244         const auto& property = node.GetRenderProperties();
245         auto geoPtr = (property.GetBoundsGeometry());
246 #ifndef USE_ROSEN_DRAWING
247         SkMatrix relativeMatrix = SkMatrix::I();
248         relativeMatrix.setScaleX(scaleX_);
249         relativeMatrix.setScaleY(scaleY_);
250         SkMatrix invertMatrix;
251         if (geoPtr->GetMatrix().invert(&invertMatrix)) {
252             relativeMatrix.preConcat(invertMatrix);
253         }
254         canvas_->setMatrix(relativeMatrix);
255 #else
256         Drawing::Matrix relativeMatrix = Drawing::Matrix();
257         relativeMatrix.Set(Drawing::Matrix::Index::SCALE_X, scaleX_);
258         relativeMatrix.Set(Drawing::Matrix::Index::SCALE_Y, scaleY_);
259         Drawing::Matrix invertMatrix;
260         if (geoPtr->GetMatrix().Invert(invertMatrix)) {
261             relativeMatrix.PreConcat(invertMatrix);
262         }
263         canvas_->SetMatrix(relativeMatrix);
264 #endif
265     }
266     node.ProcessRenderBeforeChildren(*canvas_);
267     if (node.GetType() == RSRenderNodeType::CANVAS_DRAWING_NODE) {
268         auto canvasDrawingNode = node.ReinterpretCastTo<RSCanvasDrawingRenderNode>();
269         if (!node.IsOnTheTree()) {
270             canvasDrawingNode->ProcessRenderContents(*canvas_);
271         }
272 #ifndef USE_ROSEN_DRAWING
273         SkBitmap bitmap;
274         bitmap = canvasDrawingNode->GetBitmap();
275 #ifndef NEW_SKIA
276         canvas_->drawBitmap(
277             bitmap, node.GetRenderProperties().GetBoundsPositionX(), node.GetRenderProperties().GetBoundsPositionY());
278 #else
279         canvas_->drawImage(bitmap.asImage(), node.GetRenderProperties().GetBoundsPositionX(),
280             node.GetRenderProperties().GetBoundsPositionY());
281 #endif
282 #else
283         Drawing::Bitmap bitmap;
284         canvasDrawingNode->GetBitmap(bitmap);
285         canvas_->DrawBitmap(bitmap, node.GetRenderProperties().GetBoundsPositionX(),
286             node.GetRenderProperties().GetBoundsPositionY());
287 #endif
288     } else {
289         node.ProcessRenderContents(*canvas_);
290     }
291     ProcessChildren(node);
292     node.ProcessRenderAfterChildren(*canvas_);
293 }
294 
ProcessEffectRenderNode(RSEffectRenderNode & node)295 void RSUniUICapture::RSUniUICaptureVisitor::ProcessEffectRenderNode(RSEffectRenderNode& node)
296 {
297     if (!node.ShouldPaint()) {
298         RS_LOGD("RSUniUICapture::RSUniUICaptureVisitor::ProcessEffectRenderNode, no need process");
299         return;
300     }
301     if (!canvas_) {
302         RS_LOGE("RSUniUICapture::RSUniUICaptureVisitor::ProcessEffectRenderNode, canvas is nullptr");
303         return;
304     }
305     node.ProcessRenderBeforeChildren(*canvas_);
306     ProcessChildren(node);
307     node.ProcessRenderAfterChildren(*canvas_);
308 }
309 
ProcessSurfaceRenderNode(RSSurfaceRenderNode & node)310 void RSUniUICapture::RSUniUICaptureVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node)
311 {
312     if (canvas_ == nullptr) {
313         RS_LOGE("RSUniUICaptureVisitor::ProcessSurfaceRenderNode, canvas is nullptr");
314         return;
315     }
316 
317     if (!node.ShouldPaint()) {
318         RS_LOGD("RSUniUICaptureVisitor::ProcessSurfaceRenderNode node: %" PRIu64 " invisible", node.GetId());
319         return;
320     }
321     if (isUniRender_) {
322         ProcessSurfaceRenderNodeWithUni(node);
323     } else {
324         ProcessSurfaceViewWithoutUni(node);
325     }
326 }
327 
ProcessSurfaceRenderNodeWithUni(RSSurfaceRenderNode & node)328 void RSUniUICapture::RSUniUICaptureVisitor::ProcessSurfaceRenderNodeWithUni(RSSurfaceRenderNode& node)
329 {
330     auto geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
331     if (geoPtr == nullptr) {
332         RS_LOGI(
333             "RSUniUICaptureVisitor::ProcessSurfaceRenderNode node:%" PRIu64 ", get geoPtr failed", node.GetId());
334         return;
335     }
336 #ifndef USE_ROSEN_DRAWING
337     RSAutoCanvasRestore acr(canvas_);
338 #else
339     Drawing::AutoCanvasRestore acr(*canvas_, true);
340 #endif
341     canvas_->MultiplyAlpha(node.GetRenderProperties().GetAlpha());
342     ProcessSurfaceViewWithUni(node);
343 }
344 
ProcessSurfaceViewWithUni(RSSurfaceRenderNode & node)345 void RSUniUICapture::RSUniUICaptureVisitor::ProcessSurfaceViewWithUni(RSSurfaceRenderNode& node)
346 {
347 #ifndef USE_ROSEN_DRAWING
348     canvas_->save();
349 #else
350     canvas_->Save();
351 #endif
352 
353     const auto& property = node.GetRenderProperties();
354     auto geoPtr = (property.GetBoundsGeometry());
355     if (!geoPtr) {
356         RS_LOGE("RSUniUICaptureVisitor::ProcessSurfaceViewWithUni node:%" PRIu64 ", get geoPtr failed",
357             node.GetId());
358         return;
359     }
360 #ifndef USE_ROSEN_DRAWING
361     canvas_->setMatrix(captureMatrix_);
362     canvas_->concat(geoPtr->GetAbsMatrix());
363 #else
364     canvas_->SetMatrix(captureMatrix_);
365     canvas_->ConcatMatrix(geoPtr->GetAbsMatrix());
366 #endif
367 
368     bool isSelfDrawingSurface = node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE;
369     const RectF absBounds = { 0, 0, property.GetBoundsWidth(), property.GetBoundsHeight() };
370     RRect absClipRRect = RRect(absBounds, property.GetCornerRadius());
371     if (isSelfDrawingSurface) {
372         RSPropertiesPainter::DrawShadow(property, *canvas_, &absClipRRect);
373     }
374 #ifndef USE_ROSEN_DRAWING
375     canvas_->save();
376     if (isSelfDrawingSurface && !property.GetCornerRadius().IsZero()) {
377         canvas_->clipRRect(RSPropertiesPainter::RRect2SkRRect(absClipRRect), true);
378     } else {
379         canvas_->clipRect(SkRect::MakeWH(property.GetBoundsWidth(), property.GetBoundsHeight()));
380     }
381 #else
382     canvas_->Save();
383     if (isSelfDrawingSurface && !property.GetCornerRadius().IsZero()) {
384         canvas_->ClipRoundRect(RSPropertiesPainter::RRect2DrawingRRect(absClipRRect),
385             Drawing::ClipOp::INTERSECT, true);
386     } else {
387         canvas_->ClipRect(Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight()),
388             Drawing::ClipOp::INTERSECT, false);
389     }
390 #endif
391     if (isSelfDrawingSurface) {
392         RSPropertiesPainter::DrawBackground(property, *canvas_);
393         RSPropertiesPainter::DrawMask(property, *canvas_);
394         RSPropertiesPainter::DrawFilter(property, *canvas_, FilterType::BACKGROUND_FILTER);
395     } else {
396 #ifndef USE_ROSEN_DRAWING
397         auto backgroundColor = static_cast<SkColor>(property.GetBackgroundColor().AsArgbInt());
398         if (SkColorGetA(backgroundColor) != SK_AlphaTRANSPARENT) {
399             canvas_->drawColor(backgroundColor);
400         }
401     }
402     canvas_->restore();
403 #else
404         auto backgroundColor = static_cast<Drawing::ColorQuad>(property.GetBackgroundColor().AsArgbInt());
405         if (Drawing::Color::ColorQuadGetA(backgroundColor) != Drawing::Color::COLOR_TRANSPARENT) {
406             canvas_->Clear(backgroundColor);
407         }
408     }
409     canvas_->Restore();
410 #endif
411     if (node.GetBuffer() != nullptr) {
412         auto params = RSUniRenderUtil::CreateBufferDrawParam(node, true);
413         renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
414     }
415     if (isSelfDrawingSurface) {
416         RSPropertiesPainter::DrawFilter(property, *canvas_, FilterType::FOREGROUND_FILTER);
417         RSPropertiesPainter::DrawLinearGradientBlurFilter(property, *canvas_);
418     }
419 #ifndef USE_ROSEN_DRAWING
420     canvas_->restore();
421 #else
422     canvas_->Restore();
423 #endif
424     ProcessChildren(node);
425 }
426 
ProcessSurfaceViewWithoutUni(RSSurfaceRenderNode & node)427 void RSUniUICapture::RSUniUICaptureVisitor::ProcessSurfaceViewWithoutUni(RSSurfaceRenderNode& node)
428 {
429 #ifndef USE_ROSEN_DRAWING
430     SkMatrix translateMatrix;
431     auto parentPtr = node.GetParent().lock();
432     if (parentPtr != nullptr && parentPtr->IsInstanceOf<RSSurfaceRenderNode>()) {
433         // calculate the offset from this node's parent, and perform translate.
434         auto parentNode = std::static_pointer_cast<RSSurfaceRenderNode>(parentPtr);
435         const float parentNodeTranslateX = parentNode->GetTotalMatrix().getTranslateX();
436         const float parentNodeTranslateY = parentNode->GetTotalMatrix().getTranslateY();
437         const float thisNodetranslateX = node.GetTotalMatrix().getTranslateX();
438         const float thisNodetranslateY = node.GetTotalMatrix().getTranslateY();
439         translateMatrix.preTranslate(
440             thisNodetranslateX - parentNodeTranslateX, thisNodetranslateY - parentNodeTranslateY);
441     }
442     if (node.GetChildrenCount() > 0) {
443         if (node.GetId() != nodeId_) {
444             canvas_->concat(translateMatrix);
445         }
446         const auto saveCnt = canvas_->save();
447         ProcessChildren(node);
448         canvas_->restoreToCount(saveCnt);
449         if (node.GetBuffer() != nullptr) {
450             // in node's local coordinate.
451             auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, true, false, true, false);
452             renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
453         }
454     } else {
455         canvas_->save();
456         if (node.GetId() != nodeId_) {
457             canvas_->concat(translateMatrix);
458         }
459         if (node.GetBuffer() != nullptr) {
460             // in node's local coordinate.
461             auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, true, false, true, false);
462             renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
463         }
464         canvas_->restore();
465     }
466 #else
467     Drawing::Matrix translateMatrix;
468     auto parentPtr = node.GetParent().lock();
469     if (parentPtr != nullptr && parentPtr->IsInstanceOf<RSSurfaceRenderNode>()) {
470         // calculate the offset from this node's parent, and perform translate.
471         auto parentNode = std::static_pointer_cast<RSSurfaceRenderNode>(parentPtr);
472         const float parentNodeTranslateX = parentNode->GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_X);
473         const float parentNodeTranslateY = parentNode->GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_Y);
474         const float thisNodetranslateX = node.GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_X);
475         const float thisNodetranslateY = node.GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_Y);
476         translateMatrix.PreTranslate(
477             thisNodetranslateX - parentNodeTranslateX, thisNodetranslateY - parentNodeTranslateY);
478     }
479     if (node.GetChildrenCount() > 0) {
480         if (node.GetId() != nodeId_) {
481             canvas_->ConcatMatrix(translateMatrix);
482         }
483         const auto saveCnt = canvas_->GetSaveCount();
484         canvas_->Save();
485         ProcessChildren(node);
486         canvas_->RestoreToCount(saveCnt);
487         if (node.GetBuffer() != nullptr) {
488             // in node's local coordinate.
489             auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, true, false, false, false);
490             renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
491         }
492     } else {
493         canvas_->Save();
494         if (node.GetId() != nodeId_) {
495             canvas_->ConcatMatrix(translateMatrix);
496         }
497         if (node.GetBuffer() != nullptr) {
498             // in node's local coordinate.
499             auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, true, false, false, false);
500             renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
501         }
502         canvas_->Restore();
503     }
504 #endif
505 }
506 
PrepareChildren(RSRenderNode & node)507 void RSUniUICapture::RSUniUICaptureVisitor::PrepareChildren(RSRenderNode& node)
508 {
509     node.ApplyChildrenModifiers();
510     for (auto& child : node.GetSortedChildren()) {
511         child->Prepare(shared_from_this());
512     }
513 }
514 
PrepareCanvasRenderNode(RSCanvasRenderNode & node)515 void RSUniUICapture::RSUniUICaptureVisitor::PrepareCanvasRenderNode(RSCanvasRenderNode& node)
516 {
517     auto dirtyManager = std::make_shared<RSDirtyRegionManager>();
518     node.Update(*dirtyManager, nullptr, false);
519     PrepareChildren(node);
520 }
521 
PrepareSurfaceRenderNode(RSSurfaceRenderNode & node)522 void RSUniUICapture::RSUniUICaptureVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
523 {
524     auto dirtyManager = std::make_shared<RSDirtyRegionManager>();
525     node.Update(*dirtyManager, nullptr, false);
526     PrepareChildren(node);
527 }
528 
PrepareRootRenderNode(RSRootRenderNode & node)529 void RSUniUICapture::RSUniUICaptureVisitor::PrepareRootRenderNode(RSRootRenderNode& node)
530 {
531     PrepareCanvasRenderNode(node);
532 }
533 
PrepareEffectRenderNode(RSEffectRenderNode & node)534 void RSUniUICapture::RSUniUICaptureVisitor::PrepareEffectRenderNode(RSEffectRenderNode& node)
535 {
536     auto dirtyManager = std::make_shared<RSDirtyRegionManager>();
537     node.Update(*dirtyManager, nullptr, false);
538     PrepareChildren(node);
539 }
540 
541 } // namespace Rosen
542 } // namespace OHOS
543