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