• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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_surface_capture_task.h"
17 
18 #include <memory>
19 #include <sys/mman.h>
20 
21 #ifndef USE_ROSEN_DRAWING
22 #include "include/core/SkCanvas.h"
23 #include "include/core/SkMatrix.h"
24 #include "include/core/SkRect.h"
25 #else
26 #include "draw/surface.h"
27 #include "draw/color.h"
28 #endif
29 #include "rs_trace.h"
30 
31 #include "common/rs_obj_abs_geometry.h"
32 #include "memory/rs_tag_tracker.h"
33 #include "pipeline/rs_base_render_node.h"
34 #include "pipeline/rs_canvas_drawing_render_node.h"
35 #include "pipeline/rs_cold_start_thread.h"
36 #include "pipeline/rs_display_render_node.h"
37 #include "pipeline/rs_divided_render_util.h"
38 #include "pipeline/rs_effect_render_node.h"
39 #include "pipeline/rs_main_thread.h"
40 #include "pipeline/rs_render_service_connection.h"
41 #include "pipeline/rs_root_render_node.h"
42 #include "pipeline/rs_surface_render_node.h"
43 #include "pipeline/rs_uni_render_judgement.h"
44 #include "pipeline/rs_uni_render_util.h"
45 #include "platform/common/rs_log.h"
46 #include "platform/drawing/rs_surface.h"
47 #include "render/rs_skia_filter.h"
48 #include "screen_manager/rs_screen_manager.h"
49 #include "screen_manager/rs_screen_mode_info.h"
50 
51 namespace OHOS {
52 namespace Rosen {
Run()53 std::unique_ptr<Media::PixelMap> RSSurfaceCaptureTask::Run()
54 {
55     if (ROSEN_EQ(scaleX_, 0.f) || ROSEN_EQ(scaleY_, 0.f) || scaleX_ < 0.f || scaleY_ < 0.f) {
56         RS_LOGE("RSSurfaceCaptureTask::Run: SurfaceCapture scale is invalid.");
57         return nullptr;
58     }
59     auto node = RSMainThread::Instance()->GetContext().GetNodeMap().GetRenderNode(nodeId_);
60     if (node == nullptr) {
61         RS_LOGE("RSSurfaceCaptureTask::Run: node is nullptr");
62         return nullptr;
63     }
64     std::unique_ptr<Media::PixelMap> pixelmap;
65     visitor_ = std::make_shared<RSSurfaceCaptureVisitor>(scaleX_, scaleY_, RSUniRenderJudgement::IsUniRender());
66     if (auto surfaceNode = node->ReinterpretCastTo<RSSurfaceRenderNode>()) {
67         RS_LOGD("RSSurfaceCaptureTask::Run: Into SURFACE_NODE SurfaceRenderNodeId:[%" PRIu64 "]", node->GetId());
68         pixelmap = CreatePixelMapBySurfaceNode(surfaceNode, visitor_->IsUniRender());
69         visitor_->IsDisplayNode(false);
70     } else if (auto displayNode = node->ReinterpretCastTo<RSDisplayRenderNode>()) {
71         RS_LOGD("RSSurfaceCaptureTask::Run: Into DISPLAY_NODE DisplayRenderNodeId:[%" PRIu64 "]", node->GetId());
72         visitor_->SetHasingSecurityLayer(FindSecurityLayer());
73         pixelmap = CreatePixelMapByDisplayNode(displayNode, visitor_->IsUniRender(),
74             visitor_->GetHasingSecurityLayer());
75         visitor_->IsDisplayNode(true);
76     } else {
77         RS_LOGE("RSSurfaceCaptureTask::Run: Invalid RSRenderNodeType!");
78         return nullptr;
79     }
80     if (pixelmap == nullptr) {
81         RS_LOGE("RSSurfaceCaptureTask::Run: pixelmap == nullptr!");
82         return nullptr;
83     }
84 #ifndef USE_ROSEN_DRAWING
85 #if defined(RS_ENABLE_GL)
86 #if defined(NEW_RENDER_CONTEXT)
87     auto drawingContext = RSMainThread::Instance()->GetRenderEngine()->GetDrawingContext();
88 #ifdef NEW_SKIA
89     GrDirectContext* grContext = drawingContext != nullptr ? drawingContext->GetDrawingContext() : nullptr;
90 #else
91     GrContext* grContext = drawingContext != nullptr ? drawingContext->GetDrawingContext() : nullptr;
92 #endif
93 #else
94     auto renderContext = RSMainThread::Instance()->GetRenderEngine()->GetRenderContext();
95 #ifdef NEW_SKIA
96     GrDirectContext* grContext = renderContext != nullptr ? renderContext->GetGrContext() : nullptr;
97 #else
98     GrContext* grContext = renderContext != nullptr ? renderContext->GetGrContext() : nullptr;
99 #endif
100 #endif
101     RSTagTracker tagTracker(grContext, node->GetId(), RSTagTracker::TAGTYPE::TAG_CAPTURE);
102 #endif
103 #endif
104 #ifndef USE_ROSEN_DRAWING
105     auto skSurface = CreateSurface(pixelmap);
106     if (skSurface == nullptr) {
107         RS_LOGE("RSSurfaceCaptureTask::Run: surface is nullptr!");
108         return nullptr;
109     }
110     visitor_->SetSurface(skSurface.get());
111 #else
112     auto surface = CreateSurface(pixelmap);
113     if (surface == nullptr) {
114         RS_LOGE("RSSurfaceCaptureTask::Run: surface is nullptr!");
115         return nullptr;
116     }
117     visitor_->SetSurface(surface.get());
118 #endif
119     node->Process(visitor_);
120 #if (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
121 #ifndef USE_ROSEN_DRAWING
122     sk_sp<SkImage> img(skSurface.get()->makeImageSnapshot());
123     if (!img) {
124         RS_LOGE("RSSurfaceCaptureTask::Run: img is nullptr");
125         return nullptr;
126     }
127     if (!CopyDataToPixelMap(img, pixelmap)) {
128         RS_LOGE("RSSurfaceCaptureTask::Run: CopyDataToPixelMap failed");
129         return nullptr;
130     }
131 #else
132     std::shared_ptr<Drawing::Image> img(surface.get()->GetImageSnapshot());
133     if (!img) {
134         RS_LOGE("RSSurfaceCaptureTask::Run: img is nullptr");
135         return nullptr;
136     }
137 
138     auto size = pixelmap->GetRowBytes() * pixelmap->GetHeight();
139     if (size < 0) {
140         RS_LOGE("RSSurfaceCaptureTask::Run: pxielmap size is invalid");
141         return nullptr;
142     }
143 
144     auto data = (uint8_t *)malloc(size);
145     if (data == nullptr) {
146         RS_LOGE("RSSurfaceCaptureTask::Run: data is nullptr");
147         return nullptr;
148     }
149     Drawing::BitmapFormat format { Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL };
150     Drawing::Bitmap bitmap;
151     bitmap.Build(pixelmap->GetWidth(), pixelmap->GetHeight(), format);
152     bitmap.SetPixels(data);
153     if (!img->ReadPixels(bitmap, 0, 0)) {
154         RS_LOGE("RSSurfaceCaptureTask::Run: readPixels failed");
155         free(data);
156         data = nullptr;
157         return nullptr;
158     }
159     pixelmap->SetPixelsAddr(data, nullptr, pixelmap->GetRowBytes() * pixelmap->GetHeight(),
160         Media::AllocatorType::HEAP_ALLOC, nullptr);
161 #endif // USE_ROSEN_DRAWING
162 #endif
163     if (auto displayNode = node->ReinterpretCastTo<RSDisplayRenderNode>()) {
164         if (visitor_->IsUniRender()) {
165             auto rotation = displayNode->GetRotation();
166             if (rotation == ScreenRotation::ROTATION_90) {
167                 pixelmap->rotate(static_cast<int32_t>(90)); // 90 degrees
168             }
169             if (rotation == ScreenRotation::ROTATION_270) {
170                 pixelmap->rotate(static_cast<int32_t>(270)); // 270 degrees
171             }
172             RS_LOGD("RSSurfaceCaptureTask::Run: PixelmapRotation: %d", static_cast<int32_t>(rotation));
173         }
174     }
175     return pixelmap;
176 }
177 
CreatePixelMapBySurfaceNode(std::shared_ptr<RSSurfaceRenderNode> node,bool isUniRender)178 std::unique_ptr<Media::PixelMap> RSSurfaceCaptureTask::CreatePixelMapBySurfaceNode(
179     std::shared_ptr<RSSurfaceRenderNode> node, bool isUniRender)
180 {
181     if (node == nullptr) {
182         RS_LOGE("RSSurfaceCaptureTask::CreatePixelMapBySurfaceNode: node == nullptr");
183         return nullptr;
184     }
185     if (!isUniRender && node->GetBuffer() == nullptr) {
186         RS_LOGE("RSSurfaceCaptureTask::CreatePixelMapBySurfaceNode: node GetBuffer == nullptr");
187         return nullptr;
188     }
189     int pixmapWidth = node->GetRenderProperties().GetBoundsWidth();
190     int pixmapHeight = node->GetRenderProperties().GetBoundsHeight();
191     Media::InitializationOptions opts;
192     opts.size.width = ceil(pixmapWidth * scaleX_);
193     opts.size.height = ceil(pixmapHeight * scaleY_);
194     RS_LOGD("RSSurfaceCaptureTask::CreatePixelMapBySurfaceNode: origin pixelmap width is [%u], height is [%u], "\
195         "created pixelmap width is [%u], height is [%u], the scale is scaleY:[%f], scaleY:[%f]",
196         pixmapWidth, pixmapHeight, opts.size.width, opts.size.height, scaleX_, scaleY_);
197     return Media::PixelMap::Create(opts);
198 }
199 
CreatePixelMapByDisplayNode(std::shared_ptr<RSDisplayRenderNode> node,bool isUniRender,bool hasSecurityLayer)200 std::unique_ptr<Media::PixelMap> RSSurfaceCaptureTask::CreatePixelMapByDisplayNode(
201     std::shared_ptr<RSDisplayRenderNode> node, bool isUniRender, bool hasSecurityLayer)
202 {
203     if (node == nullptr) {
204         RS_LOGE("RSSurfaceCaptureTask::CreatePixelMapByDisplayNode: node is nullptr");
205         return nullptr;
206     }
207     uint64_t screenId = node->GetScreenId();
208     RSScreenModeInfo screenModeInfo;
209     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
210     if (!screenManager) {
211         RS_LOGE("RSSurfaceCaptureTask::CreatePixelMapByDisplayNode: screenManager is nullptr!");
212         return nullptr;
213     }
214     auto screenInfo = screenManager->QueryScreenInfo(screenId);
215     uint32_t pixmapWidth = screenInfo.width;
216     uint32_t pixmapHeight = screenInfo.height;
217     if (!isUniRender) {
218         auto rotation = node->GetRotation();
219         if (rotation == ScreenRotation::ROTATION_90 || rotation == ScreenRotation::ROTATION_270) {
220             std::swap(pixmapWidth, pixmapHeight);
221         }
222     }
223     Media::InitializationOptions opts;
224     opts.size.width = ceil(pixmapWidth * scaleX_);
225     opts.size.height = ceil(pixmapHeight * scaleY_);
226     RS_LOGD("RSSurfaceCaptureTask::CreatePixelMapByDisplayNode: origin pixelmap width is [%u], height is [%u], "\
227         "created pixelmap width is [%u], height is [%u], the scale is scaleY:[%f], scaleY:[%f]",
228         pixmapWidth, pixmapHeight, opts.size.width, opts.size.height, scaleX_, scaleY_);
229     return Media::PixelMap::Create(opts);
230 }
231 
232 #ifndef USE_ROSEN_DRAWING
CreateSurface(const std::unique_ptr<Media::PixelMap> & pixelmap)233 sk_sp<SkSurface> RSSurfaceCaptureTask::CreateSurface(const std::unique_ptr<Media::PixelMap>& pixelmap)
234 {
235     if (pixelmap == nullptr) {
236         RS_LOGE("RSSurfaceCaptureTask::CreateSurface: pixelmap == nullptr");
237         return nullptr;
238     }
239     auto address = const_cast<uint32_t*>(pixelmap->GetPixel32(0, 0));
240     if (address == nullptr) {
241         RS_LOGE("RSSurfaceCaptureTask::CreateSurface: address == nullptr");
242         return nullptr;
243     }
244     SkImageInfo info = SkImageInfo::Make(pixelmap->GetWidth(), pixelmap->GetHeight(),
245         kRGBA_8888_SkColorType, kPremul_SkAlphaType);
246 #if (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
247 #if defined(NEW_RENDER_CONTEXT)
248     auto drawingContext = RSMainThread::Instance()->GetRenderEngine()->GetDrawingContext();
249     if (drawingContext == nullptr) {
250         RS_LOGE("RSSurfaceCaptureTask::CreateSurface: renderContext is nullptr");
251         return nullptr;
252     }
253     drawingContext->SetUpDrawingContext();
254     return SkSurface::MakeRenderTarget(drawingContext->GetDrawingContext(), SkBudgeted::kNo, info);
255 #else
256     auto renderContext = RSMainThread::Instance()->GetRenderEngine()->GetRenderContext();
257     if (renderContext == nullptr) {
258         RS_LOGE("RSSurfaceCaptureTask::CreateSurface: renderContext is nullptr");
259         return nullptr;
260     }
261     renderContext->SetUpGrContext();
262     return SkSurface::MakeRenderTarget(renderContext->GetGrContext(), SkBudgeted::kNo, info);
263 #endif
264 #endif
265     return SkSurface::MakeRasterDirect(info, address, pixelmap->GetRowBytes());
266 }
267 
CopyDataToPixelMap(sk_sp<SkImage> img,const std::unique_ptr<Media::PixelMap> & pixelmap)268 bool RSSurfaceCaptureTask::CopyDataToPixelMap(sk_sp<SkImage> img, const std::unique_ptr<Media::PixelMap>& pixelmap)
269 {
270     auto size = pixelmap->GetRowBytes() * pixelmap->GetHeight();
271     SkImageInfo info = SkImageInfo::Make(pixelmap->GetWidth(), pixelmap->GetHeight(),
272         kRGBA_8888_SkColorType, kPremul_SkAlphaType);
273 #ifdef ROSEN_OHOS
274     int fd = AshmemCreate("RSSurfaceCapture Data", size);
275     if (fd < 0) {
276         RS_LOGE("RSSurfaceCaptureTask::CopyDataToPixelMap AshmemCreate fd < 0");
277         return false;
278     }
279     int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE);
280     if (result < 0) {
281         RS_LOGE("RSSurfaceCaptureTask::CopyDataToPixelMap AshmemSetProt error");
282         ::close(fd);
283         return false;
284     }
285     void* ptr = ::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
286     auto data = static_cast<uint8_t*>(ptr);
287     if (ptr == MAP_FAILED || ptr == nullptr) {
288         RS_LOGE("RSSurfaceCaptureTask::CopyDataToPixelMap data is nullptr");
289         ::close(fd);
290         return false;
291     }
292 
293     if (!img->readPixels(info, data, pixelmap->GetRowBytes(), 0, 0)) {
294         RS_LOGE("RSSurfaceCaptureTask::CopyDataToPixelMap readPixels failed");
295         ::close(fd);
296         return false;
297     }
298     void* fdPtr = new int32_t();
299     *static_cast<int32_t*>(fdPtr) = fd;
300     pixelmap->SetPixelsAddr(data, fdPtr, size, Media::AllocatorType::SHARE_MEM_ALLOC, nullptr);
301 #else
302     auto data = (uint8_t *)malloc(size);
303     if (data == nullptr) {
304         RS_LOGE("RSSurfaceCaptureTask::CopyDataToPixelMap data is nullptr");
305         return false;
306     }
307     if (!img->readPixels(info, data, pixelmap->GetRowBytes(), 0, 0)) {
308         RS_LOGE("RSSurfaceCaptureTask::CopyDataToPixelMap readPixels failed");
309         free(data);
310         data = nullptr;
311         return false;
312     }
313     pixelmap->SetPixelsAddr(data, nullptr, size, Media::AllocatorType::HEAP_ALLOC, nullptr);
314 #endif
315     return true;
316 }
317 #else
CreateSurface(const std::unique_ptr<Media::PixelMap> & pixelmap)318 std::shared_ptr<Drawing::Surface> RSSurfaceCaptureTask::CreateSurface(const std::unique_ptr<Media::PixelMap>& pixelmap)
319 {
320     if (pixelmap == nullptr) {
321         RS_LOGE("RSSurfaceCaptureTask::CreateSurface: pixelmap == nullptr");
322         return nullptr;
323     }
324     auto address = const_cast<uint32_t*>(pixelmap->GetPixel32(0, 0));
325     if (address == nullptr) {
326         RS_LOGE("RSSurfaceCaptureTask::CreateSurface: address == nullptr");
327         return nullptr;
328     }
329     Drawing::BitmapFormat format { Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL };
330     auto bitmap = std::make_shared<Drawing::Bitmap>();
331     bitmap->Build(pixelmap->GetWidth(), pixelmap->GetHeight(), format);
332     bitmap->SetPixels(address);
333 #if (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
334     auto renderEngine = RSMainThread::Instance()->GetRenderEngine();
335     if (renderEngine == nullptr) {
336         RS_LOGE("RSSurfaceCaptureTask::CreateSurface: renderEngine is nullptr");
337         return nullptr;
338     }
339     auto renderContext = renderEngine->GetRenderContext();
340     if (renderContext == nullptr) {
341         RS_LOGE("RSSurfaceCaptureTask::CreateSurface: renderContext is nullptr");
342         return nullptr;
343     }
344     renderContext->SetUpGpuContext();
345     auto gpuContext = renderContext->GetDrGPUContext();
346     if (gpuContext == nullptr) {
347         RS_LOGE("RSSurfaceCaptureTask::CreateSurface: Drawing::GPUContext is nullptr");
348         return nullptr;
349     }
350     auto image = std::make_shared<Drawing::Image>();
351     if (!image->BuildFromBitmap(*gpuContext, *bitmap)) {
352         RS_LOGE("RSSurfaceCaptureTask::CreateSurface: Drawing::Image is nullptr");
353         return nullptr;
354     }
355     auto surface = std::make_shared<Drawing::Surface>();
356     if (!surface->Bind(*image)) {
357         if (!surface->Bind(*bitmap)) {
358             RS_LOGE("RSSurfaceCaptureTask::CreateSurface: Drawing::Surface is nullptr");
359             return nullptr;
360         }
361     }
362     return surface;
363 #else
364     auto surface = std::make_shared<Drawing::Surface>();
365     if (!surface->Bind(*bitmap)) {
366         RS_LOGE("RSSurfaceCaptureTask::CreateSurface: Drawing::Surface is nullptr");
367         return nullptr;
368     }
369     return surface;
370 #endif
371 }
372 #endif
373 
FindSecurityLayer()374 bool RSSurfaceCaptureTask::FindSecurityLayer()
375 {
376     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
377     bool hasSecurityLayer = false;
378     nodeMap.TraverseSurfaceNodes([this, &hasSecurityLayer](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode)
379         mutable {
380         if (surfaceNode == nullptr || !surfaceNode->IsOnTheTree()) {
381             return;
382         }
383         if (surfaceNode->GetSecurityLayer()) {
384             hasSecurityLayer = true;
385             return;
386         }
387     });
388     return hasSecurityLayer;
389 }
390 
RSSurfaceCaptureVisitor(float scaleX,float scaleY,bool isUniRender)391 RSSurfaceCaptureVisitor::RSSurfaceCaptureVisitor(float scaleX, float scaleY, bool isUniRender)
392     : scaleX_(scaleX), scaleY_(scaleY), isUniRender_(isUniRender)
393 {
394     renderEngine_ = RSMainThread::Instance()->GetRenderEngine();
395     isUIFirst_ = RSMainThread::Instance()->IsUIFirstOn();
396 }
397 
398 #ifndef USE_ROSEN_DRAWING
SetSurface(SkSurface * surface)399 void RSSurfaceCaptureVisitor::SetSurface(SkSurface* surface)
400 {
401     if (surface == nullptr) {
402         RS_LOGE("RSSurfaceCaptureVisitor::SetSurface: surface == nullptr");
403         return;
404     }
405     canvas_ = std::make_unique<RSPaintFilterCanvas>(surface);
406     canvas_->scale(scaleX_, scaleY_);
407 }
408 #else
SetSurface(Drawing::Surface * surface)409 void RSSurfaceCaptureVisitor::SetSurface(Drawing::Surface* surface)
410 {
411     if (surface == nullptr) {
412         RS_LOGE("RSSurfaceCaptureVisitor::SetSurface: surface == nullptr");
413         return;
414     }
415     canvas_ = std::make_unique<RSPaintFilterCanvas>(surface);
416     canvas_->Scale(scaleX_, scaleY_);
417 }
418 #endif
419 
ProcessChildren(RSRenderNode & node)420 void RSSurfaceCaptureVisitor::ProcessChildren(RSRenderNode &node)
421 {
422     for (auto& child : node.GetSortedChildren()) {
423         child->Process(shared_from_this());
424     }
425 }
426 
ProcessDisplayRenderNode(RSDisplayRenderNode & node)427 void RSSurfaceCaptureVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode &node)
428 {
429     RS_TRACE_NAME("RSSurfaceCaptureVisitor::ProcessDisplayRenderNode:" +
430         std::to_string(node.GetId()));
431     RS_LOGD("RSSurfaceCaptureVisitor::ProcessDisplayRenderNode child size:[%d] total size:[%d]",
432         node.GetChildrenCount(), node.GetSortedChildren().size());
433 
434     // Mirror Display is unable to snapshot.
435     if (node.IsMirrorDisplay()) {
436         RS_LOGW("RSSurfaceCaptureVisitor::ProcessDisplayRenderNode: \
437             Mirror Display(id:[%" PRIu64 "])", node.GetId());
438         return;
439     }
440 
441     if (canvas_ == nullptr) {
442         RS_LOGE("RSSurfaceCaptureVisitor::ProcessDisplayRenderNode: Canvas is null!");
443         return;
444     }
445 
446     if (IsUniRender()) {
447         FindHardwareEnabledNodes();
448         if (hasSecurityLayer_) {
449             RS_LOGD("RSSurfaceCaptureVisitor::ProcessDisplayRenderNode: \
450                 process RSDisplayRenderNode(id:[%" PRIu64 "]) Not using UniRender buffer.", node.GetId());
451             ProcessChildren(node);
452         } else {
453             if (node.GetBuffer() == nullptr) {
454                 RS_LOGE("RSSurfaceCaptureVisitor::ProcessDisplayRenderNode: buffer is null!");
455                 return;
456             }
457 
458             RS_LOGD("RSSurfaceCaptureVisitor::ProcessDisplayRenderNode: \
459                 process RSDisplayRenderNode(id:[%" PRIu64 "]) using UniRender buffer.", node.GetId());
460 
461             if (hardwareEnabledNodes_.size() != 0) {
462                 AdjustZOrderAndDrawSurfaceNode();
463             }
464 
465             auto params = RSUniRenderUtil::CreateBufferDrawParam(node, false);
466 
467             // Screen capture considering color inversion
468             ColorFilterMode colorFilterMode = renderEngine_->GetColorFilterMode();
469             if (colorFilterMode >= ColorFilterMode::INVERT_COLOR_ENABLE_MODE &&
470                 colorFilterMode <= ColorFilterMode::INVERT_DALTONIZATION_TRITANOMALY_MODE) {
471                 RS_LOGD("RSSurfaceCaptureVisitor::ProcessDisplayRenderNode: \
472                     SetColorFilterModeToPaint mode:%d.", static_cast<int32_t>(colorFilterMode));
473                 RSBaseRenderUtil::SetColorFilterModeToPaint(colorFilterMode, params.paint);
474             }
475 
476             renderEngine_->DrawDisplayNodeWithParams(*canvas_, node, params);
477         }
478     } else {
479         ProcessChildren(node);
480     }
481 }
482 
ProcessEffectRenderNode(RSEffectRenderNode & node)483 void RSSurfaceCaptureVisitor::ProcessEffectRenderNode(RSEffectRenderNode& node)
484 {
485     if (!IsUniRender()) {
486         return;
487     }
488     if (!node.ShouldPaint()) {
489         RS_LOGD("RSSurfaceCaptureVisitor::ProcessEffectRenderNode, no need process");
490         return;
491     }
492     if (!canvas_) {
493         RS_LOGE("RSSurfaceCaptureVisitor::ProcessEffectRenderNode, canvas is nullptr");
494         return;
495     }
496     node.ProcessRenderBeforeChildren(*canvas_);
497     ProcessChildren(node);
498     node.ProcessRenderAfterChildren(*canvas_);
499 }
500 
FindHardwareEnabledNodes()501 void RSSurfaceCaptureVisitor::FindHardwareEnabledNodes()
502 {
503     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
504     nodeMap.TraverseSurfaceNodes([this](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
505         if (surfaceNode == nullptr || !surfaceNode->IsOnTheTree()) {
506             return;
507         }
508         if (surfaceNode->IsLastFrameHardwareEnabled() && surfaceNode->GetBuffer() != nullptr) {
509             hardwareEnabledNodes_.emplace_back(surfaceNode);
510         }
511     });
512 }
513 
AdjustZOrderAndDrawSurfaceNode()514 void RSSurfaceCaptureVisitor::AdjustZOrderAndDrawSurfaceNode()
515 {
516     if (!RSSystemProperties::GetHardwareComposerEnabled()) {
517         RS_LOGW("RSSurfaceCaptureVisitor::AdjustZOrderAndDrawSurfaceNode: \
518             HardwareComposer is not enabled.");
519         return;
520     }
521 
522     // sort the surfaceNodes by ZOrder
523     std::stable_sort(
524         hardwareEnabledNodes_.begin(), hardwareEnabledNodes_.end(), [](const auto& first, const auto& second) -> bool {
525             return first->GetGlobalZOrder() < second->GetGlobalZOrder();
526         });
527 
528     // draw hardwareEnabledNodes
529     for (auto& surfaceNode : hardwareEnabledNodes_) {
530         if (surfaceNode->IsLastFrameHardwareEnabled() && surfaceNode->GetBuffer() != nullptr) {
531 #ifndef USE_ROSEN_DRAWING
532             RSAutoCanvasRestore acr(canvas_);
533 #else
534             Drawing::AutoCanvasRestore acr(*canvas_, true);
535 #endif
536             CaptureSurfaceInDisplayWithUni(*surfaceNode);
537         }
538     }
539 }
540 
541 #ifndef USE_ROSEN_DRAWING
CaptureSingleSurfaceNodeWithUni(RSSurfaceRenderNode & node)542 void RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithUni(RSSurfaceRenderNode& node)
543 {
544     const auto& property = node.GetRenderProperties();
545     auto geoPtr = (property.GetBoundsGeometry());
546     if (!geoPtr) {
547         RS_LOGE("RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithUni node:%" PRIu64 ", get geoPtr failed",
548             node.GetId());
549         return;
550     }
551 
552     bool isSelfDrawingSurface = node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE;
553     if (isSelfDrawingSurface) {
554         canvas_->save();
555     }
556 
557     if (node.IsAppWindow()) {
558         // When CaptureSingleSurfaceNodeWithUni, we should consider scale factor of canvas_ and
559         // child nodes (self-drawing surfaceNode) of AppWindow should use relative coordinates
560         // which is the node relative to the upper-left corner of the window.
561         // So we have to get the invert matrix of AppWindow here and apply it to canvas_
562         // when we calculate the position of self-drawing surfaceNode.
563         captureMatrix_.setScaleX(scaleX_);
564         captureMatrix_.setScaleY(scaleY_);
565         SkMatrix invertMatrix;
566         if (geoPtr->GetAbsMatrix().invert(&invertMatrix)) {
567             captureMatrix_.preConcat(invertMatrix);
568         }
569     } else if (!node.IsStartingWindow()) {
570         canvas_->setMatrix(captureMatrix_);
571         canvas_->concat(geoPtr->GetAbsMatrix());
572     }
573 
574     const RectF absBounds = {0, 0, property.GetBoundsWidth(), property.GetBoundsHeight()};
575     RRect absClipRRect = RRect(absBounds, property.GetCornerRadius());
576     if (isSelfDrawingSurface) {
577         RSPropertiesPainter::DrawShadow(property, *canvas_, &absClipRRect);
578     }
579     canvas_->save();
580     if (isSelfDrawingSurface && !property.GetCornerRadius().IsZero()) {
581         canvas_->clipRRect(RSPropertiesPainter::RRect2SkRRect(absClipRRect), true);
582     } else {
583         canvas_->clipRect(SkRect::MakeWH(property.GetBoundsWidth(), property.GetBoundsHeight()));
584     }
585     if (node.GetSecurityLayer()) {
586         RS_LOGD("RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithUni: \
587             process RSSurfaceRenderNode(id:[%" PRIu64 "]) clear white since it is security layer.",
588             node.GetId());
589         canvas_->clear(SK_ColorWHITE);
590         canvas_->restore(); // restore clipRect
591         canvas_->restore(); // restore translate and concat
592         return;
593     }
594 
595     if (isSelfDrawingSurface) {
596         RSPropertiesPainter::DrawBackground(property, *canvas_);
597         RSPropertiesPainter::DrawMask(property, *canvas_);
598         RSPropertiesPainter::DrawFilter(property, *canvas_, FilterType::BACKGROUND_FILTER);
599     } else {
600         auto backgroundColor = static_cast<SkColor>(property.GetBackgroundColor().AsArgbInt());
601         if (SkColorGetA(backgroundColor) != SK_AlphaTRANSPARENT) {
602             canvas_->drawColor(backgroundColor);
603         }
604     }
605     canvas_->restore();
606     if (!node.IsAppWindow() && node.GetBuffer() != nullptr) {
607         auto params = RSUniRenderUtil::CreateBufferDrawParam(node, false);
608         renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
609     }
610     if (isSelfDrawingSurface) {
611         RSPropertiesPainter::DrawFilter(property, *canvas_, FilterType::FOREGROUND_FILTER);
612         RSPropertiesPainter::DrawLinearGradientBlurFilter(property, *canvas_);
613     }
614 
615     if (isSelfDrawingSurface) {
616         canvas_->restore();
617     }
618 
619     if (isUIFirst_ && RSUniRenderUtil::HandleCaptureNode(node, *canvas_)) {
620         RS_LOGD("RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithUni: \
621             process RSSurfaceRenderNode [%s, %" PRIu64 "] use cache texture.",
622             node.GetName().c_str(), node.GetId());
623         return;
624     }
625 
626     if (node.IsAppWindow() && RSColdStartManager::Instance().IsColdStartThreadRunning(node.GetId()) &&
627         node.GetCachedImage() != nullptr) {
628         RS_LOGD("RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithUni: DrawCachedImage.");
629         RSUniRenderUtil::DrawCachedImage(node, *canvas_, node.GetCachedImage());
630     } else {
631         ProcessChildren(node);
632     }
633 }
634 #else
CaptureSingleSurfaceNodeWithUni(RSSurfaceRenderNode & node)635 void RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithUni(RSSurfaceRenderNode& node)
636 {
637     const auto& property = node.GetRenderProperties();
638     auto geoPtr = (property.GetBoundsGeometry());
639     if (!geoPtr) {
640         RS_LOGE("RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithUni node:%" PRIu64 ", get geoPtr failed",
641             node.GetId());
642         return;
643     }
644     if (canvas_ == nullptr) {
645         RS_LOGE("RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithUni: canvas_ is nullptr.");
646         return;
647     }
648 
649     bool isSelfDrawingSurface = node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE;
650     if (isSelfDrawingSurface) {
651         canvas_->Save();
652     }
653 
654     if (node.IsAppWindow()) {
655         // When CaptureSingleSurfaceNodeWithUni, we should consider scale factor of canvas_ and
656         // child nodes (self-drawing surfaceNode) of AppWindow should use relative coordinates
657         // which is the node relative to the upper-left corner of the window.
658         // So we have to get the invert matrix of AppWindow here and apply it to canvas_
659         // when we calculate the position of self-drawing surfaceNode.
660         captureMatrix_.Set(Drawing::Matrix::Index::SCALE_X, scaleX_);
661         captureMatrix_.Set(Drawing::Matrix::Index::SCALE_Y, scaleY_);
662         Drawing::Matrix invertMatrix;
663         if (geoPtr->GetAbsMatrix().Invert(invertMatrix)) {
664             captureMatrix_.PreConcat(invertMatrix);
665         }
666     } else if (!node.IsStartingWindow()) {
667         canvas_->SetMatrix(captureMatrix_);
668         canvas_->ConcatMatrix(geoPtr->GetAbsMatrix());
669     }
670 
671     const RectF absBounds = {0, 0, property.GetBoundsWidth(), property.GetBoundsHeight()};
672     RRect absClipRRect = RRect(absBounds, property.GetCornerRadius());
673     if (isSelfDrawingSurface) {
674         RSPropertiesPainter::DrawShadow(property, *canvas_, &absClipRRect);
675     }
676     canvas_->Save();
677     if (isSelfDrawingSurface && !property.GetCornerRadius().IsZero()) {
678         canvas_->ClipRoundRect(
679             RSPropertiesPainter::RRect2DrawingRRect(absClipRRect), Drawing::ClipOp::INTERSECT, true);
680     } else {
681         canvas_->ClipRect(Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight()),
682             Drawing::ClipOp::INTERSECT, true);
683     }
684     if (node.GetSecurityLayer()) {
685         RS_LOGD("RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithUni: \
686             process RSSurfaceRenderNode(id:[%" PRIu64 "]) clear white since it is security layer.",
687             node.GetId());
688         canvas_->Clear(Drawing::Color::COLOR_WHITE);
689         canvas_->Restore(); // restore clipRect
690         canvas_->Restore(); // restore translate and concat
691         return;
692     }
693 
694     if (isSelfDrawingSurface) {
695         RSPropertiesPainter::DrawBackground(property, *canvas_);
696         RSPropertiesPainter::DrawMask(property, *canvas_);
697         RSPropertiesPainter::DrawFilter(property, *canvas_, FilterType::BACKGROUND_FILTER);
698     } else {
699         auto backgroundColor = static_cast<Drawing::ColorQuad>(property.GetBackgroundColor().AsArgbInt());
700         if (Drawing::Color::ColorQuadGetA(backgroundColor) != Drawing::Color::COLOR_TRANSPARENT) {
701             canvas_->Clear(backgroundColor);
702         }
703     }
704     canvas_->Restore();
705     if (!node.IsAppWindow() && node.GetBuffer() != nullptr) {
706         auto params = RSUniRenderUtil::CreateBufferDrawParam(node, false);
707         renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
708     }
709     if (isSelfDrawingSurface) {
710         RSPropertiesPainter::DrawFilter(property, *canvas_, FilterType::FOREGROUND_FILTER);
711         RSPropertiesPainter::DrawLinearGradientBlurFilter(property, *canvas_);
712     }
713 
714     if (isSelfDrawingSurface) {
715         canvas_->Restore();
716     }
717 
718     if (isUIFirst_ && RSUniRenderUtil::HandleCaptureNode(node, *canvas_)) {
719         RS_LOGD("RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithUni: \
720             process RSSurfaceRenderNode [%s, %" PRIu64 "] use cache texture.",
721             node.GetName().c_str(), node.GetId());
722         return;
723     }
724 
725     if (node.IsAppWindow() && RSColdStartManager::Instance().IsColdStartThreadRunning(node.GetId()) &&
726         node.GetCachedImage() != nullptr) {
727         RS_LOGD("RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithUni: DrawCachedImage.");
728         RSUniRenderUtil::DrawCachedImage(node, *canvas_, node.GetCachedImage());
729     } else {
730         ProcessChildren(node);
731     }
732 }
733 #endif
734 
735 #ifndef USE_ROSEN_DRAWING
CaptureSurfaceInDisplayWithUni(RSSurfaceRenderNode & node)736 void RSSurfaceCaptureVisitor::CaptureSurfaceInDisplayWithUni(RSSurfaceRenderNode& node)
737 {
738     if (node.GetSecurityLayer()) {
739         RS_LOGD("RSSurfaceCaptureVisitor::CaptureSurfaceInDisplayWithUni: \
740             process RSSurfaceRenderNode(id:[%" PRIu64 "]) paused since it is security layer.",
741             node.GetId());
742         return;
743     }
744 
745     if (isUIFirst_ && RSUniRenderUtil::HandleSubThreadNode(node, *canvas_)) {
746         RS_LOGD("RSSurfaceCaptureVisitor::CaptureSurfaceInDisplayWithUni: \
747             process RSSurfaceRenderNode [%s, %" PRIu64 "] use cache texture.",
748             node.GetName().c_str(), node.GetId());
749         return;
750     }
751     bool isSelfDrawingSurface = node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE;
752 
753     const auto& property = node.GetRenderProperties();
754     auto geoPtr = (property.GetBoundsGeometry());
755     if (geoPtr) {
756         canvas_->setMatrix(geoPtr->GetAbsMatrix());
757     }
758 
759     if (isSelfDrawingSurface) {
760         canvas_->save();
761     }
762 
763     const RectF absBounds = {0, 0, property.GetBoundsWidth(), property.GetBoundsHeight()};
764     RRect absClipRRect = RRect(absBounds, property.GetCornerRadius());
765     RSPropertiesPainter::DrawShadow(property, *canvas_, &absClipRRect, node.IsLeashWindow());
766     if (!property.GetCornerRadius().IsZero()) {
767         canvas_->clipRRect(RSPropertiesPainter::RRect2SkRRect(absClipRRect), true);
768     } else {
769         canvas_->clipRect(SkRect::MakeWH(property.GetBoundsWidth(), property.GetBoundsHeight()));
770     }
771     auto backgroundColor = static_cast<SkColor>(property.GetBackgroundColor().AsArgbInt());
772     if (SkColorGetA(backgroundColor) != SK_AlphaTRANSPARENT) {
773         canvas_->drawColor(backgroundColor);
774     }
775     RSPropertiesPainter::DrawMask(property, *canvas_);
776 
777     RSPropertiesPainter::DrawFilter(property, *canvas_, FilterType::BACKGROUND_FILTER);
778     if (isSelfDrawingSurface) {
779         canvas_->restore();
780     }
781 
782     if (!node.IsAppWindow() && node.GetBuffer() != nullptr) {
783         auto params = RSUniRenderUtil::CreateBufferDrawParam(node, false);
784         renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
785     }
786 
787     ProcessChildren(node);
788     RSPropertiesPainter::DrawFilter(property, *canvas_, FilterType::FOREGROUND_FILTER);
789     RSPropertiesPainter::DrawLinearGradientBlurFilter(property, *canvas_);
790     DrawWatermarkIfNeed(property.GetBoundsWidth(), property.GetBoundsHeight());
791 }
792 #else
CaptureSurfaceInDisplayWithUni(RSSurfaceRenderNode & node)793 void RSSurfaceCaptureVisitor::CaptureSurfaceInDisplayWithUni(RSSurfaceRenderNode& node)
794 {
795     if (node.GetSecurityLayer()) {
796         RS_LOGD("RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::CaptureSurfaceInDisplayWithUni: \
797             process RSSurfaceRenderNode(id:[%" PRIu64 "]) paused since it is security layer.",
798             node.GetId());
799         return;
800     }
801 
802     if (isUIFirst_ && RSUniRenderUtil::HandleSubThreadNode(node, *canvas_)) {
803         RS_LOGD("RSSurfaceCaptureVisitor::CaptureSurfaceInDisplayWithUni: \
804             process RSSurfaceRenderNode [%s, %" PRIu64 "] use cache texture.",
805             node.GetName().c_str(), node.GetId());
806         return;
807     }
808     bool isSelfDrawingSurface = node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE;
809 
810     const auto& property = node.GetRenderProperties();
811     auto geoPtr = (property.GetBoundsGeometry());
812     if (geoPtr) {
813         canvas_->SetMatrix(geoPtr->GetAbsMatrix());
814     }
815 
816     if (isSelfDrawingSurface) {
817         canvas_->Save();
818     }
819 
820     const RectF absBounds = {0, 0, property.GetBoundsWidth(), property.GetBoundsHeight()};
821     RRect absClipRRect = RRect(absBounds, property.GetCornerRadius());
822     RSPropertiesPainter::DrawShadow(property, *canvas_, &absClipRRect, node.IsLeashWindow());
823     if (!property.GetCornerRadius().IsZero()) {
824         canvas_->ClipRoundRect(
825             RSPropertiesPainter::RRect2DrawingRRect(absClipRRect), Drawing::ClipOp::INTERSECT, true);
826     } else {
827         canvas_->ClipRect(Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight()),
828             Drawing::ClipOp::INTERSECT, false);
829     }
830     auto backgroundColor = static_cast<Drawing::ColorQuad>(property.GetBackgroundColor().AsArgbInt());
831     if (Drawing::Color::ColorQuadGetA(backgroundColor) != Drawing::Color::COLOR_TRANSPARENT) {
832         canvas_->Clear(backgroundColor);
833     }
834     RSPropertiesPainter::DrawMask(property, *canvas_);
835 
836     RSPropertiesPainter::DrawFilter(property, *canvas_, FilterType::BACKGROUND_FILTER);
837     if (isSelfDrawingSurface) {
838         canvas_->Restore();
839     }
840 
841     if (!node.IsAppWindow() && node.GetBuffer() != nullptr) {
842         canvas_->Save();
843         canvas_->SetMatrix(node.GetTotalMatrix());
844         auto params = RSUniRenderUtil::CreateBufferDrawParam(node, false);
845         renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
846         canvas_->Restore();
847     }
848 
849     ProcessChildren(node);
850     RSPropertiesPainter::DrawFilter(property, *canvas_, FilterType::FOREGROUND_FILTER);
851     RSPropertiesPainter::DrawLinearGradientBlurFilter(property, *canvas_);
852     DrawWatermarkIfNeed(property.GetBoundsWidth(), property.GetBoundsHeight());
853 }
854 #endif
855 
ProcessSurfaceRenderNodeWithUni(RSSurfaceRenderNode & node)856 void RSSurfaceCaptureVisitor::ProcessSurfaceRenderNodeWithUni(RSSurfaceRenderNode &node)
857 {
858     auto geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
859     if (geoPtr == nullptr) {
860         RS_LOGW("RSSurfaceCaptureVisitor::ProcessSurfaceRenderNode node:%" PRIu64 ", get geoPtr failed", node.GetId());
861         return;
862     }
863 
864 #ifndef USE_ROSEN_DRAWING
865     RSAutoCanvasRestore acr(canvas_);
866 #else
867     Drawing::AutoCanvasRestore acr(*canvas_, true);
868 #endif
869     canvas_->MultiplyAlpha(node.GetRenderProperties().GetAlpha());
870     if (isDisplayNode_) {
871         CaptureSurfaceInDisplayWithUni(node);
872     } else {
873         CaptureSingleSurfaceNodeWithUni(node);
874     }
875 }
876 
ProcessRootRenderNode(RSRootRenderNode & node)877 void RSSurfaceCaptureVisitor::ProcessRootRenderNode(RSRootRenderNode& node)
878 {
879     if (!RSUniRenderJudgement::IsUniRender()) {
880         return;
881     }
882     if (!node.ShouldPaint()) {
883         RS_LOGD("RSSurfaceCaptureVisitor::ProcessRootRenderNode, no need process");
884         return;
885     }
886 
887     if (!canvas_) {
888         RS_LOGE("RSSurfaceCaptureVisitor::ProcessRootRenderNode, canvas is nullptr");
889         return;
890     }
891 
892 #ifndef USE_ROSEN_DRAWING
893     SkAutoCanvasRestore acr(canvas_.get(), true);
894 #else
895     Drawing::AutoCanvasRestore acr(*canvas_.get(), true);
896 #endif
897     ProcessCanvasRenderNode(node);
898 }
899 
ProcessCanvasRenderNode(RSCanvasRenderNode & node)900 void RSSurfaceCaptureVisitor::ProcessCanvasRenderNode(RSCanvasRenderNode& node)
901 {
902     if (!IsUniRender()) {
903         return;
904     }
905     if (!node.ShouldPaint()) {
906         RS_LOGD("RSSurfaceCaptureVisitor::ProcessCanvasRenderNode, no need process");
907         return;
908     }
909     if (!canvas_) {
910         RS_LOGE("RSSurfaceCaptureVisitor::ProcessCanvasRenderNode, canvas is nullptr");
911         return;
912     }
913     if (auto drawingNode = node.ReinterpretCastTo<RSCanvasDrawingRenderNode>()) {
914 #ifndef USE_ROSEN_DRAWING
915         auto clearFunc = [id = UNI_MAIN_THREAD_INDEX](sk_sp<SkSurface> surface) {
916 #else
917         auto clearFunc = [id = UNI_MAIN_THREAD_INDEX](std::shared_ptr<Drawing::Surface> surface) {
918 #endif
919             // The second param is null, 0 is an invalid value.
920             sk_sp<SkSurface> tmpSurface = nullptr;
921             RSUniRenderUtil::ClearNodeCacheSurface(surface, tmpSurface, id, 0);
922         };
923         drawingNode->SetSurfaceClearFunc({ UNI_MAIN_THREAD_INDEX, clearFunc });
924     }
925     node.ProcessRenderBeforeChildren(*canvas_);
926     node.ProcessRenderContents(*canvas_);
927     ProcessChildren(node);
928     node.ProcessRenderAfterChildren(*canvas_);
929 }
930 
931 #ifndef USE_ROSEN_DRAWING
932 void RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithoutUni(RSSurfaceRenderNode& node)
933 {
934     SkMatrix translateMatrix;
935     auto parentPtr = node.GetParent().lock();
936     if (parentPtr != nullptr && parentPtr->IsInstanceOf<RSSurfaceRenderNode>()) {
937         // calculate the offset from this node's parent, and perform translate.
938         auto parentNode = std::static_pointer_cast<RSSurfaceRenderNode>(parentPtr);
939         const float parentNodeTranslateX = parentNode->GetTotalMatrix().getTranslateX();
940         const float parentNodeTranslateY = parentNode->GetTotalMatrix().getTranslateY();
941         const float thisNodetranslateX = node.GetTotalMatrix().getTranslateX();
942         const float thisNodetranslateY = node.GetTotalMatrix().getTranslateY();
943         translateMatrix.preTranslate(
944             thisNodetranslateX - parentNodeTranslateX, thisNodetranslateY - parentNodeTranslateY);
945     }
946     if (node.GetSecurityLayer()) {
947         RS_LOGD("RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithoutUni: \
948             process RSSurfaceRenderNode(id:[%" PRIu64 "]) clear white since it is security layer.",
949             node.GetId());
950         SkAutoCanvasRestore acr(canvas_.get(), true);
951         canvas_->concat(translateMatrix);
952         canvas_->clear(SK_ColorWHITE);
953         return;
954     }
955 
956     if (node.GetChildrenCount() > 0) {
957         canvas_->concat(translateMatrix);
958         const auto saveCnt = canvas_->save();
959         ProcessChildren(node);
960         canvas_->restoreToCount(saveCnt);
961         if (node.GetBuffer() != nullptr) {
962             // in node's local coordinate.
963             auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, true, false, false, false);
964             renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
965         }
966     } else {
967         SkAutoCanvasRestore acr(canvas_.get(), true);
968         canvas_->concat(translateMatrix);
969         if (node.GetBuffer() != nullptr) {
970             // in node's local coordinate.
971             auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, true, false, false, false);
972             renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
973         }
974     }
975 }
976 #else
977 void RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithoutUni(RSSurfaceRenderNode& node)
978 {
979     Drawing::Matrix translateMatrix;
980     auto parentPtr = node.GetParent().lock();
981     if (parentPtr != nullptr && parentPtr->IsInstanceOf<RSSurfaceRenderNode>()) {
982         // calculate the offset from this node's parent, and perform translate.
983         auto parentNode = std::static_pointer_cast<RSSurfaceRenderNode>(parentPtr);
984         const float parentNodeTranslateX = parentNode->GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_X);
985         const float parentNodeTranslateY = parentNode->GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_Y);
986         const float thisNodetranslateX = node.GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_X);
987         const float thisNodetranslateY = node.GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_Y);
988         translateMatrix.PreTranslate(
989             thisNodetranslateX - parentNodeTranslateX, thisNodetranslateY - parentNodeTranslateY);
990     }
991     if (canvas_ == nullptr) {
992         RS_LOGE("RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithoutUni: canvas_ is nullptr.");
993         return;
994     }
995     if (node.GetSecurityLayer()) {
996         RS_LOGD("RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithoutUni: \
997             process RSSurfaceRenderNode(id:[%" PRIu64 "]) clear white since it is security layer.",
998             node.GetId());
999         Drawing::AutoCanvasRestore acr(*canvas_.get(), true);
1000         canvas_->ConcatMatrix(translateMatrix);
1001         canvas_->Clear(Drawing::Color::COLOR_WHITE);
1002         return;
1003     }
1004 
1005     if (node.GetChildrenCount() > 0) {
1006         canvas_->ConcatMatrix(translateMatrix);
1007         const auto saveCnt = canvas_->GetSaveCount();
1008         canvas_->Save();
1009         ProcessChildren(node);
1010         canvas_->RestoreToCount(saveCnt);
1011         if (node.GetBuffer() != nullptr) {
1012             // in node's local coordinate.
1013             auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, true, false, false, false);
1014             renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
1015         }
1016     } else {
1017         Drawing::AutoCanvasRestore acr(*canvas_.get(), true);
1018         canvas_->ConcatMatrix(translateMatrix);
1019         if (node.GetBuffer() != nullptr) {
1020             // in node's local coordinate.
1021             auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, true, false, false, false);
1022             renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
1023         }
1024         canvas_->Restore();
1025     }
1026 }
1027 #endif
1028 
1029 void RSSurfaceCaptureVisitor::CaptureSurfaceInDisplayWithoutUni(RSSurfaceRenderNode& node)
1030 {
1031     if (node.GetSecurityLayer()) {
1032         RS_LOGD("RSSurfaceCaptureVisitor::CaptureSurfaceInDisplayWithoutUni: \
1033             process RSSurfaceRenderNode(id:[%" PRIu64 "]) paused since it is security layer.",
1034             node.GetId());
1035         return;
1036     }
1037     ProcessChildren(node);
1038     if (node.GetBuffer() != nullptr) {
1039         // in display's coordinate.
1040         auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, false, false, false, false);
1041         renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
1042     }
1043 }
1044 
1045 void RSSurfaceCaptureVisitor::ProcessSurfaceRenderNodeWithoutUni(RSSurfaceRenderNode& node)
1046 {
1047     if (isDisplayNode_) {
1048         CaptureSurfaceInDisplayWithoutUni(node);
1049     } else {
1050         CaptureSingleSurfaceNodeWithoutUni(node);
1051     }
1052 }
1053 
1054 void RSSurfaceCaptureVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode &node)
1055 {
1056     RS_TRACE_NAME("RSSurfaceCaptureVisitor::Process:" + node.GetName());
1057 
1058     if (canvas_ == nullptr) {
1059         RS_LOGE("RSSurfaceCaptureVisitor::ProcessSurfaceRenderNode, canvas is nullptr");
1060         return;
1061     }
1062 
1063     if (!node.ShouldPaint()) {
1064         RS_LOGD("RSSurfaceCaptureVisitor::ProcessSurfaceRenderNode node: %" PRIu64 " invisible", node.GetId());
1065         return;
1066     }
1067 
1068     // execute security layer in each case, ignore display snapshot and set it white for surface snapshot
1069     if (IsUniRender()) {
1070         ProcessSurfaceRenderNodeWithUni(node);
1071     } else {
1072         ProcessSurfaceRenderNodeWithoutUni(node);
1073     }
1074 }
1075 
1076 void RSSurfaceCaptureVisitor::DrawWatermarkIfNeed(float screenWidth, float screenHeight)
1077 {
1078     if (RSMainThread::Instance()->GetWatermarkFlag()) {
1079 #ifndef USE_ROSEN_DRAWING
1080         sk_sp<SkImage> skImage = RSMainThread::Instance()->GetWatermarkImg();
1081         SkPaint rectPaint;
1082         auto skSrcRect = SkRect::MakeWH(skImage->width(), skImage->height());
1083         auto skDstRect = SkRect::MakeWH(screenWidth, screenHeight);
1084 #ifdef NEW_SKIA
1085         canvas_->drawImageRect(
1086             skImage, skSrcRect, skDstRect, SkSamplingOptions(),
1087             &rectPaint, SkCanvas::kStrict_SrcRectConstraint);
1088 #else
1089         canvas_->drawImageRect(skImage, skSrcRect, skDstRect, &rectPaint);
1090 #endif
1091 #else
1092         auto image = RSMainThread::Instance()->GetWatermarkImg();
1093         if (image == nullptr) {
1094             return;
1095         }
1096 
1097         auto srcRect = Drawing::Rect(0, 0, image->GetWidth(), image->GetHeight());
1098         auto dstRect = Drawing::Rect(0, 0, screenWidth, screenHeight);
1099         Drawing::Brush rectBrush;
1100         canvas_->AttachBrush(rectBrush);
1101         canvas_->DrawImageRect(*image, srcRect, dstRect, Drawing::SamplingOptions(),
1102             Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
1103         canvas_->DetachBrush();
1104 #endif
1105     }
1106 }
1107 } // namespace Rosen
1108 } // namespace OHOS
1109