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