• 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_node.h"
17 
18 #include <algorithm>
19 #include <mutex>
20 #include <set>
21 
22 #include "animation/rs_render_animation.h"
23 #include "common/rs_obj_abs_geometry.h"
24 #include "modifier/rs_modifier_type.h"
25 #include "pipeline/rs_base_render_node.h"
26 #include "pipeline/rs_canvas_drawing_render_node.h"
27 #include "pipeline/rs_context.h"
28 #include "pipeline/rs_paint_filter_canvas.h"
29 #include "pipeline/rs_root_render_node.h"
30 #include "pipeline/rs_surface_render_node.h"
31 #include "platform/common/rs_log.h"
32 #include "platform/common/rs_system_properties.h"
33 #include "property/rs_properties_painter.h"
34 #include "property/rs_property_trace.h"
35 #include "transaction/rs_transaction_proxy.h"
36 #include "visitor/rs_node_visitor.h"
37 
38 namespace OHOS {
39 namespace Rosen {
40 namespace {
41 const std::set<RSModifierType> GROUPABLE_ANIMATION_TYPE = {
42     RSModifierType::ALPHA,
43     RSModifierType::ROTATION,
44     RSModifierType::SCALE,
45 };
46 const std::set<RSModifierType> CACHEABLE_ANIMATION_TYPE = {
47     RSModifierType::BOUNDS,
48     RSModifierType::FRAME,
49 };
50 const std::unordered_set<RSModifierType> ANIMATION_MODIFIER_TYPE  = {
51     RSModifierType::TRANSLATE,
52     RSModifierType::SCALE,
53     RSModifierType::ROTATION_X,
54     RSModifierType::ROTATION_Y,
55     RSModifierType::ROTATION
56 };
57 }
58 
AddChild(SharedPtr child,int index)59 void RSRenderNode::AddChild(SharedPtr child, int index)
60 {
61     // sanity check, avoid loop
62     if (child == nullptr || child->GetId() == GetId()) {
63         return;
64     }
65     // if child already has a parent, remove it from its previous parent
66     if (auto prevParent = child->GetParent().lock()) {
67         prevParent->RemoveChild(child);
68     }
69 
70     // Set parent-child relationship
71     child->SetParent(weak_from_this());
72     if (index < 0 || index >= static_cast<int>(children_.size())) {
73         children_.emplace_back(child);
74     } else {
75         children_.emplace(std::next(children_.begin(), index), child);
76     }
77 
78     disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
79     // A child is not on the tree until its parent is on the tree
80     if (isOnTheTree_) {
81         child->SetIsOnTheTree(true, instanceRootNodeId_);
82     }
83     SetContentDirty();
84     isFullChildrenListValid_ = false;
85 }
86 
MoveChild(SharedPtr child,int index)87 void RSRenderNode::MoveChild(SharedPtr child, int index)
88 {
89     if (child == nullptr || child->GetParent().lock().get() != this) {
90         return;
91     }
92     auto it = std::find_if(children_.begin(), children_.end(),
93         [&](WeakPtr& ptr) -> bool { return ROSEN_EQ<RSRenderNode>(ptr, child); });
94     if (it == children_.end()) {
95         return;
96     }
97 
98     // Reset parent-child relationship
99     if (index < 0 || index >= static_cast<int>(children_.size())) {
100         children_.emplace_back(child);
101     } else {
102         children_.emplace(std::next(children_.begin(), index), child);
103     }
104     children_.erase(it);
105     SetContentDirty();
106     isFullChildrenListValid_ = false;
107 }
108 
RemoveChild(SharedPtr child,bool skipTransition)109 void RSRenderNode::RemoveChild(SharedPtr child, bool skipTransition)
110 {
111     if (child == nullptr) {
112         return;
113     }
114     // break parent-child relationship
115     auto it = std::find_if(children_.begin(), children_.end(),
116         [&](WeakPtr& ptr) -> bool { return ROSEN_EQ<RSRenderNode>(ptr, child); });
117     if (it == children_.end()) {
118         return;
119     }
120     // avoid duplicate entry in disappearingChildren_ (this should not happen)
121     disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
122     // if child has disappearing transition, add it to disappearingChildren_
123     if (skipTransition == false && child->HasDisappearingTransition(true)) {
124         ROSEN_LOGD("RSRenderNode::RemoveChild %" PRIu64 " move child(id %" PRIu64 ") into disappearingChildren",
125             GetId(), child->GetId());
126         // keep shared_ptr alive for transition
127         uint32_t origPos = static_cast<uint32_t>(std::distance(children_.begin(), it));
128         disappearingChildren_.emplace_back(child, origPos);
129     } else {
130         child->ResetParent();
131     }
132     children_.erase(it);
133     SetContentDirty();
134     isFullChildrenListValid_ = false;
135 }
136 
SetIsOnTheTree(bool flag,NodeId instanceRootNodeId)137 void RSRenderNode::SetIsOnTheTree(bool flag, NodeId instanceRootNodeId)
138 {
139     // We do not need to label a child when the child is removed from a parent that is not on the tree
140     if (flag == isOnTheTree_) {
141         return;
142     }
143     instanceRootNodeId_ = instanceRootNodeId;
144     isOnTheTree_ = flag;
145     OnTreeStateChanged();
146 
147     for (auto& childWeakPtr : children_) {
148         auto child = childWeakPtr.lock();
149         if (child == nullptr) {
150             continue;
151         }
152         child->SetIsOnTheTree(flag, instanceRootNodeId);
153     }
154 
155     for (auto& childPtr : disappearingChildren_) {
156         auto child = childPtr.first;
157         if (child == nullptr) {
158             continue;
159         }
160         child->SetIsOnTheTree(flag, instanceRootNodeId);
161     }
162 }
163 
UpdateChildrenRect(const RectI & subRect)164 void RSRenderNode::UpdateChildrenRect(const RectI& subRect)
165 {
166     if (!subRect.IsEmpty()) {
167         if (childrenRect_.IsEmpty()) {
168             // init as not empty subRect in case join RectI enlarging area
169             childrenRect_ = subRect;
170         } else {
171             childrenRect_ = childrenRect_.JoinRect(subRect);
172         }
173     }
174 }
175 
AddCrossParentChild(const SharedPtr & child,int32_t index)176 void RSRenderNode::AddCrossParentChild(const SharedPtr& child, int32_t index)
177 {
178     // AddCrossParentChild only used as: the child is under multiple parents(e.g. a window cross multi-screens),
179     // so this child will not remove from the old parent.
180     if (child == nullptr) {
181         return;
182     }
183 
184     // Set parent-child relationship
185     child->SetParent(weak_from_this());
186     if (index < 0 || index >= static_cast<int32_t>(children_.size())) {
187         children_.emplace_back(child);
188     } else {
189         children_.emplace(std::next(children_.begin(), index), child);
190     }
191 
192     disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
193     // A child is not on the tree until its parent is on the tree
194     if (isOnTheTree_) {
195         child->SetIsOnTheTree(true, instanceRootNodeId_);
196     }
197     SetContentDirty();
198     isFullChildrenListValid_ = false;
199 }
200 
RemoveCrossParentChild(const SharedPtr & child,const WeakPtr & newParent)201 void RSRenderNode::RemoveCrossParentChild(const SharedPtr& child, const WeakPtr& newParent)
202 {
203     // RemoveCrossParentChild only used as: the child is under multiple parents(e.g. a window cross multi-screens),
204     // set the newParentId to rebuild the parent-child relationship.
205     if (child == nullptr) {
206         return;
207     }
208     // break parent-child relationship
209     auto it = std::find_if(children_.begin(), children_.end(),
210         [&](WeakPtr& ptr) -> bool { return ROSEN_EQ<RSRenderNode>(ptr, child); });
211     if (it == children_.end()) {
212         return;
213     }
214     // avoid duplicate entry in disappearingChildren_ (this should not happen)
215     disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
216     // if child has disappearing transition, add it to disappearingChildren_
217     if (child->HasDisappearingTransition(true)) {
218         ROSEN_LOGD("RSRenderNode::RemoveChild %" PRIu64 " move child(id %" PRIu64 ") into disappearingChildren",
219             GetId(), child->GetId());
220         // keep shared_ptr alive for transition
221         uint32_t origPos = static_cast<uint32_t>(std::distance(children_.begin(), it));
222         disappearingChildren_.emplace_back(child, origPos);
223     } else {
224         child->SetParent(newParent);
225         // attention: set new parent means 'old' parent has removed this child
226         hasRemovedChild_ = true;
227     }
228     children_.erase(it);
229     SetContentDirty();
230     isFullChildrenListValid_ = false;
231 }
232 
RemoveFromTree(bool skipTransition)233 void RSRenderNode::RemoveFromTree(bool skipTransition)
234 {
235     auto parentPtr = parent_.lock();
236     if (parentPtr == nullptr) {
237         return;
238     }
239     auto child = shared_from_this();
240     parentPtr->RemoveChild(child, skipTransition);
241     if (skipTransition == false) {
242         return;
243     }
244     // force remove child from disappearingChildren_ and clean sortChildren_ cache
245     parentPtr->disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
246     parentPtr->isFullChildrenListValid_ = false;
247     child->ResetParent();
248 }
249 
ClearChildren()250 void RSRenderNode::ClearChildren()
251 {
252     if (children_.empty()) {
253         return;
254     }
255     // Cache the parent's transition state to avoid redundant recursively check
256     bool parentHasDisappearingTransition = HasDisappearingTransition(true);
257     uint32_t pos = 0;
258     for (auto& childWeakPtr : children_) {
259         auto child = childWeakPtr.lock();
260         if (child == nullptr) {
261             ++pos;
262             continue;
263         }
264         // avoid duplicate entry in disappearingChildren_ (this should not happen)
265         disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
266         if (parentHasDisappearingTransition || child->HasDisappearingTransition(false)) {
267             // keep shared_ptr alive for transition
268             disappearingChildren_.emplace_back(child, pos);
269         } else {
270             child->ResetParent();
271         }
272         ++pos;
273     }
274     children_.clear();
275     SetContentDirty();
276     isFullChildrenListValid_ = false;
277 }
278 
SetParent(WeakPtr parent)279 void RSRenderNode::SetParent(WeakPtr parent)
280 {
281     parent_ = parent;
282 }
283 
ResetParent()284 void RSRenderNode::ResetParent()
285 {
286     auto parentNode = parent_.lock();
287     if (parentNode) {
288         parentNode->hasRemovedChild_ = true;
289     }
290     parent_.reset();
291     SetIsOnTheTree(false);
292     OnResetParent();
293 }
294 
GetParent() const295 RSRenderNode::WeakPtr RSRenderNode::GetParent() const
296 {
297     return parent_;
298 }
299 
DumpTree(int32_t depth,std::string & out) const300 void RSRenderNode::DumpTree(int32_t depth, std::string& out) const
301 {
302     for (int32_t i = 0; i < depth; ++i) {
303         out += "  ";
304     }
305     out += "| ";
306     DumpNodeType(out);
307     out += "[" + std::to_string(GetId()) + "], instanceRootNodeId" + "[" +
308         std::to_string(GetInstanceRootNodeId()) + "]";
309     if (IsSuggestedDrawInGroup()) {
310         out += ", [node group]";
311     }
312     if (GetType() == RSRenderNodeType::SURFACE_NODE) {
313         auto surfaceNode = (static_cast<const RSSurfaceRenderNode*>(this));
314         auto p = parent_.lock();
315         out += ", Parent [" + (p != nullptr ? std::to_string(p->GetId()) : "null") + "]";
316         out += ", Name [" + surfaceNode->GetName() + "]";
317         const RSSurfaceHandler& surfaceHandler = static_cast<const RSSurfaceHandler&>(*surfaceNode);
318         out += ", hasConsumer: " + std::to_string(surfaceHandler.HasConsumer());
319         std::string contextAlpha = std::to_string(surfaceNode->contextAlpha_);
320         std::string propertyAlpha = std::to_string(surfaceNode->GetRenderProperties().GetAlpha());
321         out += ", Alpha: " + propertyAlpha + " (include ContextAlpha: " + contextAlpha + ")";
322         out += ", Visible: " + std::to_string(surfaceNode->GetRenderProperties().GetVisible());
323         out += ", " + surfaceNode->GetVisibleRegion().GetRegionInfo();
324         out += ", OcclusionBg: " + std::to_string(surfaceNode->GetAbilityBgAlpha());
325     }
326     if (GetType() == RSRenderNodeType::ROOT_NODE) {
327         auto rootNode = static_cast<const RSRootRenderNode*>(this);
328         out += ", Visible: " + std::to_string(rootNode->GetRenderProperties().GetVisible());
329         out += ", Size: [" + std::to_string(rootNode->GetRenderProperties().GetFrameWidth()) + ", " +
330             std::to_string(rootNode->GetRenderProperties().GetFrameHeight()) + "]";
331         out += ", EnableRender: " + std::to_string(rootNode->GetEnableRender());
332     }
333     out += ", Properties: " + GetRenderProperties().Dump();
334     out += "\n";
335     for (auto child : children_) {
336         if (auto c = child.lock()) {
337             c->DumpTree(depth + 1, out);
338         }
339     }
340     for (auto& child : disappearingChildren_) {
341         if (auto c = child.first) {
342             c->DumpTree(depth + 1, out);
343         }
344     }
345 }
346 
DumpNodeType(std::string & out) const347 void RSRenderNode::DumpNodeType(std::string& out) const
348 {
349     switch (GetType()) {
350         case RSRenderNodeType::DISPLAY_NODE: {
351             out += "DISPLAY_NODE";
352             break;
353         }
354         case RSRenderNodeType::RS_NODE: {
355             out += "RS_NODE";
356             break;
357         }
358         case RSRenderNodeType::SURFACE_NODE: {
359             out += "SURFACE_NODE";
360             break;
361         }
362         case RSRenderNodeType::CANVAS_NODE: {
363             out += "CANVAS_NODE";
364             break;
365         }
366         case RSRenderNodeType::ROOT_NODE: {
367             out += "ROOT_NODE";
368             break;
369         }
370         case RSRenderNodeType::PROXY_NODE: {
371             out += "PROXY_NODE";
372             break;
373         }
374         case RSRenderNodeType::CANVAS_DRAWING_NODE: {
375             out += "CANVAS_DRAWING_NODE";
376             break;
377         }
378         default: {
379             out += "UNKNOWN_NODE";
380             break;
381         }
382     }
383 }
384 
385 // attention: current all base node's dirty ops causing content dirty
SetContentDirty()386 void RSRenderNode::SetContentDirty()
387 {
388     isContentDirty_ = true;
389     SetDirty();
390 }
391 
SetDirty()392 void RSRenderNode::SetDirty()
393 {
394     dirtyStatus_ = NodeDirty::DIRTY;
395 }
396 
SetClean()397 void RSRenderNode::SetClean()
398 {
399     isContentDirty_ = false;
400     dirtyStatus_ = NodeDirty::CLEAN;
401 }
402 
CollectSurface(const std::shared_ptr<RSRenderNode> & node,std::vector<RSRenderNode::SharedPtr> & vec,bool isUniRender,bool onlyFirstLevel)403 void RSRenderNode::CollectSurface(
404     const std::shared_ptr<RSRenderNode>& node, std::vector<RSRenderNode::SharedPtr>& vec, bool isUniRender,
405     bool onlyFirstLevel)
406 {
407     for (auto& child : node->GetSortedChildren()) {
408         child->CollectSurface(child, vec, isUniRender, onlyFirstLevel);
409     }
410 }
411 
Prepare(const std::shared_ptr<RSNodeVisitor> & visitor)412 void RSRenderNode::Prepare(const std::shared_ptr<RSNodeVisitor>& visitor)
413 {
414     if (!visitor) {
415         return;
416     }
417     visitor->PrepareChildren(*this);
418 }
419 
Process(const std::shared_ptr<RSNodeVisitor> & visitor)420 void RSRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
421 {
422     if (!visitor) {
423         return;
424     }
425     visitor->ProcessChildren(*this);
426 }
427 
SendCommandFromRT(std::unique_ptr<RSCommand> & command,NodeId nodeId)428 void RSRenderNode::SendCommandFromRT(std::unique_ptr<RSCommand>& command, NodeId nodeId)
429 {
430     auto transactionProxy = RSTransactionProxy::GetInstance();
431     if (transactionProxy != nullptr) {
432         transactionProxy->AddCommandFromRT(command, nodeId);
433     }
434 }
435 
InternalRemoveSelfFromDisappearingChildren()436 void RSRenderNode::InternalRemoveSelfFromDisappearingChildren()
437 {
438     // internal use only, force remove self from parent's disappearingChildren_
439     auto parent = parent_.lock();
440     if (parent == nullptr) {
441         return;
442     }
443     auto it = std::find_if(parent->disappearingChildren_.begin(), parent->disappearingChildren_.end(),
444         [childPtr = shared_from_this()](const auto& pair) -> bool { return pair.first == childPtr; });
445     if (it == parent->disappearingChildren_.end()) {
446         return;
447     }
448     parent->disappearingChildren_.erase(it);
449     parent->isFullChildrenListValid_ = false;
450     ResetParent();
451 }
452 
~RSRenderNode()453 RSRenderNode::~RSRenderNode()
454 {
455     if (fallbackAnimationOnDestroy_) {
456         FallbackAnimationsToRoot();
457     }
458     if (clearCacheSurfaceFunc_ && (cacheSurface_ || cacheCompletedSurface_)) {
459         clearCacheSurfaceFunc_(cacheSurface_, cacheCompletedSurface_, cacheSurfaceThreadIndex_,
460             completedSurfaceThreadIndex_);
461     }
462     ClearCacheSurface();
463 }
464 
FallbackAnimationsToRoot()465 void RSRenderNode::FallbackAnimationsToRoot()
466 {
467     if (animationManager_.animations_.empty()) {
468         return;
469     }
470 
471     auto context = GetContext().lock();
472     if (!context) {
473         ROSEN_LOGE("Invalid context");
474         return;
475     }
476     auto target = context->GetNodeMap().GetAnimationFallbackNode();
477     if (!target) {
478         ROSEN_LOGE("Failed to move animation to root, root render node is null!");
479         return;
480     }
481     context->RegisterAnimatingRenderNode(target);
482 
483     for (auto& [unused, animation] : animationManager_.animations_) {
484         animation->Detach();
485         // avoid infinite loop for fallback animation
486         animation->SetRepeatCount(1);
487         target->animationManager_.AddAnimation(std::move(animation));
488     }
489     animationManager_.animations_.clear();
490 }
491 
Animate(int64_t timestamp)492 std::pair<bool, bool> RSRenderNode::Animate(int64_t timestamp)
493 {
494     if (lastTimestamp_ < 0) {
495         lastTimestamp_ = timestamp;
496     } else {
497         timeDelta_ = (static_cast<float>(timestamp - lastTimestamp_)) / NS_TO_S;
498         lastTimestamp_ = timestamp;
499     }
500     return animationManager_.Animate(timestamp, IsOnTheTree());
501 }
502 
GetRSFrameRateRange()503 FrameRateRange RSRenderNode::GetRSFrameRateRange()
504 {
505     if (rsRange_.IsValid()) {
506         return rsRange_;
507     }
508     rsRange_ = animationManager_.GetFrameRateRangeFromRSAnimations();
509     return rsRange_;
510 }
511 
ResetRSFrameRateRange()512 void RSRenderNode::ResetRSFrameRateRange()
513 {
514     rsRange_.Reset();
515 }
516 
ResetUIFrameRateRange()517 void RSRenderNode::ResetUIFrameRateRange()
518 {
519     uiRange_.Reset();
520 }
521 
IsClipBound() const522 bool RSRenderNode::IsClipBound() const
523 {
524     return renderProperties_.GetClipBounds() || renderProperties_.GetClipToFrame();
525 }
526 
Update(RSDirtyRegionManager & dirtyManager,const std::shared_ptr<RSRenderNode> & parent,bool parentDirty,bool isClipBoundDirty,std::optional<RectI> clipRect)527 bool RSRenderNode::Update(
528     RSDirtyRegionManager& dirtyManager, const std::shared_ptr<RSRenderNode>& parent, bool parentDirty,
529     bool isClipBoundDirty, std::optional<RectI> clipRect)
530 {
531     // no need to update invisible nodes
532     if (!ShouldPaint() && !isLastVisible_) {
533         SetClean();
534         renderProperties_.ResetDirty();
535         return false;
536     }
537     // [planning] surfaceNode use frame instead
538 #ifndef USE_ROSEN_DRAWING
539     std::optional<SkPoint> offset;
540     if (parent != nullptr && !IsInstanceOf<RSSurfaceRenderNode>()) {
541         auto& properties = parent->GetRenderProperties();
542         offset = SkPoint { properties.GetFrameOffsetX(), properties.GetFrameOffsetY() };
543     }
544 #else
545     std::optional<Drawing::Point> offset;
546     if (parent != nullptr && !IsInstanceOf<RSSurfaceRenderNode>()) {
547         Drawing::Point offset(parent->GetFrameOffsetX(), parent->GetFrameOffsetY());
548     }
549 #endif
550     // in some case geodirty_ is not marked in drawCmdModifiers_, we should update node geometry
551     parentDirty |= (dirtyStatus_ != NodeDirty::CLEAN);
552     auto parentProperties = parent ? &parent->GetRenderProperties() : nullptr;
553     bool dirty = renderProperties_.UpdateGeometry(parentProperties, parentDirty, offset, GetContextClipRegion());
554     if ((IsDirty() || dirty) && drawCmdModifiers_.count(RSModifierType::GEOMETRYTRANS)) {
555         RSModifierContext context = { GetMutableRenderProperties() };
556         for (auto& modifier : drawCmdModifiers_[RSModifierType::GEOMETRYTRANS]) {
557             modifier->Apply(context);
558         }
559     }
560     isDirtyRegionUpdated_ = false;
561     isLastVisible_ = ShouldPaint();
562     renderProperties_.ResetDirty();
563 
564 #ifndef USE_ROSEN_DRAWING
565     // Note:
566     // 1. cache manager will use dirty region to update cache validity, background filter cache manager should use
567     // 'dirty region of all the nodes drawn before this node', and foreground filter cache manager should use 'dirty
568     // region of all the nodes drawn before this node, this node, and the children of this node'
569     // 2. Filter must be valid when filter cache manager is valid, we make sure that in RSRenderNode::ApplyModifiers().
570     UpdateFilterCacheWithDirty(dirtyManager, false);
571 #endif
572     if (!isClipBoundDirty) {
573         UpdateDirtyRegion(dirtyManager, dirty, clipRect);
574     }
575     return dirty;
576 }
577 
GetMutableRenderProperties()578 RSProperties& RSRenderNode::GetMutableRenderProperties()
579 {
580     return renderProperties_;
581 }
582 
GetRenderProperties() const583 const RSProperties& RSRenderNode::GetRenderProperties() const
584 {
585     return renderProperties_;
586 }
587 
UpdateDirtyRegion(RSDirtyRegionManager & dirtyManager,bool geoDirty,std::optional<RectI> clipRect)588 void RSRenderNode::UpdateDirtyRegion(
589     RSDirtyRegionManager& dirtyManager, bool geoDirty, std::optional<RectI> clipRect)
590 {
591     if (!IsDirty() && !geoDirty) {
592         return;
593     }
594     if (RSSystemProperties::GetSkipGeometryNotChangeEnabled()) {
595         // while node absRect not change and other content not change, return directly for not generate dirty region
596         if (!IsSelfDrawingNode() && !geometryChangeNotPerceived_ && !geoDirty) {
597             return;
598         }
599         geometryChangeNotPerceived_ = false;
600     }
601     if (!oldDirty_.IsEmpty()) {
602         dirtyManager.MergeDirtyRect(oldDirty_);
603     }
604     // merge old dirty if switch to invisible
605     if (!ShouldPaint() && isLastVisible_) {
606         ROSEN_LOGD("RSRenderNode:: id %" PRIu64 " UpdateDirtyRegion visible->invisible", GetId());
607     } else {
608         RectI drawRegion;
609         RectI shadowRect;
610         auto dirtyRect = renderProperties_.GetDirtyRect(drawRegion);
611         if (renderProperties_.IsShadowValid()) {
612             SetShadowValidLastFrame(true);
613             if (IsInstanceOf<RSSurfaceRenderNode>()) {
614                 const RectF absBounds = {0, 0, renderProperties_.GetBoundsWidth(), renderProperties_.GetBoundsHeight()};
615                 RRect absClipRRect = RRect(absBounds, renderProperties_.GetCornerRadius());
616                 RSPropertiesPainter::GetShadowDirtyRect(shadowRect, renderProperties_, &absClipRRect);
617             } else {
618                 RSPropertiesPainter::GetShadowDirtyRect(shadowRect, renderProperties_);
619             }
620             if (!shadowRect.IsEmpty()) {
621                 dirtyRect = dirtyRect.JoinRect(shadowRect);
622             }
623         }
624 
625         if (renderProperties_.pixelStretch_) {
626             auto stretchDirtyRect = renderProperties_.GetPixelStretchDirtyRect();
627             dirtyRect = dirtyRect.JoinRect(stretchDirtyRect);
628         }
629 
630         if (clipRect.has_value()) {
631             dirtyRect = dirtyRect.IntersectRect(*clipRect);
632         }
633         oldDirty_ = dirtyRect;
634         oldDirtyInSurface_ = oldDirty_.IntersectRect(dirtyManager.GetSurfaceRect());
635         // filter invalid dirtyrect
636         if (!dirtyRect.IsEmpty()) {
637             dirtyManager.MergeDirtyRect(dirtyRect);
638             isDirtyRegionUpdated_ = true;
639             // save types of dirty region of target dirty manager for dfx
640             if (dirtyManager.IsTargetForDfx() &&
641                 (GetType() == RSRenderNodeType::CANVAS_NODE || GetType() == RSRenderNodeType::SURFACE_NODE)) {
642                 dirtyManager.UpdateDirtyRegionInfoForDfx(
643                     GetId(), GetType(), DirtyRegionType::UPDATE_DIRTY_REGION, oldDirtyInSurface_);
644                 dirtyManager.UpdateDirtyRegionInfoForDfx(
645                     GetId(), GetType(), DirtyRegionType::OVERLAY_RECT, drawRegion);
646                 dirtyManager.UpdateDirtyRegionInfoForDfx(
647                     GetId(), GetType(), DirtyRegionType::SHADOW_RECT, shadowRect);
648                 dirtyManager.UpdateDirtyRegionInfoForDfx(
649                     GetId(), GetType(), DirtyRegionType::PREPARE_CLIP_RECT, clipRect.value_or(RectI()));
650             }
651         }
652     }
653 
654     SetClean();
655 }
656 
IsSelfDrawingNode() const657 bool RSRenderNode::IsSelfDrawingNode() const
658 {
659     return GetType() == RSRenderNodeType::CANVAS_DRAWING_NODE;
660 }
661 
IsDirty() const662 bool RSRenderNode::IsDirty() const
663 {
664     return dirtyStatus_ != NodeDirty::CLEAN || renderProperties_.IsDirty();
665 }
666 
IsContentDirty() const667 bool RSRenderNode::IsContentDirty() const
668 {
669     // Considering renderNode, it should consider both basenode's case and its properties
670     return isContentDirty_ || renderProperties_.IsContentDirty();
671 }
672 
UpdateRenderStatus(RectI & dirtyRegion,bool isPartialRenderEnabled)673 void RSRenderNode::UpdateRenderStatus(RectI& dirtyRegion, bool isPartialRenderEnabled)
674 {
675     auto dirtyRect = renderProperties_.GetDirtyRect();
676     // should judge if there's any child out of parent
677     if (!isPartialRenderEnabled || HasChildrenOutOfRect()) {
678         isRenderUpdateIgnored_ = false;
679     } else if (dirtyRegion.IsEmpty() || dirtyRect.IsEmpty()) {
680         isRenderUpdateIgnored_ = true;
681     } else {
682         RectI intersectRect = dirtyRegion.IntersectRect(dirtyRect);
683         isRenderUpdateIgnored_ = intersectRect.IsEmpty();
684     }
685 }
686 
UpdateParentChildrenRect(std::shared_ptr<RSRenderNode> parentNode) const687 void RSRenderNode::UpdateParentChildrenRect(std::shared_ptr<RSRenderNode> parentNode) const
688 {
689     auto renderParent = (parentNode);
690     if (renderParent) {
691         // accumulate current node's all children region(including itself)
692         // apply oldDirty_ as node's real region(including overlay and shadow)
693         RectI accumulatedRect = GetChildrenRect().JoinRect(oldDirty_);
694         renderParent->UpdateChildrenRect(accumulatedRect);
695         // check each child is inside of parent
696         if (!accumulatedRect.IsInsideOf(renderParent->GetOldDirty())) {
697             renderParent->UpdateChildrenOutOfRectFlag(true);
698         }
699     }
700 }
701 
IsFilterCacheValid() const702 bool RSRenderNode::IsFilterCacheValid() const
703 {
704     if (!RSProperties::FilterCacheEnabled) {
705         return false;
706     }
707 #ifndef USE_ROSEN_DRAWING
708     // background filter
709     auto& bgManager = renderProperties_.GetFilterCacheManager(false);
710     // foreground filter
711     auto& frManager = renderProperties_.GetFilterCacheManager(true);
712     if ((bgManager && bgManager->IsCacheValid()) || (frManager && frManager->IsCacheValid())) {
713         return true;
714     }
715 #endif
716     return false;
717 }
718 
UpdateFilterCacheWithDirty(RSDirtyRegionManager & dirtyManager,bool isForeground) const719 void RSRenderNode::UpdateFilterCacheWithDirty(RSDirtyRegionManager& dirtyManager, bool isForeground) const
720 {
721 #ifndef USE_ROSEN_DRAWING
722     if (!RSProperties::FilterCacheEnabled) {
723         return;
724     }
725     auto& properties = GetRenderProperties();
726     auto& manager = properties.GetFilterCacheManager(isForeground);
727     if (manager == nullptr) {
728         return;
729     }
730     auto geoPtr = (properties.GetBoundsGeometry());
731     if (geoPtr == nullptr) {
732         return;
733     }
734     auto& cachedImageRegion = manager->GetCachedImageRegion();
735     RectI cachedImageRect = RectI(cachedImageRegion.x(), cachedImageRegion.y(), cachedImageRegion.width(),
736         cachedImageRegion.height());
737     auto isCachedImageRegionIntersectedWithDirtyRegion =
738         cachedImageRect.IntersectRect(dirtyManager.GetIntersectedVisitedDirtyRect(geoPtr->GetAbsRect()));
739     manager->UpdateCacheStateWithDirtyRegion(isCachedImageRegionIntersectedWithDirtyRegion);
740 #endif
741 }
742 
RenderTraceDebug() const743 void RSRenderNode::RenderTraceDebug() const
744 {
745     if (RSSystemProperties::GetRenderNodeTraceEnabled()) {
746         RSPropertyTrace::GetInstance().PropertiesDisplayByTrace(GetId(), GetRenderProperties());
747     }
748 }
749 
ApplyBoundsGeometry(RSPaintFilterCanvas & canvas)750 void RSRenderNode::ApplyBoundsGeometry(RSPaintFilterCanvas& canvas)
751 {
752 #ifndef USE_ROSEN_DRAWING
753     renderNodeSaveCount_ = canvas.Save();
754 #else
755     renderNodeSaveCount_ = canvas.SaveAllStatus();
756 #endif
757     auto boundsGeo = (GetRenderProperties().GetBoundsGeometry());
758     if (boundsGeo && !boundsGeo->IsEmpty()) {
759 #ifndef USE_ROSEN_DRAWING
760         canvas.concat(boundsGeo->GetMatrix());
761 #else
762         canvas.ConcatMatrix(boundsGeo->GetMatrix());
763 #endif
764     }
765 }
766 
ProcessTransitionBeforeChildren(RSPaintFilterCanvas & canvas)767 void RSRenderNode::ProcessTransitionBeforeChildren(RSPaintFilterCanvas& canvas)
768 {
769     ApplyBoundsGeometry(canvas);
770     auto alpha = renderProperties_.GetAlpha();
771     if (alpha < 1.f) {
772         if ((GetChildrenCount() == 0) || !(GetRenderProperties().GetAlphaOffscreen() || IsForcedDrawInGroup())) {
773             canvas.MultiplyAlpha(alpha);
774         } else {
775 #ifndef USE_ROSEN_DRAWING
776             auto rect = RSPropertiesPainter::Rect2SkRect(GetRenderProperties().GetBoundsRect());
777             canvas.saveLayerAlpha(&rect, std::clamp(alpha, 0.f, 1.f) * UINT8_MAX);
778 #else
779             auto rect = RSPropertiesPainter::Rect2DrawingRect(GetRenderProperties().GetBoundsRect());
780             Drawing::Brush brush;
781             brush.SetAlphaF(std::clamp(alpha, 0.f, 1.f) * UINT8_MAX);
782             Drawing::SaveLayerOps slr(&rect, &brush);
783             canvas.SaveLayer(slr);
784 #endif
785         }
786     }
787     RSPropertiesPainter::DrawMask(GetRenderProperties(), canvas);
788 }
789 
ProcessRenderBeforeChildren(RSPaintFilterCanvas & canvas)790 void RSRenderNode::ProcessRenderBeforeChildren(RSPaintFilterCanvas& canvas)
791 {
792     RSRenderNode::ProcessTransitionBeforeChildren(canvas);
793 }
794 
ProcessTransitionAfterChildren(RSPaintFilterCanvas & canvas)795 void RSRenderNode::ProcessTransitionAfterChildren(RSPaintFilterCanvas& canvas)
796 {
797     canvas.RestoreStatus(renderNodeSaveCount_);
798 }
799 
ProcessRenderAfterChildren(RSPaintFilterCanvas & canvas)800 void RSRenderNode::ProcessRenderAfterChildren(RSPaintFilterCanvas& canvas)
801 {
802     RSRenderNode::ProcessTransitionAfterChildren(canvas);
803 }
804 
AddModifier(const std::shared_ptr<RSRenderModifier> modifier)805 void RSRenderNode::AddModifier(const std::shared_ptr<RSRenderModifier> modifier)
806 {
807     if (!modifier) {
808         return;
809     }
810     if (modifier->GetType() == RSModifierType::BOUNDS || modifier->GetType() == RSModifierType::FRAME) {
811         AddGeometryModifier(modifier);
812     } else if (modifier->GetType() < RSModifierType::CUSTOM) {
813         modifiers_.emplace(modifier->GetPropertyId(), modifier);
814     } else {
815         drawCmdModifiers_[modifier->GetType()].emplace_back(modifier);
816     }
817     modifier->GetProperty()->Attach(ReinterpretCastTo<RSRenderNode>());
818     SetDirty();
819 }
820 
AddGeometryModifier(const std::shared_ptr<RSRenderModifier> modifier)821 void RSRenderNode::AddGeometryModifier(const std::shared_ptr<RSRenderModifier> modifier)
822 {
823     // bounds and frame modifiers must be unique
824     if (modifier->GetType() == RSModifierType::BOUNDS) {
825         if (boundsModifier_ == nullptr) {
826             boundsModifier_ = modifier;
827         }
828         modifiers_.emplace(modifier->GetPropertyId(), boundsModifier_);
829     }
830 
831     if (modifier->GetType() == RSModifierType::FRAME) {
832         if (frameModifier_ == nullptr) {
833             frameModifier_ = modifier;
834         }
835         modifiers_.emplace(modifier->GetPropertyId(), frameModifier_);
836     }
837 }
838 
RemoveModifier(const PropertyId & id)839 void RSRenderNode::RemoveModifier(const PropertyId& id)
840 {
841     SetDirty();
842     auto it = modifiers_.find(id);
843     if (it != modifiers_.end()) {
844         if (it->second) {
845             AddDirtyType(it->second->GetType());
846         }
847         modifiers_.erase(it);
848         return;
849     }
850     for (auto& [type, modifiers] : drawCmdModifiers_) {
851         modifiers.remove_if([id](const auto& modifier) -> bool {
852             return modifier ? modifier->GetPropertyId() == id : true;
853         });
854     }
855 }
AddModifierProfile(std::shared_ptr<RSRenderModifier> modifier,float width,float height)856 void RSRenderNode::AddModifierProfile(std::shared_ptr<RSRenderModifier> modifier, float width, float height)
857 {
858     if (timeDelta_ < 0) {
859         return;
860     }
861     if (lastApplyTimestamp_ == lastTimestamp_) {
862         return;
863     }
864     auto propertyId = modifier->GetPropertyId();
865     auto oldPropertyValue = propertyValueMap_.find(propertyId);
866     auto newProperty = modifier->GetProperty();
867     switch (modifier->GetType()) {
868         case RSModifierType::TRANSLATE: {
869             auto newPosition = std::static_pointer_cast<RSRenderAnimatableProperty<Vector2f>>(newProperty)->Get();
870             if (oldPropertyValue != propertyValueMap_.end()) {
871                 auto oldPosition = std::get<Vector2f>(oldPropertyValue->second);
872                 auto xSpeed = (newPosition[0] - oldPosition[0]) / timeDelta_;
873                 auto ySpeed = (newPosition[1] - oldPosition[1]) / timeDelta_;
874                 HgmModifierProfile hgmModifierProfile = {xSpeed, ySpeed, HgmModifierType::TRANSLATE};
875                 hgmModifierProfileList_.emplace_back(hgmModifierProfile);
876             }
877             propertyValueMap_[propertyId] = newPosition;
878             break;
879         }
880         case RSModifierType::SCALE: {
881             auto newPosition = std::static_pointer_cast<RSRenderAnimatableProperty<Vector2f>>(newProperty)->Get();
882             if (oldPropertyValue != propertyValueMap_.end()) {
883                 auto oldPosition = std::get<Vector2f>(oldPropertyValue->second);
884                 auto xSpeed = (newPosition[0] - oldPosition[0]) * width / timeDelta_;
885                 auto ySpeed = (newPosition[1] - oldPosition[1]) * height / timeDelta_;
886                 HgmModifierProfile hgmModifierProfile = {xSpeed, ySpeed, HgmModifierType::SCALE};
887                 hgmModifierProfileList_.emplace_back(hgmModifierProfile);
888             }
889             propertyValueMap_[propertyId] = newPosition;
890             break;
891         }
892         case RSModifierType::ROTATION_X:
893         case RSModifierType::ROTATION_Y:
894         case RSModifierType::ROTATION: {
895             HgmModifierProfile hgmModifierProfile = {0, 0, HgmModifierType::ROTATION};
896             hgmModifierProfileList_.emplace_back(hgmModifierProfile);
897             break;
898         }
899         default:
900             break;
901     }
902 }
903 
SetRSFrameRateRangeByPreferred(int32_t preferred)904 void RSRenderNode::SetRSFrameRateRangeByPreferred(int32_t preferred)
905 {
906     if (preferred > 0) {
907         FrameRateRange frameRateRange = {0, preferred, preferred};
908         SetRSFrameRateRange(frameRateRange);
909     }
910 }
911 
ApplyModifiers()912 bool RSRenderNode::ApplyModifiers()
913 {
914     // quick reject test
915     if (!RSRenderNode::IsDirty() || dirtyTypes_.empty()) {
916         return false;
917     }
918     hgmModifierProfileList_.clear();
919     const auto prevPositionZ = renderProperties_.GetPositionZ();
920 
921     // Reset and re-apply all modifiers
922     RSModifierContext context = { renderProperties_ };
923     std::vector<std::shared_ptr<RSRenderModifier>> animationModifiers;
924 
925     // Reset before apply modifiers
926     renderProperties_.ResetProperty(dirtyTypes_);
927 
928     // Apply modifiers
929     for (auto& [id, modifier] : modifiers_) {
930         if (!dirtyTypes_.count(modifier->GetType())) {
931             continue;
932         }
933         modifier->Apply(context);
934         if (ANIMATION_MODIFIER_TYPE.count(modifier->GetType())) {
935             animationModifiers.push_back(modifier);
936         }
937     }
938 
939     for (auto &modifier : animationModifiers) {
940         AddModifierProfile(modifier, context.property_.GetBoundsWidth(), context.property_.GetBoundsHeight());
941     }
942     // execute hooks
943     renderProperties_.OnApplyModifiers();
944     OnApplyModifiers();
945 
946     // update state
947     dirtyTypes_.clear();
948     lastApplyTimestamp_ = lastTimestamp_;
949 
950     // return true if positionZ changed
951     return renderProperties_.GetPositionZ() != prevPositionZ;
952 }
953 
954 #ifndef USE_ROSEN_DRAWING
UpdateEffectRegion(std::optional<SkPath> & region) const955 void RSRenderNode::UpdateEffectRegion(std::optional<SkPath>& region) const
956 #else
957 void RSRenderNode::UpdateEffectRegion(std::optional<Drawing::Path>& region) const
958 #endif
959 {
960     if (!region.has_value()) {
961         return;
962     }
963     const auto& property = GetRenderProperties();
964     if (!property.GetUseEffect()) {
965         return;
966     }
967     auto& effectPath = region.value();
968     auto geoPtr = (property.GetBoundsGeometry());
969     if (!geoPtr) {
970         return;
971     }
972 
973 #ifndef USE_ROSEN_DRAWING
974     SkPath clipPath;
975     if (property.GetClipBounds() != nullptr) {
976         clipPath = property.GetClipBounds()->GetSkiaPath();
977     } else {
978         auto rrect = RSPropertiesPainter::RRect2SkRRect(property.GetRRect());
979         clipPath.addRRect(rrect);
980     }
981 
982     // accumulate children clip path, with matrix
983     effectPath.addPath(clipPath, geoPtr->GetAbsMatrix());
984 #else
985     Drawing::Path clipPath;
986     if (property.GetClipBounds() != nullptr) {
987         clipPath = property.GetClipBounds()->GetDrawingPath();
988     } else {
989         auto rrect = RSPropertiesPainter::RRect2DrawingRRect(property.GetRRect());
990         clipPath.AddRoundRect(rrect);
991     }
992 
993     // accumulate children clip path, with matrix
994     effectPath.AddPath(clipPath, geoPtr->GetAbsMatrix());
995 #endif
996 }
997 
GetModifier(const PropertyId & id)998 std::shared_ptr<RSRenderModifier> RSRenderNode::GetModifier(const PropertyId& id)
999 {
1000     if (modifiers_.count(id)) {
1001         return modifiers_[id];
1002     }
1003     for (auto& [type, modifiers] : drawCmdModifiers_) {
1004         auto it = std::find_if(modifiers.begin(), modifiers.end(),
1005             [id](const auto& modifier) -> bool { return modifier->GetPropertyId() == id; });
1006         if (it != modifiers.end()) {
1007             return *it;
1008         }
1009     }
1010     return nullptr;
1011 }
1012 
FilterModifiersByPid(pid_t pid)1013 void RSRenderNode::FilterModifiersByPid(pid_t pid)
1014 {
1015     // remove all modifiers added by given pid (by matching higher 32 bits of node id)
1016     EraseIf(modifiers_, [pid](const auto& pair) -> bool { return ExtractPid(pair.first) == pid; });
1017 
1018     // remove all modifiers added by given pid (by matching higher 32 bits of node id)
1019     for (auto& [type, modifiers] : drawCmdModifiers_) {
1020         modifiers.remove_if(
1021             [pid](const auto& it) -> bool { return ExtractPid(it->GetPropertyId()) == pid; });
1022     }
1023 }
1024 
ShouldPaint() const1025 bool RSRenderNode::ShouldPaint() const
1026 {
1027     // node should be painted if either it is visible or it has disappearing transition animation, but only when its
1028     // alpha is not zero
1029     return (renderProperties_.GetVisible() || HasDisappearingTransition(false)) &&
1030            (renderProperties_.GetAlpha() > 0.0f);
1031 }
1032 
SetSharedTransitionParam(const std::optional<SharedTransitionParam> && sharedTransitionParam)1033 void RSRenderNode::SetSharedTransitionParam(const std::optional<SharedTransitionParam>&& sharedTransitionParam)
1034 {
1035     if (!sharedTransitionParam_.has_value() && !sharedTransitionParam.has_value()) {
1036         // both are empty, do nothing
1037         return;
1038     }
1039     sharedTransitionParam_ = sharedTransitionParam;
1040     SetDirty();
1041 }
1042 
GetSharedTransitionParam() const1043 const std::optional<RSRenderNode::SharedTransitionParam>& RSRenderNode::GetSharedTransitionParam() const
1044 {
1045     return sharedTransitionParam_;
1046 }
1047 
SetGlobalAlpha(float alpha)1048 void RSRenderNode::SetGlobalAlpha(float alpha)
1049 {
1050     if (globalAlpha_ == alpha) {
1051         return;
1052     }
1053     if ((ROSEN_EQ(globalAlpha_, 1.0f) && alpha != 1.0f) ||
1054         (ROSEN_EQ(alpha, 1.0f) && globalAlpha_ != 1.0f)) {
1055         OnAlphaChanged();
1056     }
1057     globalAlpha_ = alpha;
1058 }
1059 
GetGlobalAlpha() const1060 float RSRenderNode::GetGlobalAlpha() const
1061 {
1062     return globalAlpha_;
1063 }
1064 
NeedInitCacheSurface() const1065 bool RSRenderNode::NeedInitCacheSurface() const
1066 {
1067     if (cacheSurface_ == nullptr) {
1068         return true;
1069     }
1070     auto cacheType = GetCacheType();
1071     int width = 0;
1072     int height = 0;
1073     if (cacheType == CacheType::ANIMATE_PROPERTY &&
1074         renderProperties_.IsShadowValid() && !renderProperties_.IsSpherizeValid()) {
1075         const RectF boundsRect = renderProperties_.GetBoundsRect();
1076         RRect rrect = RRect(boundsRect, {0, 0, 0, 0});
1077         RectI shadowRect;
1078         RSPropertiesPainter::GetShadowDirtyRect(shadowRect, renderProperties_, &rrect, false);
1079         width = shadowRect.GetWidth();
1080         height = shadowRect.GetHeight();
1081     } else {
1082         Vector2f size = GetOptionalBufferSize();
1083         width =  size.x_;
1084         height = size.y_;
1085     }
1086     return cacheSurface_->width() != width || cacheSurface_->height() !=height;
1087 }
1088 
1089 #ifndef USE_ROSEN_DRAWING
1090 #ifdef NEW_SKIA
InitCacheSurface(GrRecordingContext * grContext,ClearCacheSurfaceFunc func,uint32_t threadIndex)1091 void RSRenderNode::InitCacheSurface(GrRecordingContext* grContext, ClearCacheSurfaceFunc func, uint32_t threadIndex)
1092 #else
1093 void RSRenderNode::InitCacheSurface(GrContext* grContext, ClearCacheSurfaceFunc func, uint32_t threadIndex)
1094 #endif
1095 #else
1096 void RSRenderNode::InitCacheSurface(Drawing::GPUContext* gpuContext, ClearCacheSurfaceFunc func, uint32_t threadIndex)
1097 #endif
1098 {
1099     if (func) {
1100         cacheSurfaceThreadIndex_ = threadIndex;
1101         if (!clearCacheSurfaceFunc_) {
1102             clearCacheSurfaceFunc_ = func;
1103         }
1104         if (cacheSurface_) {
1105             func(cacheSurface_, cacheCompletedSurface_, cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
1106             ClearCacheSurface();
1107         }
1108     } else {
1109         cacheSurface_ = nullptr;
1110     }
1111     auto cacheType = GetCacheType();
1112     float width = 0.0f, height = 0.0f;
1113     Vector2f size = GetOptionalBufferSize();
1114     boundsWidth_ = size.x_;
1115     boundsHeight_ = size.y_;
1116     if (cacheType == CacheType::ANIMATE_PROPERTY &&
1117         renderProperties_.IsShadowValid() && !renderProperties_.IsSpherizeValid()) {
1118         const RectF boundsRect = renderProperties_.GetBoundsRect();
1119         RRect rrect = RRect(boundsRect, {0, 0, 0, 0});
1120         RectI shadowRect;
1121         RSPropertiesPainter::GetShadowDirtyRect(shadowRect, renderProperties_, &rrect, false);
1122         width = shadowRect.GetWidth();
1123         height = shadowRect.GetHeight();
1124         shadowRectOffsetX_ = -shadowRect.GetLeft();
1125         shadowRectOffsetY_ = -shadowRect.GetTop();
1126     } else {
1127         width = boundsWidth_;
1128         height = boundsHeight_;
1129     }
1130 #ifndef USE_ROSEN_DRAWING
1131 #if ((defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)) || (defined RS_ENABLE_VK)
1132     if (grContext == nullptr) {
1133         if (func) {
1134             func(cacheSurface_, cacheCompletedSurface_, cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
1135             ClearCacheSurface();
1136         }
1137         return;
1138     }
1139     SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
1140     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1141     cacheSurface_ = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kYes, info);
1142 #else
1143     cacheSurface_ = SkSurface::MakeRasterN32Premul(width, height);
1144 #endif
1145 #else // USE_ROSEN_DRAWING
1146     Drawing::BitmapFormat format = { Drawing::ColorType::COLORTYPE_N32, Drawing::AlphaType::ALPHATYPE_PREMUL };
1147     auto bitmap = std::make_shared<Drawing::Bitmap>();
1148     bitmap->Build(width, height, format);
1149 #if ((defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)) || (defined RS_ENABLE_VK)
1150     if (gpuContext == nullptr) {
1151         if (func) {
1152             func(cacheSurface_, cacheCompletedSurface_, cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
1153             ClearCacheSurface();
1154         }
1155         return;
1156     }
1157     auto image = std::make_shared<Drawing::Image>();
1158     if (!image->BuildFromBitmap(*gpuContext, *bitmap)) {
1159         RS_LOGE("InitCacheSurface: image BuildFromBitmap failed");
1160         return;
1161     }
1162     auto surface = std::make_shared<Drawing::Surface>();
1163     if (!surface->Bind(*image)) {
1164         RS_LOGE("InitCacheSurface: surface bind image failed");
1165         return;
1166     }
1167 #else
1168     auto surface = std::make_shared<Drawing::Surface>();
1169     if (!surface->Bind(*bitmap)) {
1170         RS_LOGE("InitCacheSurface: surface bind bitmap failed");
1171         return;
1172     }
1173 #endif
1174     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1175     cacheBitmap_ = bitmap;
1176     cacheSurface_ = surface;
1177 #endif // USE_ROSEN_DRAWING
1178 }
1179 
GetOptionalBufferSize() const1180 Vector2f RSRenderNode::GetOptionalBufferSize() const
1181 {
1182     const auto& modifier = boundsModifier_ ? boundsModifier_ : frameModifier_;
1183     if (!modifier) {
1184         return {0.0f, 0.0f};
1185     }
1186     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(modifier->GetProperty());
1187     auto vector4f = renderProperty->Get();
1188     // bounds vector4f: x y z w -> left top width height
1189     return { vector4f.z_, vector4f.w_ };
1190 }
1191 
1192 #ifndef USE_ROSEN_DRAWING
DrawCacheSurface(RSPaintFilterCanvas & canvas,uint32_t threadIndex,bool isUIFirst)1193 void RSRenderNode::DrawCacheSurface(RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
1194 {
1195     auto cacheType = GetCacheType();
1196     canvas.save();
1197     Vector2f size = GetOptionalBufferSize();
1198     float scaleX = size.x_ / boundsWidth_;
1199     float scaleY = size.y_ / boundsHeight_;
1200     canvas.scale(scaleX, scaleY);
1201     auto cacheImage = GetCompletedImage(canvas, threadIndex, isUIFirst);
1202     if (cacheImage == nullptr) {
1203         canvas.restore();
1204         return;
1205     }
1206     if ((cacheType == CacheType::ANIMATE_PROPERTY && renderProperties_.IsShadowValid()) || isUIFirst) {
1207         auto samplingOptions = SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);
1208         canvas.drawImage(cacheImage, -shadowRectOffsetX_ * scaleX, -shadowRectOffsetY_ * scaleY, samplingOptions);
1209     } else {
1210         canvas.drawImage(cacheImage, 0.0, 0.0);
1211     }
1212     canvas.restore();
1213 }
1214 
GetCompletedImage(RSPaintFilterCanvas & canvas,uint32_t threadIndex,bool isUIFirst)1215 sk_sp<SkImage> RSRenderNode::GetCompletedImage(RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
1216 {
1217     if (isUIFirst) {
1218 #if defined(NEW_SKIA) && defined(RS_ENABLE_GL)
1219         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1220         if (!cacheCompletedBackendTexture_.isValid()) {
1221             RS_LOGE("invalid grBackendTexture_");
1222             return nullptr;
1223         }
1224         auto image = SkImage::MakeFromTexture(canvas.recordingContext(), cacheCompletedBackendTexture_,
1225             kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
1226         return image;
1227 #endif
1228     }
1229 
1230     if (!cacheCompletedSurface_) {
1231         RS_LOGE("DrawCacheSurface invalid cacheCompletedSurface");
1232         return nullptr;
1233     }
1234     auto completeImage = cacheCompletedSurface_->makeImageSnapshot();
1235     if (!completeImage) {
1236         RS_LOGE("Get complete image failed");
1237         return nullptr;
1238     }
1239     if (threadIndex == completedSurfaceThreadIndex_) {
1240         return completeImage;
1241     }
1242 #if defined(NEW_SKIA) && defined(RS_ENABLE_GL)
1243     GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin;
1244     auto backendTexture = completeImage->getBackendTexture(false, &origin);
1245     if (!backendTexture.isValid()) {
1246         RS_LOGE("get backendTexture failed");
1247         return nullptr;
1248     }
1249     auto cacheImage = SkImage::MakeFromTexture(canvas.recordingContext(), backendTexture, origin,
1250         completeImage->colorType(), completeImage->alphaType(), nullptr);
1251     return cacheImage;
1252 #else
1253     return completeImage;
1254 #endif
1255 }
1256 #else
DrawCacheSurface(RSPaintFilterCanvas & canvas,uint32_t threadIndex,bool isUIFirst)1257 void RSRenderNode::DrawCacheSurface(RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
1258 {
1259     auto cacheType = GetCacheType();
1260     canvas.Save();
1261     Vector2f size = GetOptionalBufferSize();
1262     float scaleX = size.x_ / boundsWidth_;
1263     float scaleY = size.y_ / boundsHeight_;
1264     canvas.Scale(scaleX, scaleY);
1265 #if defined(RS_ENABLE_GL)
1266     if (isUIFirst) {
1267         RS_LOGE("[%s:%d] Drawing is not supported", __func__, __LINE__);
1268         return;
1269     }
1270 #endif
1271     auto surface = GetCompletedCacheSurface(threadIndex, true);
1272     if (surface == nullptr || (boundsWidth_ == 0 || boundsHeight_ == 0)) {
1273         RS_LOGE("invalid complete cache surface");
1274         canvas.Restore();
1275         return;
1276     }
1277     auto image = surface->GetImageSnapshot();
1278     if (image == nullptr) {
1279         RS_LOGE("invalid complete cache image");
1280         canvas.Restore();
1281         return;
1282     }
1283     Drawing::Brush brush;
1284     canvas.AttachBrush(brush);
1285     if (cacheType == CacheType::ANIMATE_PROPERTY && renderProperties_.IsShadowValid()) {
1286         canvas.DrawImage(*image, -shadowRectOffsetX_ * scaleX,
1287             -shadowRectOffsetY_ * scaleY, Drawing::SamplingOptions());
1288     } else {
1289         canvas.DrawImage(*image, 0.0, 0.0, Drawing::SamplingOptions());
1290     }
1291     canvas.DetachBrush();
1292     canvas.Restore();
1293 }
1294 #endif
1295 
1296 #ifdef RS_ENABLE_GL
UpdateBackendTexture()1297 void RSRenderNode::UpdateBackendTexture()
1298 {
1299 #ifndef USE_ROSEN_DRAWING
1300     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1301     if (cacheSurface_ == nullptr) {
1302         return;
1303     }
1304     cacheBackendTexture_
1305         = cacheSurface_->getBackendTexture(SkSurface::BackendHandleAccess::kFlushRead_BackendHandleAccess);
1306 #else
1307     RS_LOGE("[%s:%d] Drawing is not supported", __func__, __LINE__);
1308 #endif
1309 }
1310 #endif
1311 
1312 #ifndef USE_ROSEN_DRAWING
GetCompletedCacheSurface(uint32_t threadIndex,bool needCheckThread)1313 sk_sp<SkSurface> RSRenderNode::GetCompletedCacheSurface(uint32_t threadIndex, bool needCheckThread)
1314 #else
1315 std::shared_ptr<Drawing::Surface> RSRenderNode::GetCompletedCacheSurface(uint32_t threadIndex, bool needCheckThread)
1316 #endif
1317 {
1318     {
1319         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1320         if (!needCheckThread || completedSurfaceThreadIndex_ == threadIndex || !cacheCompletedSurface_) {
1321             return cacheCompletedSurface_;
1322         }
1323     }
1324 
1325     // freeze cache scene
1326     if (clearCacheSurfaceFunc_) {
1327         clearCacheSurfaceFunc_(cacheSurface_, cacheCompletedSurface_, cacheSurfaceThreadIndex_,
1328             completedSurfaceThreadIndex_);
1329     }
1330     ClearCacheSurface();
1331     return nullptr;
1332 }
1333 
1334 #ifndef USE_ROSEN_DRAWING
GetCacheSurface(uint32_t threadIndex,bool needCheckThread)1335     sk_sp<SkSurface> RSRenderNode::GetCacheSurface(uint32_t threadIndex, bool needCheckThread)
1336 #else
1337     std::shared_ptr<Drawing::Surface> RSRenderNode::GetCacheSurface(uint32_t threadIndex, bool needCheckThread)
1338 #endif
1339 {
1340     {
1341         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1342         if (!needCheckThread || cacheSurfaceThreadIndex_ == threadIndex || !cacheSurface_) {
1343             return cacheSurface_;
1344         }
1345     }
1346 
1347     // freeze cache scene
1348     if (clearCacheSurfaceFunc_) {
1349         clearCacheSurfaceFunc_(cacheSurface_, cacheCompletedSurface_, cacheSurfaceThreadIndex_,
1350             completedSurfaceThreadIndex_);
1351     }
1352     ClearCacheSurface();
1353     return nullptr;
1354 }
1355 
CheckGroupableAnimation(const PropertyId & id,bool isAnimAdd)1356 void RSRenderNode::CheckGroupableAnimation(const PropertyId& id, bool isAnimAdd)
1357 {
1358     if (id <= 0 || GetType() != RSRenderNodeType::CANVAS_NODE) {
1359         return;
1360     }
1361     auto context = GetContext().lock();
1362     if (!context || !context->GetNodeMap().IsResidentProcessNode(GetId())) {
1363         return;
1364     }
1365     auto target = modifiers_.find(id);
1366     if (target == modifiers_.end() || !target->second) {
1367         return;
1368     }
1369     if (isAnimAdd) {
1370         if (GROUPABLE_ANIMATION_TYPE.count(target->second->GetType())) {
1371             MarkNodeGroup(NodeGroupType::GROUPED_BY_ANIM, true);
1372         } else if (CACHEABLE_ANIMATION_TYPE.count(target->second->GetType())) {
1373             hasCacheableAnim_ = true;
1374         }
1375         return;
1376     }
1377     bool hasGroupableAnim = false;
1378     hasCacheableAnim_ = false;
1379     for (auto& [_, animation] : animationManager_.animations_) {
1380         if (!animation || id == animation->GetPropertyId()) {
1381             continue;
1382         }
1383         auto itr = modifiers_.find(animation->GetPropertyId());
1384         if (itr == modifiers_.end() || !itr->second) {
1385             continue;
1386         }
1387         hasGroupableAnim = (hasGroupableAnim || (GROUPABLE_ANIMATION_TYPE.count(itr->second->GetType()) != 0));
1388         hasCacheableAnim_ = (hasCacheableAnim_ || (CACHEABLE_ANIMATION_TYPE.count(itr->second->GetType()) != 0));
1389     }
1390     MarkNodeGroup(NodeGroupType::GROUPED_BY_ANIM, hasGroupableAnim);
1391 }
1392 
IsForcedDrawInGroup() const1393 bool RSRenderNode::IsForcedDrawInGroup() const
1394 {
1395     return (nodeGroupType_ == NodeGroupType::GROUPED_BY_USER) && (renderProperties_.GetAlpha() < 1.f);
1396 }
1397 
IsSuggestedDrawInGroup() const1398 bool RSRenderNode::IsSuggestedDrawInGroup() const
1399 {
1400     return nodeGroupType_ != NodeGroupType::NONE;
1401 }
1402 
MarkNodeGroup(NodeGroupType type,bool isNodeGroup)1403 void RSRenderNode::MarkNodeGroup(NodeGroupType type, bool isNodeGroup)
1404 {
1405     if (type >= nodeGroupType_) {
1406         nodeGroupType_ = isNodeGroup ? type : NodeGroupType::NONE;
1407         SetDirty();
1408     }
1409 }
1410 
CheckDrawingCacheType()1411 void RSRenderNode::CheckDrawingCacheType()
1412 {
1413     if (nodeGroupType_ == NodeGroupType::NONE) {
1414         SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
1415     } else if ((nodeGroupType_ == NodeGroupType::GROUPED_BY_USER) && (renderProperties_.GetAlpha() < 1.f)) {
1416         SetDrawingCacheType(RSDrawingCacheType::FORCED_CACHE);
1417     } else {
1418         SetDrawingCacheType(RSDrawingCacheType::TARGETED_CACHE);
1419     }
1420 }
1421 
GetFilterRect() const1422 RectI RSRenderNode::GetFilterRect() const
1423 {
1424     auto& properties = GetRenderProperties();
1425     auto geoPtr = (properties.GetBoundsGeometry());
1426     if (!geoPtr) {
1427         return {};
1428     }
1429     if (properties.GetClipBounds() != nullptr) {
1430 #ifndef USE_ROSEN_DRAWING
1431         auto filterRect = properties.GetClipBounds()->GetSkiaPath().getBounds();
1432         auto absRect = geoPtr->GetAbsMatrix().mapRect(filterRect);
1433         return {absRect.x(), absRect.y(), absRect.width(), absRect.height()};
1434 #else
1435         auto filterRect = properties.GetClipBounds()->GetDrawingPath().GetBounds();
1436         Drawing::Rect absRect;
1437         geoPtr->GetAbsMatrix().MapRect(absRect, filterRect);
1438         return {absRect.GetLeft(), absRect.GetTop(), absRect.GetWidth(), absRect.GetHeight()};
1439 #endif
1440     } else {
1441         return geoPtr->GetAbsRect();
1442     }
1443 }
1444 
UpdateFilterCacheManagerWithCacheRegion(const std::optional<RectI> & clipRect) const1445 void RSRenderNode::UpdateFilterCacheManagerWithCacheRegion(const std::optional<RectI>& clipRect) const
1446 {
1447 #ifndef USE_ROSEN_DRAWING
1448     if (!RSProperties::FilterCacheEnabled) {
1449         return;
1450     }
1451     auto& renderProperties = GetRenderProperties();
1452     if (!renderProperties.NeedFilter()) {
1453         return;
1454     }
1455     auto filterRect = GetFilterRect();
1456     if (clipRect.has_value()) {
1457         filterRect.IntersectRect(*clipRect);
1458     }
1459     // background filter
1460     if (auto& manager = renderProperties.GetFilterCacheManager(false)) {
1461         manager->UpdateCacheStateWithFilterRegion(filterRect);
1462     }
1463     // foreground filter
1464     if (auto& manager = renderProperties.GetFilterCacheManager(true)) {
1465         manager->UpdateCacheStateWithFilterRegion(filterRect);
1466     }
1467 #endif
1468 }
1469 
OnTreeStateChanged()1470 void RSRenderNode::OnTreeStateChanged()
1471 {
1472     if (isOnTheTree_) {
1473         return;
1474     }
1475 #ifndef USE_ROSEN_DRAWING
1476     // clear filter cache when node is removed from tree
1477     if (auto& manager = renderProperties_.GetFilterCacheManager(false)) {
1478         manager->InvalidateCache();
1479     }
1480     if (auto& manager = renderProperties_.GetFilterCacheManager(true)) {
1481         manager->InvalidateCache();
1482     }
1483 #endif
1484 }
1485 
HasDisappearingTransition(bool recursive) const1486 bool RSRenderNode::HasDisappearingTransition(bool recursive) const
1487 {
1488     if (disappearingTransitionCount_ > 0) {
1489         return true;
1490     }
1491     if (recursive == false) {
1492         return false;
1493     }
1494     auto parent = GetParent().lock();
1495     if (parent == nullptr) {
1496         return false;
1497     }
1498     return parent->HasDisappearingTransition(true);
1499 }
1500 
GetChildren()1501 const std::list<RSRenderNode::SharedPtr>& RSRenderNode::GetChildren()
1502 {
1503     GenerateFullChildrenList();
1504     return fullChildrenList_;
1505 }
1506 
GetSortedChildren()1507 const std::list<RSRenderNode::SharedPtr>& RSRenderNode::GetSortedChildren()
1508 {
1509     GenerateFullChildrenList();
1510     SortChildren();
1511     return fullChildrenList_;
1512 }
1513 
GenerateFullChildrenList()1514 void RSRenderNode::GenerateFullChildrenList()
1515 {
1516     // if fullChildrenList_ is valid, just return
1517     if (isFullChildrenListValid_) {
1518         return;
1519     }
1520     // Node is currently used by sub thread, delay the operation
1521     if (NodeIsUsedBySubThread()) {
1522         return;
1523     }
1524     // maybe unnecessary, but just in case
1525     fullChildrenList_.clear();
1526     // both children_ and disappearingChildren_ are empty, no need to generate fullChildrenList_
1527     if (children_.empty() && disappearingChildren_.empty()) {
1528         isFullChildrenListValid_ = true;
1529         isChildrenSorted_ = true;
1530         return;
1531     }
1532 
1533     // Step 1: Copy all children into sortedChildren while checking and removing expired children.
1534     children_.remove_if([this](const auto& child) -> bool {
1535         auto existingChild = child.lock();
1536         if (existingChild == nullptr) {
1537             ROSEN_LOGI("RSRenderNode::GenerateSortedChildren removing expired child, this is rare but possible.");
1538             return true;
1539         }
1540         fullChildrenList_.emplace_back(std::move(existingChild));
1541         return false;
1542     });
1543 
1544     // Step 2: Insert disappearing children into sortedChildren at their original position.
1545     // Note:
1546     //     1. We don't need to check if the disappearing transition is finished; it's already handled in
1547     //     RSRenderTransition::OnDetach.
1548     //     2. We don't need to check if the disappearing child is expired; it's already been checked when moving from
1549     //     children_ to disappearingChildren_. We hold ownership of the shared_ptr of the child after that.
1550     std::for_each(disappearingChildren_.begin(), disappearingChildren_.end(), [this](const auto& pair) -> void {
1551         auto& disappearingChild = pair.first;
1552         const auto& origPos = pair.second;
1553 
1554         if (origPos < fullChildrenList_.size()) {
1555             fullChildrenList_.emplace(std::next(fullChildrenList_.begin(), origPos), disappearingChild);
1556         } else {
1557             fullChildrenList_.emplace_back(disappearingChild);
1558         }
1559     });
1560 
1561     // update flags
1562     isFullChildrenListValid_ = true;
1563     isChildrenSorted_ = false;
1564 }
1565 
SortChildren()1566 void RSRenderNode::SortChildren()
1567 {
1568     // if children are already sorted, just return
1569     if (isChildrenSorted_) {
1570         return;
1571     }
1572     // Node is currently used by sub thread, delay the operation
1573     if (NodeIsUsedBySubThread()) {
1574         return;
1575     }
1576     // sort all children by z-order (note: std::list::sort is stable) if needed
1577     fullChildrenList_.sort([](const auto& first, const auto& second) -> bool {
1578         return first->GetRenderProperties().GetPositionZ() < second->GetRenderProperties().GetPositionZ();
1579     });
1580     isChildrenSorted_ = true;
1581 }
1582 
ApplyChildrenModifiers()1583 void RSRenderNode::ApplyChildrenModifiers()
1584 {
1585     bool anyChildZOrderChanged = false;
1586     for (auto& child : GetChildren()) {
1587         anyChildZOrderChanged = child->ApplyModifiers() || anyChildZOrderChanged;
1588     }
1589     if (anyChildZOrderChanged) {
1590         isChildrenSorted_ = false;
1591     }
1592 }
1593 
GetChildrenCount() const1594 uint32_t RSRenderNode::GetChildrenCount() const
1595 {
1596     return children_.size();
1597 }
1598 
IsOnTheTree() const1599 bool RSRenderNode::IsOnTheTree() const
1600 {
1601     return isOnTheTree_;
1602 }
SetTunnelHandleChange(bool change)1603 void RSRenderNode::SetTunnelHandleChange(bool change)
1604 {
1605     isTunnelHandleChange_ = change;
1606 }
GetTunnelHandleChange() const1607 bool RSRenderNode::GetTunnelHandleChange() const
1608 {
1609     return isTunnelHandleChange_;
1610 }
HasChildrenOutOfRect() const1611 bool RSRenderNode::HasChildrenOutOfRect() const
1612 {
1613     return hasChildrenOutOfRect_;
1614 }
UpdateChildrenOutOfRectFlag(bool flag)1615 void RSRenderNode::UpdateChildrenOutOfRectFlag(bool flag)
1616 {
1617     hasChildrenOutOfRect_ = flag;
1618 }
ResetHasRemovedChild()1619 void RSRenderNode::ResetHasRemovedChild()
1620 {
1621     hasRemovedChild_ = false;
1622 }
HasRemovedChild() const1623 bool RSRenderNode::HasRemovedChild() const
1624 {
1625     return hasRemovedChild_;
1626 }
ResetChildrenRect()1627 void RSRenderNode::ResetChildrenRect()
1628 {
1629     childrenRect_ = RectI();
1630 }
GetChildrenRect() const1631 RectI RSRenderNode::GetChildrenRect() const
1632 {
1633     return childrenRect_;
1634 }
ChildHasFilter() const1635 bool RSRenderNode::ChildHasFilter() const
1636 {
1637     return childHasFilter_;
1638 }
SetChildHasFilter(bool childHasFilter)1639 void RSRenderNode::SetChildHasFilter(bool childHasFilter)
1640 {
1641     childHasFilter_ = childHasFilter;
1642 }
GetInstanceRootNodeId() const1643 NodeId RSRenderNode::GetInstanceRootNodeId() const
1644 {
1645     return instanceRootNodeId_;
1646 }
IsRenderUpdateIgnored() const1647 bool RSRenderNode::IsRenderUpdateIgnored() const
1648 {
1649     return isRenderUpdateIgnored_;
1650 }
GetAnimationManager()1651 RSAnimationManager& RSRenderNode::GetAnimationManager()
1652 {
1653     return animationManager_;
1654 }
GetOldDirty() const1655 RectI RSRenderNode::GetOldDirty() const
1656 {
1657     return oldDirty_;
1658 }
GetOldDirtyInSurface() const1659 RectI RSRenderNode::GetOldDirtyInSurface() const
1660 {
1661     return oldDirtyInSurface_;
1662 }
IsDirtyRegionUpdated() const1663 bool RSRenderNode::IsDirtyRegionUpdated() const
1664 {
1665     return isDirtyRegionUpdated_;
1666 }
IsShadowValidLastFrame() const1667 bool RSRenderNode::IsShadowValidLastFrame() const
1668 {
1669     return isShadowValidLastFrame_;
1670 }
SetStaticCached(bool isStaticCached)1671 void RSRenderNode::SetStaticCached(bool isStaticCached)
1672 {
1673     isStaticCached_ = isStaticCached;
1674 }
IsStaticCached() const1675 bool RSRenderNode::IsStaticCached() const
1676 {
1677     return isStaticCached_;
1678 }
UpdateCompletedCacheSurface()1679 void RSRenderNode::UpdateCompletedCacheSurface()
1680 {
1681     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1682     std::swap(cacheSurface_, cacheCompletedSurface_);
1683     std::swap(cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
1684 #ifndef USE_ROSEN_DRAWING
1685 #ifdef RS_ENABLE_GL
1686     std::swap(cacheBackendTexture_, cacheCompletedBackendTexture_);
1687     SetTextureValidFlag(true);
1688 #endif
1689 #endif
1690 }
SetTextureValidFlag(bool isValid)1691 void RSRenderNode::SetTextureValidFlag(bool isValid)
1692 {
1693 #ifndef USE_ROSEN_DRAWING
1694 #ifdef RS_ENABLE_GL
1695     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1696     isTextureValid_ = isValid;
1697 #endif
1698 #endif
1699 }
ClearCacheSurface()1700 void RSRenderNode::ClearCacheSurface()
1701 {
1702     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1703     cacheSurface_ = nullptr;
1704     cacheCompletedSurface_ = nullptr;
1705 }
SetCacheType(CacheType cacheType)1706 void RSRenderNode::SetCacheType(CacheType cacheType)
1707 {
1708     cacheType_ = cacheType;
1709 }
GetCacheType() const1710 CacheType RSRenderNode::GetCacheType() const
1711 {
1712     return cacheType_;
1713 }
GetShadowRectOffsetX() const1714 int RSRenderNode::GetShadowRectOffsetX() const
1715 {
1716     return shadowRectOffsetX_;
1717 }
GetShadowRectOffsetY() const1718 int RSRenderNode::GetShadowRectOffsetY() const
1719 {
1720     return shadowRectOffsetY_;
1721 }
SetDrawingCacheType(RSDrawingCacheType cacheType)1722 void RSRenderNode::SetDrawingCacheType(RSDrawingCacheType cacheType)
1723 {
1724     drawingCacheType_ = cacheType;
1725 }
GetDrawingCacheType() const1726 RSDrawingCacheType RSRenderNode::GetDrawingCacheType() const
1727 {
1728     return drawingCacheType_;
1729 }
SetDrawingCacheChanged(bool cacheChanged)1730 void RSRenderNode::SetDrawingCacheChanged(bool cacheChanged)
1731 {
1732     isDrawingCacheChanged_ = cacheChanged;
1733 }
GetDrawingCacheChanged() const1734 bool RSRenderNode::GetDrawingCacheChanged() const
1735 {
1736     return isDrawingCacheChanged_;
1737 }
SetIsMarkDriven(bool isMarkDriven)1738 void RSRenderNode::SetIsMarkDriven(bool isMarkDriven)
1739 {
1740     isMarkDriven_ = isMarkDriven;
1741 }
IsMarkDriven() const1742 bool RSRenderNode::IsMarkDriven() const
1743 {
1744     return isMarkDriven_;
1745 }
SetIsMarkDrivenRender(bool isMarkDrivenRender)1746 void RSRenderNode::SetIsMarkDrivenRender(bool isMarkDrivenRender)
1747 {
1748     isMarkDrivenRender_ = isMarkDrivenRender;
1749 }
IsMarkDrivenRender() const1750 bool RSRenderNode::IsMarkDrivenRender() const
1751 {
1752     return isMarkDrivenRender_;
1753 }
SetItemIndex(int index)1754 void RSRenderNode::SetItemIndex(int index)
1755 {
1756     itemIndex_ = index;
1757 }
GetItemIndex() const1758 int RSRenderNode::GetItemIndex() const
1759 {
1760     return itemIndex_;
1761 }
SetPaintState(bool paintState)1762 void RSRenderNode::SetPaintState(bool paintState)
1763 {
1764     paintState_ = paintState;
1765 }
GetPaintState() const1766 bool RSRenderNode::GetPaintState() const
1767 {
1768     return paintState_;
1769 }
SetIsContentChanged(bool isChanged)1770 void RSRenderNode::SetIsContentChanged(bool isChanged)
1771 {
1772     isContentChanged_ = isChanged;
1773 }
IsContentChanged() const1774 bool RSRenderNode::IsContentChanged() const
1775 {
1776     return isContentChanged_ || HasAnimation();
1777 }
HasAnimation() const1778 bool RSRenderNode::HasAnimation() const
1779 {
1780     return !animationManager_.animations_.empty();
1781 }
HasFilter() const1782 bool RSRenderNode::HasFilter() const
1783 {
1784     return hasFilter_;
1785 }
SetHasFilter(bool hasFilter)1786 void RSRenderNode::SetHasFilter(bool hasFilter)
1787 {
1788     hasFilter_ = hasFilter;
1789 }
GetSurfaceMutex() const1790 std::recursive_mutex& RSRenderNode::GetSurfaceMutex() const
1791 {
1792     return surfaceMutex_;
1793 }
HasHardwareNode() const1794 bool RSRenderNode::HasHardwareNode() const
1795 {
1796     return hasHardwareNode_;
1797 }
SetHasHardwareNode(bool hasHardwareNode)1798 void RSRenderNode::SetHasHardwareNode(bool hasHardwareNode)
1799 {
1800     hasHardwareNode_ = hasHardwareNode;
1801 }
HasAbilityComponent() const1802 bool RSRenderNode::HasAbilityComponent() const
1803 {
1804     return hasAbilityComponent_;
1805 }
SetHasAbilityComponent(bool hasAbilityComponent)1806 void RSRenderNode::SetHasAbilityComponent(bool hasAbilityComponent)
1807 {
1808     hasAbilityComponent_ = hasAbilityComponent;
1809 }
GetCacheSurfaceThreadIndex() const1810 uint32_t RSRenderNode::GetCacheSurfaceThreadIndex() const
1811 {
1812     return cacheSurfaceThreadIndex_;
1813 }
QuerySubAssignable(bool isRotation) const1814 bool RSRenderNode::QuerySubAssignable(bool isRotation) const
1815 {
1816     return !hasFilter_ && !hasAbilityComponent_ && !isRotation && !hasHardwareNode_;
1817 }
GetCompletedSurfaceThreadIndex() const1818 uint32_t RSRenderNode::GetCompletedSurfaceThreadIndex() const
1819 {
1820     return completedSurfaceThreadIndex_;
1821 }
1822 
IsMainThreadNode() const1823 bool RSRenderNode::IsMainThreadNode() const
1824 {
1825     return isMainThreadNode_;
1826 }
SetIsMainThreadNode(bool isMainThreadNode)1827 void RSRenderNode::SetIsMainThreadNode(bool isMainThreadNode)
1828 {
1829     isMainThreadNode_ = isMainThreadNode;
1830 }
IsScale() const1831 bool RSRenderNode::IsScale() const
1832 {
1833     return isScale_;
1834 }
SetIsScale(bool isScale)1835 void RSRenderNode::SetIsScale(bool isScale)
1836 {
1837     isScale_ = isScale;
1838 }
SetPriority(NodePriorityType priority)1839 void RSRenderNode::SetPriority(NodePriorityType priority)
1840 {
1841     priority_ = priority;
1842 }
GetPriority()1843 NodePriorityType RSRenderNode::GetPriority()
1844 {
1845     return priority_;
1846 }
IsAncestorDirty() const1847 bool RSRenderNode::IsAncestorDirty() const
1848 {
1849     return isAncestorDirty_;
1850 }
SetIsAncestorDirty(bool isAncestorDirty)1851 void RSRenderNode::SetIsAncestorDirty(bool isAncestorDirty)
1852 {
1853     isAncestorDirty_ = isAncestorDirty;
1854 }
HasCachedTexture() const1855 bool RSRenderNode::HasCachedTexture() const
1856 {
1857 #ifndef USE_ROSEN_DRAWING
1858 #ifdef RS_ENABLE_GL
1859     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1860     return isTextureValid_;
1861 #else
1862     return true;
1863 #endif
1864 #else
1865     return false;
1866 #endif
1867 }
SetDrawRegion(std::shared_ptr<RectF> rect)1868 void RSRenderNode::SetDrawRegion(std::shared_ptr<RectF> rect)
1869 {
1870     drawRegion_ = rect;
1871     renderProperties_.SetDrawRegion(rect);
1872 }
GetDrawRegion() const1873 std::shared_ptr<RectF> RSRenderNode::GetDrawRegion() const
1874 {
1875     return drawRegion_;
1876 }
GetNodeGroupType()1877 RSRenderNode::NodeGroupType RSRenderNode::GetNodeGroupType()
1878 {
1879     return nodeGroupType_;
1880 }
SetRSFrameRateRange(FrameRateRange range)1881 void RSRenderNode::SetRSFrameRateRange(FrameRateRange range)
1882 {
1883     rsRange_ = range;
1884 }
SetUIFrameRateRange(FrameRateRange range)1885 void RSRenderNode::SetUIFrameRateRange(FrameRateRange range)
1886 {
1887     uiRange_ = range;
1888 }
GetUIFrameRateRange() const1889 FrameRateRange RSRenderNode::GetUIFrameRateRange() const
1890 {
1891     return uiRange_;
1892 }
MarkNonGeometryChanged()1893 void RSRenderNode::MarkNonGeometryChanged()
1894 {
1895     geometryChangeNotPerceived_ = true;
1896 }
GetHgmModifierProfileList() const1897 std::vector<HgmModifierProfile> RSRenderNode::GetHgmModifierProfileList() const
1898 {
1899     return hgmModifierProfileList_;
1900 }
1901 } // namespace Rosen
1902 } // namespace OHOS
1903