• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "pipeline/rs_surface_capture_task.h"
17 
18 #include <memory>
19 #include <sys/mman.h>
20 
21 #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