• 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_render_thread_visitor.h"
17 
18 #include <cmath>
19 #ifndef USE_ROSEN_DRAWING
20 #include <include/core/SkColor.h>
21 #include <include/core/SkFont.h>
22 #include <include/core/SkMatrix.h>
23 #include <include/core/SkPaint.h>
24 #include <include/core/SkRect.h>
25 #else
26 #include "draw/color.h"
27 #include "drawing/engine_adapter/impl_interface/matrix_impl.h"
28 #endif
29 
30 #include "rs_trace.h"
31 
32 #include "command/rs_base_node_command.h"
33 #include "common/rs_obj_abs_geometry.h"
34 #include "common/rs_vector4.h"
35 #include "pipeline/rs_canvas_render_node.h"
36 #include "pipeline/rs_dirty_region_manager.h"
37 #include "pipeline/rs_effect_render_node.h"
38 #include "pipeline/rs_node_map.h"
39 #include "pipeline/rs_proxy_render_node.h"
40 #include "pipeline/rs_render_thread.h"
41 #include "pipeline/rs_root_render_node.h"
42 #include "pipeline/rs_surface_render_node.h"
43 #include "platform/common/rs_log.h"
44 #ifdef NEW_RENDER_CONTEXT
45 #include "rs_render_surface.h"
46 #else
47 #include "platform/drawing/rs_surface.h"
48 #endif
49 #include "transaction/rs_transaction_proxy.h"
50 #include "ui/rs_surface_extractor.h"
51 #include "ui/rs_surface_node.h"
52 
53 #ifdef ROSEN_OHOS
54 #include <frame_collector.h>
55 #include <frame_painter.h>
56 #include "platform/ohos/overdraw/rs_cpu_overdraw_canvas_listener.h"
57 #include "platform/ohos/overdraw/rs_gpu_overdraw_canvas_listener.h"
58 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
59 #include "surface_utils.h"
60 #endif
61 
62 #ifdef RS_ENABLE_VK
63 #include "platform/ohos/backend/rs_vulkan_context.h"
64 #include "platform/ohos/backend/rs_surface_ohos_vulkan.h"
65 #endif
66 
67 namespace OHOS {
68 namespace Rosen {
RSRenderThreadVisitor()69 RSRenderThreadVisitor::RSRenderThreadVisitor()
70     : curDirtyManager_(std::make_shared<RSDirtyRegionManager>()), canvas_(nullptr) {}
71 
72 RSRenderThreadVisitor::~RSRenderThreadVisitor() = default;
73 
IsValidRootRenderNode(RSRootRenderNode & node)74 bool RSRenderThreadVisitor::IsValidRootRenderNode(RSRootRenderNode& node)
75 {
76     auto ptr = RSNodeMap::Instance().GetNode<RSSurfaceNode>(node.GetRSSurfaceNodeId());
77     if (ptr == nullptr) {
78         ROSEN_LOGE("No valid RSSurfaceNode id");
79         return false;
80     }
81     if (!node.enableRender_) {
82         ROSEN_LOGD("RootNode %{public}s: Invisible", ptr->GetName().c_str());
83         return false;
84     }
85     if (node.GetSuggestedBufferWidth() <= 0 || node.GetSuggestedBufferHeight() <= 0) {
86         ROSEN_LOGD("Root %{public}s: Negative width or height [%{public}f %{public}f]", ptr->GetName().c_str(),
87             node.GetSuggestedBufferWidth(), node.GetSuggestedBufferHeight());
88         return false;
89     }
90     return true;
91 }
92 
SetPartialRenderStatus(PartialRenderType status,bool isRenderForced)93 void RSRenderThreadVisitor::SetPartialRenderStatus(PartialRenderType status, bool isRenderForced)
94 {
95     RS_TRACE_FUNC();
96     isRenderForced_ = isRenderForced;
97     dfxDirtyType_ = RSSystemProperties::GetDirtyRegionDebugType();
98     isEglSetDamageRegion_ = !isRenderForced_ && (status != PartialRenderType::DISABLED);
99     isOpDropped_ = (dfxDirtyType_ == DirtyRegionDebugType::DISABLED) && !isRenderForced_ &&
100         (status == PartialRenderType::SET_DAMAGE_AND_DROP_OP);
101     if (partialRenderStatus_ != status) {
102         ROSEN_LOGD("PartialRenderStatus: %{public}d->%{public}d, isRenderForced_=%{public}d, dfxDirtyType_=%{public}d,\
103             isEglSetDamageRegion_=%{public}d, isOpDropped_=%{public}d", partialRenderStatus_, status,
104             isRenderForced_, dfxDirtyType_, isEglSetDamageRegion_, isOpDropped_);
105     }
106     partialRenderStatus_ = status;
107 }
108 
PrepareChildren(RSRenderNode & node)109 void RSRenderThreadVisitor::PrepareChildren(RSRenderNode& node)
110 {
111     for (auto& child : *node.GetSortedChildren()) {
112         child->Prepare(shared_from_this());
113     }
114 }
115 
PrepareRootRenderNode(RSRootRenderNode & node)116 void RSRenderThreadVisitor::PrepareRootRenderNode(RSRootRenderNode& node)
117 {
118     if (isIdle_) {
119         curDirtyManager_ = node.GetDirtyManager();
120         curDirtyManager_->Clear();
121         curDirtyManager_->UpdateDebugRegionTypeEnable(dfxDirtyType_);
122         // After the node calls ApplyModifiers, the modifiers assign the renderProperties to the node
123         // Otherwise node.GetSuggestedBufferHeight always less than 0, causing black screen
124         if (!IsValidRootRenderNode(node)) {
125             return;
126         }
127         dirtyFlag_ = false;
128         isIdle_ = false;
129         PrepareCanvasRenderNode(node);
130         isIdle_ = true;
131     } else {
132         PrepareCanvasRenderNode(node);
133     }
134 }
135 
ResetAndPrepareChildrenNode(RSRenderNode & node,std::shared_ptr<RSBaseRenderNode> nodeParent)136 void RSRenderThreadVisitor::ResetAndPrepareChildrenNode(RSRenderNode& node,
137     std::shared_ptr<RSBaseRenderNode> nodeParent)
138 {
139     // merge last childRect as dirty if any child has been removed
140     if (curDirtyManager_ && node.HasRemovedChild()) {
141         curDirtyManager_->MergeDirtyRect(node.GetChildrenRect());
142         node.ResetHasRemovedChild();
143     }
144     // reset childRect before prepare children
145     node.ResetChildrenRect();
146     node.UpdateChildrenOutOfRectFlag(false);
147     PrepareChildren(node);
148     // accumulate direct parent's childrenRect
149     node.UpdateParentChildrenRect(nodeParent);
150 }
151 
PrepareCanvasRenderNode(RSCanvasRenderNode & node)152 void RSRenderThreadVisitor::PrepareCanvasRenderNode(RSCanvasRenderNode& node)
153 {
154     if (!node.ShouldPaint() || curDirtyManager_ == nullptr) {
155         return;
156     }
157     bool dirtyFlag = dirtyFlag_;
158     auto nodeParent = node.GetParent().lock();
159     dirtyFlag_ = node.Update(*curDirtyManager_, nodeParent, dirtyFlag_);
160     if (node.IsDirtyRegionUpdated() && curDirtyManager_->IsDebugRegionTypeEnable(DebugRegionType::CURRENT_SUB)) {
161         curDirtyManager_->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
162             DirtyRegionType::UPDATE_DIRTY_REGION, node.GetOldDirty());
163     }
164     ResetAndPrepareChildrenNode(node, nodeParent);
165     node.UpdateEffectRegion(effectRegion_);
166     dirtyFlag_ = dirtyFlag;
167 }
168 
PrepareSurfaceRenderNode(RSSurfaceRenderNode & node)169 void RSRenderThreadVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
170 {
171     if (curDirtyManager_ == nullptr) {
172         return;
173     }
174     node.ApplyModifiers();
175     bool dirtyFlag = dirtyFlag_;
176     auto nodeParent = node.GetParent().lock();
177     // If rt buffer switches to be available
178     // set its SurfaceRenderNode's render dirty
179     if (!node.IsNotifyRTBufferAvailablePre() && node.IsNotifyRTBufferAvailable()) {
180         ROSEN_LOGD("NotifyRTBufferAvailable and set it dirty");
181         node.SetDirty();
182     }
183     dirtyFlag_ = node.Update(*curDirtyManager_, nodeParent, dirtyFlag_);
184     if (node.IsDirtyRegionUpdated() && curDirtyManager_->IsDebugRegionTypeEnable(DebugRegionType::CURRENT_SUB)) {
185         curDirtyManager_->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::SURFACE_NODE,
186             DirtyRegionType::UPDATE_DIRTY_REGION, node.GetOldDirty());
187     }
188     ResetAndPrepareChildrenNode(node, nodeParent);
189     dirtyFlag_ = dirtyFlag;
190 }
191 
PrepareEffectRenderNode(RSEffectRenderNode & node)192 void RSRenderThreadVisitor::PrepareEffectRenderNode(RSEffectRenderNode& node)
193 {
194 #ifndef CROSS_PLATFORM
195     if (!node.ShouldPaint() || curDirtyManager_ == nullptr) {
196         return;
197     }
198     auto effectRegion = effectRegion_;
199 
200     effectRegion_ = node.InitializeEffectRegion();
201     bool dirtyFlag = dirtyFlag_;
202     auto nodeParent = node.GetParent().lock();
203     dirtyFlag_ = node.Update(*curDirtyManager_, nodeParent, dirtyFlag_);
204     ResetAndPrepareChildrenNode(node, nodeParent);
205     node.SetEffectRegion(effectRegion_);
206 
207     effectRegion_ = effectRegion;
208     dirtyFlag_ = dirtyFlag;
209 #endif
210 }
211 
212 #ifndef USE_ROSEN_DRAWING
DrawRectOnCanvas(const RectI & dirtyRect,const SkColor color,const SkPaint::Style fillType,float alpha,int strokeWidth)213 void RSRenderThreadVisitor::DrawRectOnCanvas(const RectI& dirtyRect, const SkColor color,
214     const SkPaint::Style fillType, float alpha, int strokeWidth)
215 #else
216 void RSRenderThreadVisitor::DrawRectOnCanvas(const RectI& dirtyRect, const Drawing::ColorQuad color,
217     RSPaintStyle fillType, float alpha, int strokeWidth)
218 #endif // USE_ROSEN_DRAWING
219 {
220     if (dirtyRect.IsEmpty()) {
221         ROSEN_LOGD("DrawRectOnCanvas dirty rect is invalid.");
222         return;
223     }
224 #ifndef USE_ROSEN_DRAWING
225     auto skRect = SkRect::MakeXYWH(dirtyRect.left_, dirtyRect.top_, dirtyRect.width_, dirtyRect.height_);
226     SkPaint rectPaint;
227     rectPaint.setColor(color);
228     rectPaint.setAntiAlias(true);
229     rectPaint.setAlphaf(alpha);
230     rectPaint.setStyle(fillType);
231     rectPaint.setStrokeWidth(strokeWidth);
232     if (fillType == SkPaint::kFill_Style) {
233         rectPaint.setStrokeJoin(SkPaint::kRound_Join);
234     }
235     canvas_->drawRect(skRect, rectPaint);
236 #else
237     auto drawingRect = Drawing::Rect(dirtyRect.left_, dirtyRect.top_,
238         dirtyRect.width_ + dirtyRect.left_, dirtyRect.height_ + dirtyRect.top_);
239     Drawing::Pen pen;
240     Drawing::Brush brush;
241     if (fillType == RSPaintStyle::STROKE) {
242         pen.SetColor(color);
243         pen.SetAntiAlias(true);
244         pen.SetAlphaF(alpha);
245         pen.SetWidth(strokeWidth);
246         pen.SetJoinStyle(Drawing::Pen::JoinStyle::ROUND_JOIN);
247         canvas_->AttachPen(pen);
248     } else if (fillType == RSPaintStyle::FILL) {
249         brush.SetColor(color);
250         brush.SetAntiAlias(true);
251         brush.SetAlphaF(alpha);
252         canvas_->AttachBrush(brush);
253     }
254     canvas_->DrawRect(drawingRect);
255     canvas_->DetachPen();
256     canvas_->DetachBrush();
257 #endif // USE_ROSEN_DRAWING
258 }
259 
DrawDirtyRegion()260 void RSRenderThreadVisitor::DrawDirtyRegion()
261 {
262     auto dirtyRect = RectI();
263     const float fillAlpha = 0.2;
264     const float edgeAlpha = 0.4;
265 
266     if (curDirtyManager_->IsDebugRegionTypeEnable(DebugRegionType::MULTI_HISTORY)) {
267         dirtyRect = curDirtyManager_->GetDirtyRegion();
268         if (dirtyRect.IsEmpty()) {
269             ROSEN_LOGD("DrawDirtyRegion his dirty rect is invalid. dirtyRect = %{public}s",
270                 dirtyRect.ToString().c_str());
271         } else {
272             ROSEN_LOGD("DrawDirtyRegion his dirty rect. dirtyRect = %{public}s", dirtyRect.ToString().c_str());
273             // green
274 #ifndef USE_ROSEN_DRAWING
275             DrawRectOnCanvas(dirtyRect, 0x442FDD2F, SkPaint::kFill_Style, fillAlpha);
276             DrawRectOnCanvas(dirtyRect, 0xFF2FDD2F, SkPaint::kStroke_Style, edgeAlpha);
277 #else
278             DrawRectOnCanvas(dirtyRect, 0x442FDD2F, RSPaintStyle::FILL, fillAlpha);
279             DrawRectOnCanvas(dirtyRect, 0xFF2FDD2F, RSPaintStyle::STROKE, edgeAlpha);
280 #endif // USE_ROSEN_DRAWING
281         }
282     }
283 
284     if (curDirtyManager_->IsDebugRegionTypeEnable(DebugRegionType::CURRENT_WHOLE)) {
285         dirtyRect = curDirtyManager_->GetLatestDirtyRegion();
286         if (dirtyRect.IsEmpty()) {
287             ROSEN_LOGD("DrawDirtyRegion current frame's dirty rect is invalid. dirtyRect = %{public}s",
288                 dirtyRect.ToString().c_str());
289         } else {
290             ROSEN_LOGD("DrawDirtyRegion cur dirty rect. dirtyRect = %{public}s", dirtyRect.ToString().c_str());
291             // yellow
292 #ifndef USE_ROSEN_DRAWING
293             DrawRectOnCanvas(dirtyRect, 0x88FFFF00, SkPaint::kFill_Style, fillAlpha);
294             DrawRectOnCanvas(dirtyRect, 0xFFFFFF00, SkPaint::kStroke_Style, edgeAlpha);
295 #else
296             DrawRectOnCanvas(dirtyRect, 0x88FFFF00, RSPaintStyle::FILL, fillAlpha);
297             DrawRectOnCanvas(dirtyRect, 0xFFFFFF00, RSPaintStyle::STROKE, edgeAlpha);
298 #endif // USE_ROSEN_DRAWING
299         }
300     }
301 
302     if (curDirtyManager_->IsDebugRegionTypeEnable(DebugRegionType::CURRENT_SUB)) {
303         const int strokeWidth = 4;
304         std::map<NodeId, RectI> dirtyRegionRects_;
305         curDirtyManager_->GetDirtyRegionInfo(dirtyRegionRects_, RSRenderNodeType::CANVAS_NODE,
306             DirtyRegionType::UPDATE_DIRTY_REGION);
307         ROSEN_LOGD("DrawDirtyRegion canvas dirtyRegionRects_ size %{public}zu", dirtyRegionRects_.size());
308         // Draw Canvas Node
309         for (const auto& [nid, subRect] : dirtyRegionRects_) {
310             ROSEN_LOGD("DrawDirtyRegion canvas node id %{public}" PRIu64 " is dirty. dirtyRect = %{public}s",
311                 nid, subRect.ToString().c_str());
312 #ifndef USE_ROSEN_DRAWING
313             DrawRectOnCanvas(subRect, 0x88FF0000, SkPaint::kStroke_Style, edgeAlpha, strokeWidth);
314 #else
315             DrawRectOnCanvas(subRect, 0x88FF0000, RSPaintStyle::STROKE, edgeAlpha, strokeWidth);
316 #endif // USE_ROSEN_DRAWING
317         }
318 
319         curDirtyManager_->GetDirtyRegionInfo(dirtyRegionRects_, RSRenderNodeType::SURFACE_NODE,
320             DirtyRegionType::UPDATE_DIRTY_REGION);
321         ROSEN_LOGD("DrawDirtyRegion surface dirtyRegionRects_ size %{public}zu", dirtyRegionRects_.size());
322         // Draw Surface Node
323         for (const auto& [nid, subRect] : dirtyRegionRects_) {
324             ROSEN_LOGD("DrawDirtyRegion surface node id %{public}" PRIu64 " is dirty. dirtyRect = %{public}s",
325                 nid, subRect.ToString().c_str());
326 #ifndef USE_ROSEN_DRAWING
327             DrawRectOnCanvas(subRect, 0xFFD864D8, SkPaint::kStroke_Style, edgeAlpha, strokeWidth);
328 #else
329             DrawRectOnCanvas(subRect, 0xFFD864D8, RSPaintStyle::STROKE, edgeAlpha, strokeWidth);
330 #endif // USE_ROSEN_DRAWING
331         }
332     }
333 }
334 
335 #ifdef NEW_RENDER_CONTEXT
UpdateDirtyAndSetEGLDamageRegion(std::shared_ptr<RSRenderSurface> & surface)336 void RSRenderThreadVisitor::UpdateDirtyAndSetEGLDamageRegion(std::shared_ptr<RSRenderSurface>& surface)
337 #else
338 void RSRenderThreadVisitor::UpdateDirtyAndSetEGLDamageRegion(std::unique_ptr<RSSurfaceFrame>& surfaceFrame)
339 #endif
340 {
341     RS_TRACE_BEGIN("UpdateDirtyAndSetEGLDamageRegion");
342 #ifdef RS_ENABLE_EGLQUERYSURFACE
343     if (isEglSetDamageRegion_) {
344         // get and update valid buffer age(>0) to merge history
345 #if defined(NEW_RENDER_CONTEXT)
346         if (surface == nullptr) {
347             ROSEN_LOGE("Failed to UpdateDirtyAndSetEGLDamageRegion, surface is nullptr");
348             return;
349         }
350         int32_t bufferAge = surface->GetBufferAge();
351 #else
352         int32_t bufferAge = surfaceFrame->GetBufferAge();
353 #endif
354         if (!curDirtyManager_->SetBufferAge(bufferAge)) {
355             ROSEN_LOGD("ProcessRootRenderNode SetBufferAge with invalid buffer age %{public}d", bufferAge);
356             curDirtyManager_->ResetDirtyAsSurfaceSize();
357         }
358         curDirtyManager_->UpdateDirtyByAligned();
359         curDirtyManager_->UpdateDirty();
360         curDirtyRegion_ = curDirtyManager_->GetDirtyRegion();
361         // only set damage region if dirty region and buffer age is valid(>0)
362         if (bufferAge >= 0) {
363             // get dirty rect coordinated from upper left to lower left corner in current surface
364             RectI dirtyRectFlip = curDirtyManager_->GetRectFlipWithinSurface(curDirtyRegion_);
365             // set dirty rect as eglSurfaceFrame's damage region
366 #if defined(NEW_RENDER_CONTEXT)
367             std::vector<RectI> dirtyRects;
368             dirtyRects.push_back(dirtyRectFlip);
369             surface->SetDamageRegion(dirtyRects);
370 #else
371             surfaceFrame->SetDamageRegion(dirtyRectFlip.left_, dirtyRectFlip.top_, dirtyRectFlip.width_,
372                 dirtyRectFlip.height_);
373 #endif
374             // flip aligned rect for op drops
375             curDirtyRegion_ = curDirtyManager_->GetRectFlipWithinSurface(dirtyRectFlip);
376             ROSEN_LOGD("GetPartialRenderEnabled buffer age %{public}d, dirtyRectFlip ="
377                 "[%{public}d, %{public}d, %{public}d, %{public}d], "
378                 "dirtyRectAlign = [%{public}d, %{public}d, %{public}d, %{public}d]", bufferAge,
379                 dirtyRectFlip.left_, dirtyRectFlip.top_, dirtyRectFlip.width_, dirtyRectFlip.height_,
380                 curDirtyRegion_.left_, curDirtyRegion_.top_, curDirtyRegion_.width_, curDirtyRegion_.height_);
381         }
382     } else {
383         curDirtyManager_->UpdateDirty();
384         curDirtyRegion_ = curDirtyManager_->GetDirtyRegion();
385     }
386 #else
387     curDirtyManager_->UpdateDirty();
388     curDirtyRegion_ = curDirtyManager_->GetDirtyRegion();
389 #endif
390     ROSEN_LOGD("UpdateDirtyAndSetEGLDamageRegion dirtyRect = [%{public}d, %{public}d, %{public}d, %{public}d]",
391         curDirtyRegion_.left_, curDirtyRegion_.top_, curDirtyRegion_.width_, curDirtyRegion_.height_);
392     RS_TRACE_END();
393 }
394 
ProcessShadowFirst(RSRenderNode & node)395 void RSRenderThreadVisitor::ProcessShadowFirst(RSRenderNode& node)
396 {
397     if (RSSystemProperties::GetUseShadowBatchingEnabled()
398         && (node.GetRenderProperties().GetUseShadowBatching())) {
399         auto children = node.GetSortedChildren();
400         for (auto& child : *children) {
401             if (auto node = child->ReinterpretCastTo<RSCanvasRenderNode>()) {
402                 node->ProcessShadowBatching(*canvas_);
403             }
404         }
405     }
406 }
407 
ProcessChildren(RSRenderNode & node)408 void RSRenderThreadVisitor::ProcessChildren(RSRenderNode& node)
409 {
410     ProcessShadowFirst(node);
411     for (auto& child : *node.GetSortedChildren()) {
412         child->Process(shared_from_this());
413     }
414 }
415 
ProcessRootRenderNode(RSRootRenderNode & node)416 void RSRenderThreadVisitor::ProcessRootRenderNode(RSRootRenderNode& node)
417 {
418     if (!isIdle_) {
419         ProcessCanvasRenderNode(node);
420         return;
421     }
422     auto ptr = RSNodeMap::Instance().GetNode<RSSurfaceNode>(node.GetRSSurfaceNodeId());
423     if (!IsValidRootRenderNode(node)) {
424         return;
425     }
426     drawCmdListVector_.clear();
427     curDirtyManager_ = node.GetDirtyManager();
428 
429     auto surfaceNodeColorSpace = ptr->GetColorSpace();
430 #ifdef NEW_RENDER_CONTEXT
431     std::shared_ptr<RSRenderSurface> rsSurface = RSSurfaceExtractor::ExtractRSSurface(ptr);
432 #else
433     std::shared_ptr<RSSurface> rsSurface = RSSurfaceExtractor::ExtractRSSurface(ptr);
434 #endif
435     if (rsSurface == nullptr) {
436         ROSEN_LOGE("ProcessRoot %{public}s: No RSSurface found", ptr->GetName().c_str());
437         return;
438     }
439     // Update queue size for each process loop in case it dynamically changes
440     queueSize_ = rsSurface->GetQueueSize();
441 
442     auto rsSurfaceColorSpace = rsSurface->GetColorSpace();
443     if (surfaceNodeColorSpace != rsSurfaceColorSpace) {
444         ROSEN_LOGD("Set new colorspace %{public}d to rsSurface", surfaceNodeColorSpace);
445         rsSurface->SetColorSpace(surfaceNodeColorSpace);
446     }
447 
448 #if defined(ACE_ENABLE_GL) || defined (ACE_ENABLE_VK)
449 #if defined(NEW_RENDER_CONTEXT)
450     std::shared_ptr<RenderContextBase> rc = RSRenderThread::Instance().GetRenderContext();
451     std::shared_ptr<DrawingContext> dc = RSRenderThread::Instance().GetDrawingContext();
452     rsSurface->SetDrawingContext(dc);
453 #else
454     RenderContext* rc = RSRenderThread::Instance().GetRenderContext();
455 #endif
456     rsSurface->SetRenderContext(rc);
457 #endif
458 
459 #ifdef ACE_ENABLE_VK
460     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
461         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
462         auto skContext = RsVulkanContext::GetSingleton().CreateDrawingContext();
463         if (skContext == nullptr) {
464             ROSEN_LOGE("RSRenderThreadVisitor::ProcessRootRenderNode CreateDrawingContext is null");
465             return;
466         }
467         std::static_pointer_cast<RSSurfaceOhosVulkan>(rsSurface)->SetSkContext(skContext);
468     }
469 #endif
470     uiTimestamp_ = RSRenderThread::Instance().GetUITimestamp();
471     RS_TRACE_BEGIN(ptr->GetName() + " rsSurface->RequestFrame");
472 #ifdef ROSEN_OHOS
473     FrameCollector::GetInstance().MarkFrameEvent(FrameEventType::ReleaseStart);
474 #endif
475 
476     const auto& property = node.GetRenderProperties();
477     const float bufferWidth = node.GetSuggestedBufferWidth() * property.GetScaleX();
478     const float bufferHeight = node.GetSuggestedBufferHeight() * property.GetScaleY();
479 #ifdef ROSEN_OHOS
480     auto surfaceFrame = rsSurface->RequestFrame(bufferWidth, bufferHeight, uiTimestamp_);
481 #else
482     auto surfaceFrame = rsSurface->RequestFrame(std::round(bufferWidth), std::round(bufferHeight), uiTimestamp_);
483 #endif
484     RS_TRACE_END();
485     if (surfaceFrame == nullptr) {
486         ROSEN_LOGI("ProcessRoot %{public}s: Request Frame Failed", ptr->GetName().c_str());
487 #ifdef ROSEN_OHOS
488         FrameCollector::GetInstance().MarkFrameEvent(FrameEventType::ReleaseEnd);
489 #endif
490         return;
491     }
492 #ifndef USE_ROSEN_DRAWING
493 #ifdef NEW_RENDER_CONTEXT
494     auto skSurface = rsSurface->GetSurface();
495 #else
496     auto skSurface = surfaceFrame->GetSurface();
497 #endif
498     if (skSurface == nullptr) {
499         ROSEN_LOGE("skSurface null.");
500         return;
501     }
502     if (skSurface->getCanvas() == nullptr) {
503         ROSEN_LOGE("skSurface.getCanvas is null.");
504         return;
505     }
506 #else
507     auto surface = surfaceFrame->GetSurface();
508     if (surface == nullptr) {
509         ROSEN_LOGE("surface null.");
510         return;
511     }
512     if (surface->GetCanvas() == nullptr) {
513         ROSEN_LOGE("surface.GetCanvas is null.");
514         return;
515     }
516 #endif
517 
518 #ifdef ROSEN_OHOS
519     // if listenedCanvas is nullptr, that means disabled or listen failed
520     std::shared_ptr<RSListenedCanvas> listenedCanvas = nullptr;
521     std::shared_ptr<RSCanvasListener> overdrawListener = nullptr;
522 
523     if (RSOverdrawController::GetInstance().IsEnabled()) {
524         auto &oc = RSOverdrawController::GetInstance();
525 #ifndef USE_ROSEN_DRAWING
526         listenedCanvas = std::make_shared<RSListenedCanvas>(skSurface.get());
527 #else
528         listenedCanvas = std::make_shared<RSListenedCanvas>(*surface);
529 #endif
530         overdrawListener = oc.CreateListener<RSCPUOverdrawCanvasListener>(listenedCanvas.get());
531         if (overdrawListener == nullptr) {
532             overdrawListener = oc.CreateListener<RSGPUOverdrawCanvasListener>(listenedCanvas.get());
533         }
534 
535         if (overdrawListener != nullptr) {
536             listenedCanvas->SetListener(overdrawListener);
537         } else {
538             // create listener failed
539             listenedCanvas = nullptr;
540         }
541     }
542 
543     if (listenedCanvas != nullptr) {
544         canvas_ = listenedCanvas;
545     } else {
546 #ifndef USE_ROSEN_DRAWING
547         canvas_ = std::make_shared<RSPaintFilterCanvas>(skSurface.get());
548 #else
549         canvas_ = std::make_shared<RSPaintFilterCanvas>(surface.get());
550 #endif // USE_ROSEN_DRAWING
551     }
552 #else
553 #ifndef USE_ROSEN_DRAWING
554     canvas_ = std::make_shared<RSPaintFilterCanvas>(skSurface.get());
555 #else
556     canvas_ = std::make_shared<RSPaintFilterCanvas>(surface.get());
557 #endif // USE_ROSEN_DRAWING
558 #endif
559 
560     canvas_->SetHighContrast(RSRenderThread::Instance().isHighContrastEnabled());
561 
562     // node's surface size already check, so here we do not need to check return
563     // attention: currently surfaceW/H are float values transformed into int implicitly
564     (void)curDirtyManager_->SetSurfaceSize(bufferWidth, bufferHeight);
565     // keep non-negative rect region within surface
566     curDirtyManager_->ClipDirtyRectWithinSurface();
567     // reset matrix
568     const float rootWidth = property.GetFrameWidth() * property.GetScaleX();
569     const float rootHeight = property.GetFrameHeight() * property.GetScaleY();
570 #ifndef USE_ROSEN_DRAWING
571     SkMatrix gravityMatrix;
572 #else
573     Drawing::Matrix gravityMatrix;
574 #endif // USE_ROSEN_DRAWING
575     (void)RSPropertiesPainter::GetGravityMatrix(
576         Gravity::RESIZE, RectF { 0.0f, 0.0f, bufferWidth, bufferHeight }, rootWidth, rootHeight, gravityMatrix);
577 
578     if (isRenderForced_ ||
579         curDirtyManager_->GetCurrentFrameDirtyRegion().GetWidth() == 0 ||
580         curDirtyManager_->GetCurrentFrameDirtyRegion().GetHeight() == 0 ||
581 #ifndef USE_ROSEN_DRAWING
582         !gravityMatrix.isIdentity()) {
583 #else
584         !(gravityMatrix == Drawing::Matrix())) {
585 #endif // USE_ROSEN_DRAWING
586         curDirtyManager_->ResetDirtyAsSurfaceSize();
587     }
588 #ifdef NEW_RENDER_CONTEXT
589     UpdateDirtyAndSetEGLDamageRegion(rsSurface);
590 #else
591     UpdateDirtyAndSetEGLDamageRegion(surfaceFrame);
592 #endif
593 
594 #ifndef USE_ROSEN_DRAWING
595     canvas_->clipRect(SkRect::MakeWH(bufferWidth, bufferHeight));
596     canvas_->clear(SK_ColorTRANSPARENT);
597 #else
598     canvas_->ClipRect(Drawing::Rect(0, 0, bufferWidth, bufferHeight), Drawing::ClipOp::INTERSECT, false);
599     canvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
600 #endif // USE_ROSEN_DRAWING
601     isIdle_ = false;
602 
603     // clear current children before traversal, we will re-add them again during traversal
604     childSurfaceNodeIds_.clear();
605 
606 #ifndef USE_ROSEN_DRAWING
607     canvas_->concat(gravityMatrix);
608 #else
609     canvas_->ConcatMatrix(gravityMatrix);
610 #endif // USE_ROSEN_DRAWING
611     parentSurfaceNodeMatrix_ = gravityMatrix;
612 
613     RS_TRACE_BEGIN("ProcessRenderNodes");
614     ProcessCanvasRenderNode(node);
615 
616     if (childSurfaceNodeIds_ != node.childSurfaceNodeIds_) {
617         auto thisSurfaceNodeId = node.GetRSSurfaceNodeId();
618         std::unique_ptr<RSCommand> command = std::make_unique<RSBaseNodeClearChild>(thisSurfaceNodeId);
619         SendCommandFromRT(command, thisSurfaceNodeId, FollowType::FOLLOW_TO_SELF);
620         for (const auto& childSurfaceNodeId : childSurfaceNodeIds_) {
621             command = std::make_unique<RSBaseNodeAddChild>(thisSurfaceNodeId, childSurfaceNodeId, -1);
622             SendCommandFromRT(command, thisSurfaceNodeId, FollowType::FOLLOW_TO_SELF);
623         }
624         node.childSurfaceNodeIds_ = std::move(childSurfaceNodeIds_);
625     }
626     RS_TRACE_END();
627 
628     auto transactionProxy = RSTransactionProxy::GetInstance();
629     if (transactionProxy != nullptr) {
630         ROSEN_LOGD("RSRenderThreadVisitor FlushImplicitTransactionFromRT uiTimestamp = %{public}" PRIu64,
631             uiTimestamp_);
632         transactionProxy->FlushImplicitTransactionFromRT(uiTimestamp_);
633     }
634 
635     if ((dfxDirtyType_ != DirtyRegionDebugType::DISABLED) && curDirtyManager_->IsDirty()) {
636         ROSEN_LOGD("ProcessRootRenderNode %{public}s [%{public}" PRIu64 "] draw dirtyRect",
637             ptr->GetName().c_str(), node.GetId());
638         DrawDirtyRegion();
639     }
640 
641 #ifdef ROSEN_OHOS
642     if (overdrawListener != nullptr) {
643         overdrawListener->Draw();
644     }
645 
646     FramePainter fpainter(FrameCollector::GetInstance());
647     fpainter.Draw(*canvas_);
648     FrameCollector::GetInstance().MarkFrameEvent(FrameEventType::ReleaseEnd);
649     FrameCollector::GetInstance().MarkFrameEvent(FrameEventType::FlushStart);
650 #endif
651 
652     RS_TRACE_BEGIN(ptr->GetName() + " rsSurface->FlushFrame");
653     ROSEN_LOGD("RSRenderThreadVisitor FlushFrame surfaceNodeId = %{public}" PRIu64 ", uiTimestamp = %{public}" PRIu64,
654         node.GetRSSurfaceNodeId(), uiTimestamp_);
655 #ifdef NEW_RENDER_CONTEXT
656     rsSurface->FlushFrame(uiTimestamp_);
657 #else
658     rsSurface->FlushFrame(surfaceFrame, uiTimestamp_);
659 #endif
660 #ifdef ROSEN_OHOS
661     FrameCollector::GetInstance().MarkFrameEvent(FrameEventType::FlushEnd);
662 #endif
663     RS_TRACE_END();
664 
665     canvas_ = nullptr;
666     isIdle_ = true;
667 }
668 
669 void RSRenderThreadVisitor::ProcessCanvasRenderNode(RSCanvasRenderNode& node)
670 {
671     if (!node.ShouldPaint()) {
672         return;
673     }
674     if (!canvas_) {
675         ROSEN_LOGE("RSRenderThreadVisitor::ProcessCanvasRenderNode, canvas is nullptr");
676         return;
677     }
678 #ifdef RS_ENABLE_EGLQUERYSURFACE
679     node.UpdateRenderStatus(curDirtyRegion_, isOpDropped_);
680     if (node.IsRenderUpdateIgnored()) {
681         return;
682     }
683 #endif
684     const auto& property = node.GetRenderProperties();
685     if (property.IsSpherizeValid()) {
686         if (node.GetCacheType() != CacheType::ANIMATE_PROPERTY) {
687             node.SetCacheType(CacheType::ANIMATE_PROPERTY);
688             node.ClearCacheSurface();
689         }
690         if (!node.GetCompletedCacheSurface() && UpdateAnimatePropertyCacheSurface(node)) {
691             node.UpdateCompletedCacheSurface();
692         }
693         node.ProcessTransitionBeforeChildren(*canvas_);
694         RSPropertiesPainter::DrawSpherize(
695             property, *canvas_, node.GetCompletedCacheSurface());
696         node.ProcessTransitionAfterChildren(*canvas_);
697         return;
698     }
699 
700     if (node.GetCompletedCacheSurface()) {
701         node.SetCacheType(CacheType::NONE);
702         node.ClearCacheSurface();
703     }
704     node.ProcessRenderBeforeChildren(*canvas_);
705     node.ProcessRenderContents(*canvas_);
706     ProcessChildren(node);
707     node.ProcessRenderAfterChildren(*canvas_);
708 }
709 
710 bool RSRenderThreadVisitor::UpdateAnimatePropertyCacheSurface(RSRenderNode& node)
711 {
712     if (!node.GetCacheSurface()) {
713 #ifndef USE_ROSEN_DRAWING
714 #ifdef NEW_SKIA
715         node.InitCacheSurface(canvas_ ? canvas_->recordingContext() : nullptr);
716 #else
717         node.InitCacheSurface(canvas_ ? canvas_->getGrContext() : nullptr);
718 #endif
719 #else
720         node.InitCacheSurface(canvas_ ? canvas_->GetGPUContext().get() : nullptr);
721 #endif
722     }
723     if (!node.GetCacheSurface()) {
724         return false;
725     }
726     auto cacheCanvas = std::make_shared<RSPaintFilterCanvas>(node.GetCacheSurface().get());
727     if (!cacheCanvas) {
728         return false;
729     }
730 
731     // copy current canvas properties into cacheCanvas
732     cacheCanvas->CopyConfiguration(*canvas_);
733 
734     // When drawing CacheSurface, all child node should be drawn.
735     // So set isOpDropped_ = false here.
736     bool isOpDropped = isOpDropped_;
737     isOpDropped_ = false;
738 
739     swap(cacheCanvas, canvas_);
740     node.ProcessAnimatePropertyBeforeChildren(*canvas_);
741     node.ProcessRenderContents(*canvas_);
742     ProcessChildren(node);
743     node.ProcessAnimatePropertyAfterChildren(*canvas_);
744     swap(cacheCanvas, canvas_);
745 
746     isOpDropped_ = isOpDropped;
747     return true;
748 }
749 
750 void RSRenderThreadVisitor::ProcessEffectRenderNode(RSEffectRenderNode& node)
751 {
752     if (!node.ShouldPaint()) {
753         RS_LOGD("RSRenderThreadVisitor::ProcessEffectRenderNode, no need process");
754         return;
755     }
756     if (!canvas_) {
757         RS_LOGE("RSRenderThreadVisitor::ProcessEffectRenderNode, canvas is nullptr");
758         return;
759     }
760     node.ProcessRenderBeforeChildren(*canvas_);
761     ProcessChildren(node);
762     node.ProcessRenderAfterChildren(*canvas_);
763 }
764 
765 int RSRenderThreadVisitor::CacRotationFromTransformType(GraphicTransformType transform)
766 {
767     GraphicTransformType rotation;
768     switch (transform) {
769         case GraphicTransformType::GRAPHIC_FLIP_H_ROT90:
770         case GraphicTransformType::GRAPHIC_FLIP_V_ROT90:
771             rotation = GraphicTransformType::GRAPHIC_ROTATE_90;
772             break;
773         case GraphicTransformType::GRAPHIC_FLIP_H_ROT180:
774         case GraphicTransformType::GRAPHIC_FLIP_V_ROT180:
775             rotation = GraphicTransformType::GRAPHIC_ROTATE_180;
776             break;
777         case GraphicTransformType::GRAPHIC_FLIP_H_ROT270:
778         case GraphicTransformType::GRAPHIC_FLIP_V_ROT270:
779             rotation = GraphicTransformType::GRAPHIC_ROTATE_270;
780             break;
781         default:
782             rotation = transform;
783             break;
784     }
785     static const std::map<GraphicTransformType, int> transformTypeEnumToIntMap = {
786         {GraphicTransformType::GRAPHIC_ROTATE_NONE, 0}, {GraphicTransformType::GRAPHIC_ROTATE_90, 270},
787         {GraphicTransformType::GRAPHIC_ROTATE_180, 180}, {GraphicTransformType::GRAPHIC_ROTATE_270, 90}};
788     auto iter = transformTypeEnumToIntMap.find(rotation);
789     return iter != transformTypeEnumToIntMap.end() ? iter->second : 0;
790 }
791 
792 void RSRenderThreadVisitor::ProcessSurfaceViewInRT(RSSurfaceRenderNode& node)
793 {
794 #ifdef ROSEN_OHOS
795     const auto& property = node.GetRenderProperties();
796     sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(node.GetSurfaceId());
797     if (surface == nullptr) {
798         RS_LOGE("RSRenderThreadVisitor::ProcessSurfaceViewInRT nodeId is %llu cannot find surface by surfaceId %llu",
799             node.GetId(), node.GetSurfaceId());
800         return;
801     }
802     sptr<SurfaceBuffer> surfaceBuffer;
803     // a 4 * 4 idetity matrix
804     float matrix[16] = {
805         1, 0, 0, 0,
806         0, 1, 0, 0,
807         0, 0, 1, 0,
808         0, 0, 0, 1
809     };
810     sptr<SyncFence> fence;
811     int ret = surface->GetLastFlushedBuffer(surfaceBuffer, fence, matrix);
812     if (ret != OHOS::GSERROR_OK || surfaceBuffer == nullptr) {
813         RS_LOGE("RSRenderThreadVisitor::ProcessSurfaceViewInRT: GetLastFlushedBuffer failed, err: %{public}d", ret);
814         return;
815     }
816     if (fence != nullptr) {
817         fence->Wait(3000); // wait at most 3000ms
818     }
819     Drawing::Matrix transfromMatrix;
820     auto transform = surface->GetTransform();
821     int rotation = CacRotationFromTransformType(transform);
822     transfromMatrix.PreRotate(rotation, property.GetBoundsWidth() * 0.5f, property.GetBoundsHeight() * 0.5f);
823     canvas_->ConcatMatrix(transfromMatrix);
824 #ifndef USE_ROSEN_DRAWING
825     auto recordingCanvas = std::make_shared<RSRecordingCanvas>(property.GetBoundsWidth(), property.GetBoundsHeight());
826     RSSurfaceBufferInfo rsSurfaceBufferInfo(surfaceBuffer, property.GetBoundsPositionX(), property.GetBoundsPositionY(),
827         property.GetBoundsWidth(), property.GetBoundsHeight());
828 #else
829     auto recordingCanvas = std::make_shared<ExtendRecordingCanvas>(property.GetBoundsWidth(),
830         property.GetBoundsHeight());
831     DrawingSurfaceBufferInfo rsSurfaceBufferInfo(surfaceBuffer, property.GetBoundsPositionX(),
832         property.GetBoundsPositionY(), property.GetBoundsWidth(), property.GetBoundsHeight());
833 #endif //USE_ROSEN_DRAWING
834     recordingCanvas->DrawSurfaceBuffer(rsSurfaceBufferInfo);
835     auto drawCmdList = recordingCanvas->GetDrawCmdList();
836     drawCmdList->Playback(*canvas_);
837     drawCmdListVector_.emplace_back(drawCmdList);
838 #endif
839 }
840 
841 void RSRenderThreadVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node)
842 {
843     if (!canvas_) {
844         ROSEN_LOGE("RSRenderThreadVisitor::ProcessSurfaceRenderNode, canvas is nullptr");
845         return;
846     }
847     if (!node.ShouldPaint()) {
848         ROSEN_LOGI("RSRenderThreadVisitor::ProcessSurfaceRenderNode node : %{public}" PRIu64 " is invisible",
849             node.GetId());
850         node.SetContextAlpha(0.0f);
851         return;
852     }
853     // RSSurfaceRenderNode in RSRenderThreadVisitor do not have information of property.
854     // We only get parent's matrix and send it to RenderService
855 #ifndef USE_ROSEN_DRAWING
856     SkMatrix invertMatrix;
857     SkMatrix contextMatrix = canvas_->getTotalMatrix();
858 
859     if (parentSurfaceNodeMatrix_.invert(&invertMatrix)) {
860         contextMatrix.preConcat(invertMatrix);
861 #else
862     Drawing::Matrix invertMatrix;
863     Drawing::Matrix contextMatrix = canvas_->GetTotalMatrix();
864 
865     if (parentSurfaceNodeMatrix_.Invert(invertMatrix)) {
866         contextMatrix.PreConcat(invertMatrix);
867 #endif // USE_ROSEN_DRAWING
868     } else {
869         ROSEN_LOGE("RSRenderThreadVisitor::ProcessSurfaceRenderNode, invertMatrix failed");
870     }
871     node.SetContextMatrix(contextMatrix);
872     node.SetContextAlpha(canvas_->GetAlpha());
873 
874     // PLANNING: This is a temporary modification. Animation for surfaceView should not be triggered in RenderService.
875     // We plan to refactor code here.
876     node.SetContextBounds(node.GetRenderProperties().GetBounds());
877 #ifdef USE_SURFACE_TEXTURE
878     if (node.GetIsTextureExportNode()) {
879         ProcessSurfaceViewInRT(node);
880     } else if (node.GetSurfaceNodeType() == RSSurfaceNodeType::SURFACE_TEXTURE_NODE) {
881         ProcessTextureSurfaceRenderNode(node);
882     } else {
883         ProcessOtherSurfaceRenderNode(node);
884     }
885 #else
886     if (node.GetIsTextureExportNode()) {
887         ProcessSurfaceViewInRT(node);
888     } else {
889         ProcessOtherSurfaceRenderNode(node);
890     }
891 #endif
892 
893     // 1. add this node to parent's children list
894     childSurfaceNodeIds_.emplace_back(node.GetId());
895 
896     // 2. backup and reset environment variables before traversal children
897     std::vector<NodeId> siblingSurfaceNodeIds(std::move(childSurfaceNodeIds_));
898     childSurfaceNodeIds_.clear();
899     auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
900 #ifndef USE_ROSEN_DRAWING
901     parentSurfaceNodeMatrix_ = canvas_->getTotalMatrix();
902 #else
903     parentSurfaceNodeMatrix_ = canvas_->GetTotalMatrix();
904 #endif // USE_ROSEN_DRAWING
905 
906     // 3. traversal children, child surface node will be added to childSurfaceNodeIds_
907     // note: apply current node properties onto canvas if there is any child node
908     ProcessChildren(node);
909 
910     // 4. if children changed, sync children to RenderService
911     if (childSurfaceNodeIds_ != node.childSurfaceNodeIds_) {
912         auto thisSurfaceNodeId = node.GetId();
913         std::unique_ptr<RSCommand> command = std::make_unique<RSBaseNodeClearChild>(thisSurfaceNodeId);
914         SendCommandFromRT(command, thisSurfaceNodeId, FollowType::FOLLOW_TO_SELF);
915         for (const auto& childSurfaceNodeId : childSurfaceNodeIds_) {
916             command = std::make_unique<RSBaseNodeAddChild>(thisSurfaceNodeId, childSurfaceNodeId, -1);
917             SendCommandFromRT(command, thisSurfaceNodeId, FollowType::FOLLOW_TO_SELF);
918         }
919         node.childSurfaceNodeIds_ = std::move(childSurfaceNodeIds_);
920     }
921 
922     // 5. restore environments variables before continue traversal siblings
923     childSurfaceNodeIds_ = std::move(siblingSurfaceNodeIds);
924     parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
925 
926     // 6.draw border
927 #ifndef USE_ROSEN_DRAWING
928     canvas_->save();
929     auto geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
930     canvas_->concat(geoPtr->GetMatrix());
931     RSPropertiesPainter::DrawOutline(node.GetRenderProperties(), *canvas_);
932     RSPropertiesPainter::DrawBorder(node.GetRenderProperties(), *canvas_);
933     canvas_->restore();
934 #else
935     canvas_->Save();
936     auto geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
937     canvas_->ConcatMatrix(geoPtr->GetMatrix());
938     RSPropertiesPainter::DrawOutline(node.GetRenderProperties(), *canvas_);
939     RSPropertiesPainter::DrawBorder(node.GetRenderProperties(), *canvas_);
940     canvas_->Restore();
941 #endif
942 }
943 
944 void RSRenderThreadVisitor::ProcessProxyRenderNode(RSProxyRenderNode& node)
945 {
946     if (!canvas_) {
947         ROSEN_LOGE("RSRenderThreadVisitor::ProcessProxyRenderNode, canvas is nullptr");
948         return;
949     }
950     // RSProxyRenderNode in RSRenderThreadVisitor do not have information of property.
951     // We only get parent's matrix and send it to RenderService
952 #ifdef ROSEN_OHOS
953 #ifndef USE_ROSEN_DRAWING
954     SkMatrix invertMatrix;
955     SkMatrix contextMatrix = canvas_->getTotalMatrix();
956     if (parentSurfaceNodeMatrix_.invert(&invertMatrix)) {
957         contextMatrix.preConcat(invertMatrix);
958     } else {
959         ROSEN_LOGE("RSRenderThreadVisitor::ProcessProxyRenderNode, invertMatrix failed");
960     }
961 #else
962     Drawing::Matrix invertMatrix;
963     Drawing::Matrix contextMatrix = canvas_->GetTotalMatrix();
964 
965     if (parentSurfaceNodeMatrix_.Invert(invertMatrix)) {
966         contextMatrix.PreConcat(invertMatrix);
967     } else {
968         ROSEN_LOGE("RSRenderThreadVisitor::ProcessProxyRenderNode, invertMatrix failed");
969     }
970 #endif // USE_ROSEN_DRAWING
971     node.SetContextMatrix(contextMatrix);
972     node.SetContextAlpha(canvas_->GetAlpha());
973 
974     // context clipRect should be based on parent node's coordinate system, in dividend render mode, it is the
975     // same as canvas coordinate system.
976     auto clipRect = RSPaintFilterCanvas::GetLocalClipBounds(*canvas_);
977     node.SetContextClipRegion(clipRect);
978 #endif
979 }
980 
981 void RSRenderThreadVisitor::AddSurfaceChangedCallBack(uint64_t id,
982     const std::function<void(float, float, float, float)>& callback)
983 {
984     surfaceCallbacks_.emplace(id, callback);
985 }
986 
987 void RSRenderThreadVisitor::RemoveSurfaceChangedCallBack(uint64_t id)
988 {
989     surfaceCallbacks_.erase(id);
990 }
991 
992 void RSRenderThreadVisitor::ClipHoleForSurfaceNode(RSSurfaceRenderNode& node)
993 {
994     // Calculation position in RenderService may appear floating point number, and it will be removed.
995     // It caused missed line problem on surfaceview hap, so we subtract one pixel when cliphole to avoid this problem
996     static int pixel = 1;
997     auto x = std::ceil(node.GetRenderProperties().GetBoundsPositionX() + pixel); // x increase 1 pixel
998     auto y = std::ceil(node.GetRenderProperties().GetBoundsPositionY() + pixel); // y increase 1 pixel
999     auto width = std::floor(node.GetRenderProperties().GetBoundsWidth() - (2 * pixel)); // width decrease 2 pixels
1000     auto height = std::floor(node.GetRenderProperties().GetBoundsHeight() - (2 * pixel)); // height decrease 2 pixels
1001 #ifndef USE_ROSEN_DRAWING
1002     canvas_->save();
1003     SkRect originRect = SkRect::MakeXYWH(x, y, width, height);
1004     canvas_->clipRect(originRect);
1005 
1006     auto iter = surfaceCallbacks_.find(node.GetId());
1007     if (iter != surfaceCallbacks_.end()) {
1008         (iter->second)(canvas_->getTotalMatrix().getTranslateX(), canvas_->getTotalMatrix().getTranslateY(), width, height);
1009     }
1010 
1011     if (node.IsNotifyRTBufferAvailable() && !node.GetIsForeground()) {
1012         ROSEN_LOGD("RSRenderThreadVisitor::ClipHoleForSurfaceNode node : %{public}" PRIu64 ","
1013             " clip [%{public}f, %{public}f, %{public}f, %{public}f]", node.GetId(), x, y, width, height);
1014         canvas_->clear(SK_ColorTRANSPARENT);
1015     } else {
1016         ROSEN_LOGD("RSRenderThreadVisitor::ClipHoleForSurfaceNode node : %{public}" PRIu64 ","
1017             " not clip [%{public}f, %{public}f, %{public}f, %{public}f]",
1018             node.GetId(), x, y, width, height);
1019         auto backgroundColor = node.GetRenderProperties().GetBackgroundColor();
1020         if (backgroundColor != RgbPalette::Transparent()) {
1021             canvas_->clear(backgroundColor.AsArgbInt());
1022         }
1023     }
1024     canvas_->restore();
1025 #else
1026     canvas_->Save();
1027     Drawing::Rect originRect = Drawing::Rect(x, y, width + x, height + y);
1028     canvas_->ClipRect(originRect, Drawing::ClipOp::INTERSECT, false);
1029     auto iter = surfaceCallbacks_.find(node.GetId());
1030     if (iter != surfaceCallbacks_.end()) {
1031         (iter->second)(canvas_->GetTotalMatrix().Get(Drawing::Matrix::TRANS_X),
1032             canvas_->GetTotalMatrix().Get(Drawing::Matrix::TRANS_Y), width, height);
1033     }
1034     if (node.IsNotifyRTBufferAvailable() == true) {
1035         ROSEN_LOGI("RSRenderThreadVisitor::ClipHoleForSurfaceNode node : %{public}" PRIu64 ","
1036             "clip [%{public}f, %{public}f, %{public}f, %{public}f]", node.GetId(), x, y, width, height);
1037         canvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
1038     } else {
1039         ROSEN_LOGI("RSRenderThreadVisitor::ClipHoleForSurfaceNode node : %{public}" PRIu64 ","
1040             "not clip [%{public}f, %{public}f, %{public}f, %{public}f]", node.GetId(), x, y, width, height);
1041         auto backgroundColor = node.GetRenderProperties().GetBackgroundColor();
1042         if (backgroundColor != RgbPalette::Transparent()) {
1043             canvas_->Clear(backgroundColor.AsArgbInt());
1044         }
1045     }
1046     canvas_->Restore();
1047 #endif // USE_ROSEN_DRAWING
1048 }
1049 
1050 void RSRenderThreadVisitor::SendCommandFromRT(std::unique_ptr<RSCommand>& command, NodeId nodeId, FollowType followType)
1051 {
1052     auto transactionProxy = RSTransactionProxy::GetInstance();
1053     if (transactionProxy != nullptr) {
1054         transactionProxy->AddCommandFromRT(command, nodeId, followType);
1055     }
1056 }
1057 
1058 #ifdef USE_SURFACE_TEXTURE
1059 void RSRenderThreadVisitor::ProcessTextureSurfaceRenderNode(RSSurfaceRenderNode& node)
1060 {
1061     auto texture = node.GetSurfaceTexture();
1062     if (texture == nullptr) {
1063         ROSEN_LOGE("ProcessTextureSurfaceRenderNode %{public}" PRIu64, node.GetId());
1064         return;
1065     }
1066     auto clipRect = RSPaintFilterCanvas::GetLocalClipBounds(*canvas_);
1067 #ifndef USE_ROSEN_DRAWING
1068     if (!clipRect.has_value() ||
1069         clipRect->width() < std::numeric_limits<float>::epsilon() ||
1070         clipRect->height() < std::numeric_limits<float>::epsilon()) {
1071 #else
1072     if (!clipRect.has_value() ||
1073         clipRect->GetWidth() < std::numeric_limits<float>::epsilon() ||
1074         clipRect->GetHeight() < std::numeric_limits<float>::epsilon()) {
1075 #endif
1076         // if clipRect is empty, this node will be removed from parent's children list.
1077         return;
1078     }
1079 
1080     // Calculation position in RenderService may appear floating point number, and it will be removed.
1081     // It caused missed line problem on surfaceview hap, so we subtract one pixel when cliphole to avoid this problem
1082     static int pixel = 1;
1083     auto x = std::ceil(node.GetRenderProperties().GetBoundsPositionX() + pixel); // x increase 1 pixel
1084     auto y = std::ceil(node.GetRenderProperties().GetBoundsPositionY() + pixel); // y increase 1 pixel
1085     auto width = std::floor(node.GetRenderProperties().GetBoundsWidth() - (2 * pixel)); // width decrease 2 pixels
1086     auto height = std::floor(node.GetRenderProperties().GetBoundsHeight() - (2 * pixel)); // height decrease 2 pixels
1087 
1088 #ifndef USE_ROSEN_DRAWING
1089     canvas_->save();
1090     SkRect originRect = SkRect::MakeXYWH(x, y, width, height);
1091 #else
1092     canvas_->Save();
1093     Drawing::Rect originRect = Drawing::Rect(x, y, width + x, height + y);
1094 #endif
1095 
1096     if (node.IsNotifyRTBufferAvailable()) {
1097         texture->DrawTextureImage(*canvas_, false, originRect);
1098     } else {
1099         auto backgroundColor = node.GetRenderProperties().GetBackgroundColor();
1100         if (backgroundColor != RgbPalette::Transparent()) {
1101 #ifndef USE_ROSEN_DRAWING
1102             canvas_->clear(backgroundColor.AsArgbInt());
1103 #else
1104             canvas_->Clear(backgroundColor.AsArgbInt());
1105 #endif
1106         }
1107     }
1108 #ifndef USE_ROSEN_DRAWING
1109     canvas_->restore();
1110 #else
1111     canvas_->Restore();
1112 #endif
1113 }
1114 #endif
1115 
1116 void RSRenderThreadVisitor::ProcessOtherSurfaceRenderNode(RSSurfaceRenderNode& node)
1117 {
1118     auto clipRect = RSPaintFilterCanvas::GetLocalClipBounds(*canvas_);
1119 #ifndef USE_ROSEN_DRAWING
1120     if (!clipRect.has_value() ||
1121         clipRect->width() < std::numeric_limits<float>::epsilon() ||
1122         clipRect->height() < std::numeric_limits<float>::epsilon()) {
1123 #else
1124     if (!clipRect.has_value() ||
1125         clipRect->GetWidth() < std::numeric_limits<float>::epsilon() ||
1126         clipRect->GetHeight() < std::numeric_limits<float>::epsilon()) {
1127 #endif
1128         // if clipRect is empty, this node will be removed from parent's children list.
1129         node.SetContextClipRegion(std::nullopt);
1130 
1131         static int pixel = 1;
1132         auto width = std::floor(node.GetRenderProperties().GetBoundsWidth() - (2 * pixel)); // width decrease 2 pixels
1133         auto height = std::floor(node.GetRenderProperties().GetBoundsHeight() - (2 * pixel)); // height decrease 2 pixels
1134         auto iter = surfaceCallbacks_.find(node.GetId());
1135         if (iter != surfaceCallbacks_.end()) {
1136 #ifndef USE_ROSEN_DRAWING
1137             (iter->second)(canvas_->getTotalMatrix().getTranslateX(),
1138                 canvas_->getTotalMatrix().getTranslateY(), width, height);
1139 #else
1140             (iter->second)(canvas_->GetTotalMatrix().Get(Drawing::Matrix::TRANS_X),
1141                 canvas_->GetTotalMatrix().Get(Drawing::Matrix::TRANS_Y), width, height);
1142 #endif
1143         }
1144         return;
1145     }
1146     node.SetContextClipRegion(clipRect);
1147     // temporary workaround since ContextAlpha/ContextClipRegion happens after ApplyModifiers
1148     node.ApplyModifiers();
1149 
1150     // clip hole
1151     ClipHoleForSurfaceNode(node);
1152 }
1153 } // namespace Rosen
1154 } // namespace OHOS
1155