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