• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 
20 #include "include/core/SkCanvas.h"
21 #include "include/core/SkMatrix.h"
22 #include "include/core/SkRect.h"
23 #include "rs_trace.h"
24 
25 #include "common/rs_obj_abs_geometry.h"
26 #include "pipeline/rs_base_render_node.h"
27 #include "pipeline/rs_cold_start_thread.h"
28 #include "pipeline/rs_display_render_node.h"
29 #include "pipeline/rs_divided_render_util.h"
30 #include "pipeline/rs_main_thread.h"
31 #include "pipeline/rs_render_service_connection.h"
32 #include "pipeline/rs_root_render_node.h"
33 #include "pipeline/rs_surface_render_node.h"
34 #include "pipeline/rs_uni_render_judgement.h"
35 #include "pipeline/rs_uni_render_util.h"
36 #include "platform/common/rs_log.h"
37 #include "platform/drawing/rs_surface.h"
38 #include "render/rs_skia_filter.h"
39 #include "screen_manager/rs_screen_manager.h"
40 #include "screen_manager/rs_screen_mode_info.h"
41 
42 namespace OHOS {
43 namespace Rosen {
Run()44 std::unique_ptr<Media::PixelMap> RSSurfaceCaptureTask::Run()
45 {
46     if (ROSEN_EQ(scaleX_, 0.f) || ROSEN_EQ(scaleY_, 0.f) || scaleX_ < 0.f || scaleY_ < 0.f) {
47         RS_LOGE("RSSurfaceCaptureTask::Run: SurfaceCapture scale is invalid.");
48         return nullptr;
49     }
50     auto node = RSMainThread::Instance()->GetContext().GetNodeMap().GetRenderNode(nodeId_);
51     if (node == nullptr) {
52         RS_LOGE("RSSurfaceCaptureTask::Run: node is nullptr");
53         return nullptr;
54     }
55     std::unique_ptr<Media::PixelMap> pixelmap;
56     std::shared_ptr<RSSurfaceCaptureVisitor> visitor = std::make_shared<RSSurfaceCaptureVisitor>(scaleX_, scaleY_,
57         RSMainThread::Instance()->IfUseUniVisitor());
58     if (auto surfaceNode = node->ReinterpretCastTo<RSSurfaceRenderNode>()) {
59         RS_LOGD("RSSurfaceCaptureTask::Run: Into SURFACE_NODE SurfaceRenderNodeId:[%" PRIu64 "]", node->GetId());
60         pixelmap = CreatePixelMapBySurfaceNode(surfaceNode, visitor->IsUniRender());
61         visitor->IsDisplayNode(false);
62     } else if (auto displayNode = node->ReinterpretCastTo<RSDisplayRenderNode>()) {
63         RS_LOGD("RSSurfaceCaptureTask::Run: Into DISPLAY_NODE DisplayRenderNodeId:[%" PRIu64 "]", node->GetId());
64         pixelmap = CreatePixelMapByDisplayNode(displayNode);
65         visitor->IsDisplayNode(true);
66     } else {
67         RS_LOGE("RSSurfaceCaptureTask::Run: Invalid RSRenderNodeType!");
68         return nullptr;
69     }
70     if (pixelmap == nullptr) {
71         RS_LOGE("RSSurfaceCaptureTask::Run: pixelmap == nullptr!");
72         return nullptr;
73     }
74     auto skSurface = CreateSurface(pixelmap);
75     if (skSurface == nullptr) {
76         RS_LOGE("RSSurfaceCaptureTask::Run: surface is nullptr!");
77         return nullptr;
78     }
79     visitor->SetSurface(skSurface.get());
80     node->Process(visitor);
81 #if (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
82     sk_sp<SkImage> img(skSurface.get()->makeImageSnapshot());
83     if (!img) {
84         RS_LOGE("RSSurfaceCaptureTask::Run: img is nullptr");
85         return nullptr;
86     }
87 
88     auto data = (uint8_t *)malloc(pixelmap->GetRowBytes() * pixelmap->GetHeight());
89     if (data == nullptr) {
90         RS_LOGE("RSSurfaceCaptureTask::Run: data is nullptr");
91         return nullptr;
92     }
93     SkImageInfo info = SkImageInfo::Make(pixelmap->GetWidth(), pixelmap->GetHeight(),
94         kRGBA_8888_SkColorType, kPremul_SkAlphaType);
95     if (!img->readPixels(info, data, pixelmap->GetRowBytes(), 0, 0)) {
96         RS_LOGE("RSSurfaceCaptureTask::Run: readPixels failed");
97         free(data);
98         data = nullptr;
99         return nullptr;
100     }
101     pixelmap->SetPixelsAddr(data, nullptr, pixelmap->GetRowBytes() * pixelmap->GetHeight(),
102         Media::AllocatorType::HEAP_ALLOC, nullptr);
103 #endif
104     return pixelmap;
105 }
106 
CreatePixelMapBySurfaceNode(std::shared_ptr<RSSurfaceRenderNode> node,bool isUniRender)107 std::unique_ptr<Media::PixelMap> RSSurfaceCaptureTask::CreatePixelMapBySurfaceNode(
108     std::shared_ptr<RSSurfaceRenderNode> node, bool isUniRender)
109 {
110     if (node == nullptr) {
111         RS_LOGE("CreatePixelMapBySurfaceNode: node == nullptr");
112         return nullptr;
113     }
114     if (!isUniRender && node->GetBuffer() == nullptr) {
115         RS_LOGE("CreatePixelMapBySurfaceNode: node GetBuffer == nullptr");
116         return nullptr;
117     }
118     int pixmapWidth = node->GetRenderProperties().GetBoundsWidth();
119     int pixmapHeight = node->GetRenderProperties().GetBoundsHeight();
120     Media::InitializationOptions opts;
121     opts.size.width = ceil(pixmapWidth * scaleX_);
122     opts.size.height = ceil(pixmapHeight * scaleY_);
123     RS_LOGD("RSSurfaceCaptureTask::CreatePixelMapBySurfaceNode: origin pixelmap width is [%u], height is [%u], "\
124         "created pixelmap width is [%u], height is [%u], the scale is scaleY:[%f], scaleY:[%f]",
125         pixmapWidth, pixmapHeight, opts.size.width, opts.size.height, scaleX_, scaleY_);
126     return Media::PixelMap::Create(opts);
127 }
128 
CreatePixelMapByDisplayNode(std::shared_ptr<RSDisplayRenderNode> node)129 std::unique_ptr<Media::PixelMap> RSSurfaceCaptureTask::CreatePixelMapByDisplayNode(
130     std::shared_ptr<RSDisplayRenderNode> node)
131 {
132     if (node == nullptr) {
133         RS_LOGE("RSSurfaceCaptureTask::CreatePixelMapByDisplayNode: node is nullptr");
134         return nullptr;
135     }
136     uint64_t screenId = node->GetScreenId();
137     RSScreenModeInfo screenModeInfo;
138     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
139     if (!screenManager) {
140         RS_LOGE("RSSurfaceCaptureTask::CreatePixelMapByDisplayNode: screenManager is nullptr!");
141         return nullptr;
142     }
143     auto screenInfo = screenManager->QueryScreenInfo(screenId);
144     uint32_t pixmapWidth = screenInfo.width;
145     uint32_t pixmapHeight = screenInfo.height;
146     auto rotation = node->GetRotation();
147     if (rotation == ScreenRotation::ROTATION_90 || rotation == ScreenRotation::ROTATION_270) {
148         std::swap(pixmapWidth, pixmapHeight);
149     }
150     Media::InitializationOptions opts;
151     opts.size.width = ceil(pixmapWidth * scaleX_);
152     opts.size.height = ceil(pixmapHeight * scaleY_);
153     RS_LOGD("RSSurfaceCaptureTask::CreatePixelMapByDisplayNode: origin pixelmap width is [%u], height is [%u], "\
154         "created pixelmap width is [%u], height is [%u], the scale is scaleY:[%f], scaleY:[%f]",
155         pixmapWidth, pixmapHeight, opts.size.width, opts.size.height, scaleX_, scaleY_);
156     return Media::PixelMap::Create(opts);
157 }
158 
CreateSurface(const std::unique_ptr<Media::PixelMap> & pixelmap)159 sk_sp<SkSurface> RSSurfaceCaptureTask::CreateSurface(const std::unique_ptr<Media::PixelMap>& pixelmap)
160 {
161     if (pixelmap == nullptr) {
162         RS_LOGE("RSSurfaceCaptureTask::CreateSurface: pixelmap == nullptr");
163         return nullptr;
164     }
165     auto address = const_cast<uint32_t*>(pixelmap->GetPixel32(0, 0));
166     if (address == nullptr) {
167         RS_LOGE("RSSurfaceCaptureTask::CreateSurface: address == nullptr");
168         return nullptr;
169     }
170     SkImageInfo info = SkImageInfo::Make(pixelmap->GetWidth(), pixelmap->GetHeight(),
171         kRGBA_8888_SkColorType, kPremul_SkAlphaType);
172 #if (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
173     auto renderContext = RSBaseRenderEngine::GetRenderContext();
174     if (renderContext == nullptr) {
175         RS_LOGE("RSSurfaceCaptureTask::CreateSurface: renderContext is nullptr");
176         return nullptr;
177     }
178     renderContext->SetUpGrContext();
179     return SkSurface::MakeRenderTarget(renderContext->GetGrContext(), SkBudgeted::kNo, info);
180 #endif
181     return SkSurface::MakeRasterDirect(info, address, pixelmap->GetRowBytes());
182 }
183 
RSSurfaceCaptureVisitor(float scaleX,float scaleY,bool isUniRender)184 RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::RSSurfaceCaptureVisitor(float scaleX, float scaleY, bool isUniRender)
185     : scaleX_(scaleX), scaleY_(scaleY), isUniRender_(isUniRender)
186 {
187     renderEngine_ = RSMainThread::Instance()->GetRenderEngine();
188 }
189 
SetSurface(SkSurface * surface)190 void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::SetSurface(SkSurface* surface)
191 {
192     if (surface == nullptr) {
193         RS_LOGE("RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::SetSurface: surface == nullptr");
194         return;
195     }
196     canvas_ = std::make_unique<RSPaintFilterCanvas>(surface);
197     canvas_->scale(scaleX_, scaleY_);
198 }
199 
ProcessBaseRenderNode(RSBaseRenderNode & node)200 void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::ProcessBaseRenderNode(RSBaseRenderNode &node)
201 {
202     for (auto& child : node.GetSortedChildren()) {
203         child->Process(shared_from_this());
204     }
205     // clear SortedChildren, it will be generated again in next frame
206     node.ResetSortedChildren();
207 }
208 
ProcessDisplayRenderNode(RSDisplayRenderNode & node)209 void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode &node)
210 {
211     RS_LOGD("RsDebug RSSurfaceCaptureVisitor::ProcessDisplayRenderNode child size:[%d] total size:[%d]",
212         node.GetChildrenCount(), node.GetSortedChildren().size());
213 
214     ProcessBaseRenderNode(node);
215 }
216 
CaptureSingleSurfaceNodeWithUni(RSSurfaceRenderNode & node)217 void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithUni(RSSurfaceRenderNode& node)
218 {
219     const auto& property = node.GetRenderProperties();
220     auto geoPtr = std::static_pointer_cast<RSObjAbsGeometry>(property.GetBoundsGeometry());
221     if (!geoPtr) {
222         RS_LOGE("RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithUni node:%" PRIu64 ", get geoPtr failed",
223             node.GetId());
224         return;
225     }
226 
227     canvas_->save();
228 
229     if (node.IsAppWindow()) {
230         // When CaptureSingleSurfaceNodeWithUni, we should consider scale factor of canvas_ and
231         // child nodes (self-drawing surfaceNode) of AppWindow should use relative coordinates
232         // which is the node relative to the upper-left corner of the window.
233         // So we have to get the invert matrix of AppWindow here and apply it to canvas_
234         // when we calculate the position of self-drawing surfaceNode.
235         captureMatrix_.setScaleX(scaleX_);
236         captureMatrix_.setScaleY(scaleY_);
237         SkMatrix invertMatrix;
238         if (geoPtr->GetAbsMatrix().invert(&invertMatrix)) {
239             captureMatrix_.preConcat(invertMatrix);
240         }
241     } else {
242         canvas_->setMatrix(captureMatrix_);
243         canvas_->concat(geoPtr->GetAbsMatrix());
244     }
245 
246     bool isSelfDrawingSurface = node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE;
247     const RectF absBounds = {0, 0, property.GetBoundsWidth(), property.GetBoundsHeight()};
248     RRect absClipRRect = RRect(absBounds, property.GetCornerRadius());
249     if (isSelfDrawingSurface) {
250         RSPropertiesPainter::DrawShadow(property, *canvas_, &absClipRRect);
251     }
252     canvas_->save();
253     if (isSelfDrawingSurface && !property.GetCornerRadius().IsZero()) {
254         canvas_->clipRRect(RSPropertiesPainter::RRect2SkRRect(absClipRRect), true);
255     } else {
256         canvas_->clipRect(SkRect::MakeWH(property.GetBoundsWidth(), property.GetBoundsHeight()));
257     }
258     if (node.GetSecurityLayer()) {
259         RS_LOGD("RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithUni: \
260             process RSSurfaceRenderNode(id:[%" PRIu64 "]) clear white since it is security layer.",
261             node.GetId());
262         canvas_->clear(SK_ColorWHITE);
263         canvas_->restore(); // restore clipRect
264         canvas_->restore(); // restore translate and concat
265         return;
266     }
267     if (isSelfDrawingSurface) {
268         RSPropertiesPainter::DrawBackground(property, *canvas_);
269         RSPropertiesPainter::DrawMask(property, *canvas_);
270         auto filter = std::static_pointer_cast<RSSkiaFilter>(property.GetBackgroundFilter());
271         if (filter != nullptr) {
272             auto skRectPtr = std::make_unique<SkRect>();
273             skRectPtr->setXYWH(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
274             RSPropertiesPainter::DrawFilter(property, *canvas_, filter, skRectPtr, canvas_->GetSurface());
275         }
276     } else {
277         auto backgroundColor = static_cast<SkColor>(property.GetBackgroundColor().AsArgbInt());
278         if (SkColorGetA(backgroundColor) != SK_AlphaTRANSPARENT) {
279             canvas_->drawColor(backgroundColor);
280         }
281     }
282     canvas_->restore();
283     if (!node.IsAppWindow() && node.GetBuffer() != nullptr) {
284         auto params = RSUniRenderUtil::CreateBufferDrawParam(node, false);
285         renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
286     }
287     if (isSelfDrawingSurface) {
288         auto filter = std::static_pointer_cast<RSSkiaFilter>(property.GetFilter());
289         if (filter != nullptr) {
290             auto skRectPtr = std::make_unique<SkRect>();
291             skRectPtr->setXYWH(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
292             RSPropertiesPainter::DrawFilter(property, *canvas_, filter, skRectPtr, canvas_->GetSurface());
293         }
294     }
295     canvas_->restore();
296     if (node.IsAppWindow() && RSColdStartManager::Instance().IsColdStartThreadRunning(node.GetId()) &&
297         node.GetCachedImage() != nullptr) {
298         RS_LOGD("RSSurfaceCaptureVisitor DrawCachedImage");
299         RSUniRenderUtil::DrawCachedImage(node, *canvas_, node.GetCachedImage());
300     } else {
301         ProcessBaseRenderNode(node);
302     }
303 }
304 
CaptureSurfaceInDisplayWithUni(RSSurfaceRenderNode & node)305 void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::CaptureSurfaceInDisplayWithUni(RSSurfaceRenderNode& node)
306 {
307     if (node.GetSecurityLayer()) {
308         RS_LOGD("RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::CaptureSurfaceInDisplayWithUni: \
309             process RSSurfaceRenderNode(id:[%" PRIu64 "]) paused since it is security layer.",
310             node.GetId());
311         return;
312     }
313     bool isSelfDrawingSurface = node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE ||
314         node.GetSurfaceNodeType() == RSSurfaceNodeType::ABILITY_COMPONENT_NODE;
315     if (!isSelfDrawingSurface) {
316         canvas_->concat(node.GetContextMatrix());
317         auto contextClipRect = node.GetContextClipRegion();
318         if (!contextClipRect.isEmpty()) {
319             canvas_->clipRect(contextClipRect);
320         }
321     }
322 
323     if (isSelfDrawingSurface) {
324         canvas_->save();
325     }
326 
327     const auto& property = node.GetRenderProperties();
328     auto geoPtr = std::static_pointer_cast<RSObjAbsGeometry>(property.GetBoundsGeometry());
329     if (geoPtr) {
330         canvas_->concat(geoPtr->GetMatrix());
331     }
332 
333     if (isSelfDrawingSurface) {
334         canvas_->save();
335     }
336 
337     const RectF absBounds = {0, 0, property.GetBoundsWidth(), property.GetBoundsHeight()};
338     RRect absClipRRect = RRect(absBounds, property.GetCornerRadius());
339     RSPropertiesPainter::DrawShadow(property, *canvas_, &absClipRRect);
340     if (!property.GetCornerRadius().IsZero()) {
341         canvas_->clipRRect(RSPropertiesPainter::RRect2SkRRect(absClipRRect), true);
342     } else {
343         canvas_->clipRect(SkRect::MakeWH(property.GetBoundsWidth(), property.GetBoundsHeight()));
344     }
345     auto backgroundColor = static_cast<SkColor>(property.GetBackgroundColor().AsArgbInt());
346     if (SkColorGetA(backgroundColor) != SK_AlphaTRANSPARENT) {
347         canvas_->drawColor(backgroundColor);
348     }
349     RSPropertiesPainter::DrawMask(property, *canvas_);
350 
351     auto filter = std::static_pointer_cast<RSSkiaFilter>(property.GetBackgroundFilter());
352     if (filter != nullptr) {
353         auto skRectPtr = std::make_unique<SkRect>();
354         skRectPtr->setXYWH(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
355         RSPropertiesPainter::DrawFilter(property, *canvas_, filter, skRectPtr, canvas_->GetSurface());
356     }
357     if (isSelfDrawingSurface) {
358         canvas_->restore();
359     }
360 
361     if (!node.IsAppWindow() && node.GetBuffer() != nullptr) {
362         auto params = RSUniRenderUtil::CreateBufferDrawParam(node, false);
363         renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
364     }
365 
366     if (isSelfDrawingSurface) {
367         canvas_->restore();
368     }
369 
370     ProcessBaseRenderNode(node);
371     filter = std::static_pointer_cast<RSSkiaFilter>(property.GetFilter());
372     if (filter != nullptr) {
373         auto skRectPtr = std::make_unique<SkRect>();
374         skRectPtr->setXYWH(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
375         RSPropertiesPainter::DrawFilter(property, *canvas_, filter, skRectPtr, canvas_->GetSurface());
376     }
377 }
378 
ProcessSurfaceRenderNodeWithUni(RSSurfaceRenderNode & node)379 void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::ProcessSurfaceRenderNodeWithUni(RSSurfaceRenderNode &node)
380 {
381     auto geoPtr = std::static_pointer_cast<RSObjAbsGeometry>(node.GetRenderProperties().GetBoundsGeometry());
382     if (geoPtr == nullptr) {
383         RS_LOGI("ProcessSurfaceRenderNode node:%" PRIu64 ", get geoPtr failed", node.GetId());
384         return;
385     }
386 
387     canvas_->save();
388     canvas_->SaveAlpha();
389     canvas_->MultiplyAlpha(node.GetRenderProperties().GetAlpha() * node.GetContextAlpha());
390     if (isDisplayNode_) {
391         CaptureSurfaceInDisplayWithUni(node);
392     } else {
393         CaptureSingleSurfaceNodeWithUni(node);
394     }
395     canvas_->RestoreAlpha();
396     canvas_->restore();
397 }
398 
ProcessRootRenderNode(RSRootRenderNode & node)399 void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::ProcessRootRenderNode(RSRootRenderNode& node)
400 {
401     if (!RSMainThread::Instance()->IfUseUniVisitor()) {
402         return;
403     }
404     if (!node.ShouldPaint()) {
405         RS_LOGD("ProcessRootRenderNode, no need process");
406         return;
407     }
408 
409     if (!canvas_) {
410         RS_LOGE("ProcessRootRenderNode, canvas is nullptr");
411         return;
412     }
413 
414     canvas_->save();
415     ProcessCanvasRenderNode(node);
416     canvas_->restore();
417 }
418 
ProcessCanvasRenderNode(RSCanvasRenderNode & node)419 void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::ProcessCanvasRenderNode(RSCanvasRenderNode& node)
420 {
421     if (!IsUniRender()) {
422         return;
423     }
424     if (!node.ShouldPaint()) {
425         RS_LOGD("ProcessCanvasRenderNode, no need process");
426         return;
427     }
428     if (!canvas_) {
429         RS_LOGE("ProcessCanvasRenderNode, canvas is nullptr");
430         return;
431     }
432     node.GetMutableRenderProperties().CheckEmptyBounds();
433     node.ProcessRenderBeforeChildren(*canvas_);
434     ProcessBaseRenderNode(node);
435     node.ProcessRenderAfterChildren(*canvas_);
436 }
437 
CaptureSingleSurfaceNodeWithoutUni(RSSurfaceRenderNode & node)438 void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithoutUni(RSSurfaceRenderNode& node)
439 {
440     SkMatrix translateMatrix;
441     auto parentPtr = node.GetParent().lock();
442     if (parentPtr != nullptr && parentPtr->IsInstanceOf<RSSurfaceRenderNode>()) {
443         // calculate the offset from this node's parent, and perform translate.
444         auto parentNode = std::static_pointer_cast<RSSurfaceRenderNode>(parentPtr);
445         const float parentNodeTranslateX = parentNode->GetTotalMatrix().getTranslateX();
446         const float parentNodeTranslateY = parentNode->GetTotalMatrix().getTranslateY();
447         const float thisNodetranslateX = node.GetTotalMatrix().getTranslateX();
448         const float thisNodetranslateY = node.GetTotalMatrix().getTranslateY();
449         translateMatrix.preTranslate(
450             thisNodetranslateX - parentNodeTranslateX, thisNodetranslateY - parentNodeTranslateY);
451     }
452     if (node.GetSecurityLayer()) {
453         RS_LOGD("RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::CaptureSingleSurfaceNodeWithoutUni: \
454             process RSSurfaceRenderNode(id:[%" PRIu64 "]) clear white since it is security layer.",
455             node.GetId());
456         canvas_->save();
457         canvas_->concat(translateMatrix);
458         canvas_->clear(SK_ColorWHITE);
459         canvas_->restore();
460         return;
461     }
462 
463     if (node.GetChildrenCount() > 0) {
464         canvas_->concat(translateMatrix);
465         const auto saveCnt = canvas_->save();
466         ProcessBaseRenderNode(node);
467         canvas_->restoreToCount(saveCnt);
468         if (node.GetBuffer() != nullptr) {
469             // in node's local coordinate.
470             auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, true, false, false, false);
471             renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
472         }
473     } else {
474         canvas_->save();
475         canvas_->concat(translateMatrix);
476         if (node.GetBuffer() != nullptr) {
477             // in node's local coordinate.
478             auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, true, false, false, false);
479             renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
480         }
481         canvas_->restore();
482     }
483 }
484 
CaptureSurfaceInDisplayWithoutUni(RSSurfaceRenderNode & node)485 void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::CaptureSurfaceInDisplayWithoutUni(RSSurfaceRenderNode& node)
486 {
487     if (node.GetSecurityLayer()) {
488         RS_LOGD("RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::CaptureSurfaceInDisplayWithoutUni: \
489             process RSSurfaceRenderNode(id:[%" PRIu64 "]) paused since it is security layer.",
490             node.GetId());
491         return;
492     }
493     ProcessBaseRenderNode(node);
494     if (node.GetBuffer() != nullptr) {
495         // in display's coordinate.
496         auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, false, false, false, false);
497         renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
498     }
499 }
500 
ProcessSurfaceRenderNodeWithoutUni(RSSurfaceRenderNode & node)501 void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::ProcessSurfaceRenderNodeWithoutUni(RSSurfaceRenderNode& node)
502 {
503     if (isDisplayNode_) {
504         CaptureSurfaceInDisplayWithoutUni(node);
505     } else {
506         CaptureSingleSurfaceNodeWithoutUni(node);
507     }
508 }
509 
ProcessSurfaceRenderNode(RSSurfaceRenderNode & node)510 void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode &node)
511 {
512     RS_TRACE_NAME("RSSurfaceCaptureVisitor::Process:" + node.GetName());
513 
514     if (canvas_ == nullptr) {
515         RS_LOGE("ProcessSurfaceRenderNode, canvas is nullptr");
516         return;
517     }
518 
519     if (!node.ShouldPaint()) {
520         RS_LOGD("ProcessSurfaceRenderNode node: %" PRIu64 " invisible", node.GetId());
521         return;
522     }
523 
524     // execute security layer in each case, ignore display snapshot and set it white for surface snapshot
525     if (IsUniRender()) {
526         ProcessSurfaceRenderNodeWithUni(node);
527     } else {
528         ProcessSurfaceRenderNodeWithoutUni(node);
529     }
530 }
531 } // namespace Rosen
532 } // namespace OHOS
533