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