• 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     float width = 0.0f, height = 0.0f;
1072     if (cacheType == CacheType::ANIMATE_PROPERTY &&
1073         renderProperties_.IsShadowValid() && !renderProperties_.IsSpherizeValid()) {
1074         const RectF boundsRect = renderProperties_.GetBoundsRect();
1075         RRect rrect = RRect(boundsRect, {0, 0, 0, 0});
1076         RectI shadowRect;
1077         RSPropertiesPainter::GetShadowDirtyRect(shadowRect, renderProperties_, &rrect, false);
1078         width = shadowRect.GetWidth();
1079         height = shadowRect.GetHeight();
1080     } else {
1081         Vector2f size = GetOptionalBufferSize();
1082         width =  size.x_;
1083         height = size.y_;
1084     }
1085     return cacheSurface_->width() != width || cacheSurface_->height() !=height;
1086 }
1087 
1088 #ifndef USE_ROSEN_DRAWING
1089 #ifdef NEW_SKIA
InitCacheSurface(GrRecordingContext * grContext,ClearCacheSurfaceFunc func,uint32_t threadIndex)1090 void RSRenderNode::InitCacheSurface(GrRecordingContext* grContext, ClearCacheSurfaceFunc func, uint32_t threadIndex)
1091 #else
1092 void RSRenderNode::InitCacheSurface(GrContext* grContext, ClearCacheSurfaceFunc func, uint32_t threadIndex)
1093 #endif
1094 #else
1095 void RSRenderNode::InitCacheSurface(Drawing::GPUContext* gpuContext, ClearCacheSurfaceFunc func, uint32_t threadIndex)
1096 #endif
1097 {
1098     if (func) {
1099         cacheSurfaceThreadIndex_ = threadIndex;
1100         if (!clearCacheSurfaceFunc_) {
1101             clearCacheSurfaceFunc_ = func;
1102         }
1103         if (cacheSurface_) {
1104             func(cacheSurface_, cacheCompletedSurface_, cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
1105             ClearCacheSurface();
1106         }
1107     } else {
1108         cacheSurface_ = nullptr;
1109     }
1110     auto cacheType = GetCacheType();
1111     float width = 0.0f, height = 0.0f;
1112     Vector2f size = GetOptionalBufferSize();
1113     boundsWidth_ = size.x_;
1114     boundsHeight_ = size.y_;
1115     if (cacheType == CacheType::ANIMATE_PROPERTY &&
1116         renderProperties_.IsShadowValid() && !renderProperties_.IsSpherizeValid()) {
1117         const RectF boundsRect = renderProperties_.GetBoundsRect();
1118         RRect rrect = RRect(boundsRect, {0, 0, 0, 0});
1119         RectI shadowRect;
1120         RSPropertiesPainter::GetShadowDirtyRect(shadowRect, renderProperties_, &rrect, false);
1121         width = shadowRect.GetWidth();
1122         height = shadowRect.GetHeight();
1123         shadowRectOffsetX_ = -shadowRect.GetLeft();
1124         shadowRectOffsetY_ = -shadowRect.GetTop();
1125     } else {
1126         width = boundsWidth_;
1127         height = boundsHeight_;
1128     }
1129 #ifndef USE_ROSEN_DRAWING
1130 #if ((defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)) || (defined RS_ENABLE_VK)
1131     if (grContext == nullptr) {
1132         if (func) {
1133             func(cacheSurface_, cacheCompletedSurface_, cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
1134             ClearCacheSurface();
1135         }
1136         return;
1137     }
1138     SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
1139     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1140     cacheSurface_ = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kYes, info);
1141 #else
1142     cacheSurface_ = SkSurface::MakeRasterN32Premul(width, height);
1143 #endif
1144 #else // USE_ROSEN_DRAWING
1145     Drawing::BitmapFormat format = { Drawing::ColorType::COLORTYPE_N32, Drawing::AlphaType::ALPHATYPE_PREMUL };
1146     auto bitmap = std::make_shared<Drawing::Bitmap>();
1147     bitmap->Build(width, height, format);
1148 #if ((defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)) || (defined RS_ENABLE_VK)
1149     if (gpuContext == nullptr) {
1150         if (func) {
1151             func(cacheSurface_, cacheCompletedSurface_, cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
1152             ClearCacheSurface();
1153         }
1154         return;
1155     }
1156     auto image = std::make_shared<Drawing::Image>();
1157     if (!image->BuildFromBitmap(*gpuContext, *bitmap)) {
1158         RS_LOGE("InitCacheSurface: image BuildFromBitmap failed");
1159         return;
1160     }
1161     auto surface = std::make_shared<Drawing::Surface>();
1162     if (!surface->Bind(*image)) {
1163         RS_LOGE("InitCacheSurface: surface bind image failed");
1164         return;
1165     }
1166 #else
1167     auto surface = std::make_shared<Drawing::Surface>();
1168     if (!surface->Bind(*bitmap)) {
1169         RS_LOGE("InitCacheSurface: surface bind bitmap failed");
1170         return;
1171     }
1172 #endif
1173     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1174     cacheBitmap_ = bitmap;
1175     cacheSurface_ = surface;
1176 #endif // USE_ROSEN_DRAWING
1177 }
1178 
GetOptionalBufferSize() const1179 Vector2f RSRenderNode::GetOptionalBufferSize() const
1180 {
1181     const auto& modifier = boundsModifier_ ? boundsModifier_ : frameModifier_;
1182     if (!modifier) {
1183         return {0.0f, 0.0f};
1184     }
1185     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(modifier->GetProperty());
1186     auto vector4f = renderProperty->Get();
1187     // bounds vector4f: x y z w -> left top width height
1188     return { vector4f.z_, vector4f.w_ };
1189 }
1190 
1191 #ifndef USE_ROSEN_DRAWING
DrawCacheSurface(RSPaintFilterCanvas & canvas,uint32_t threadIndex,bool isUIFirst)1192 void RSRenderNode::DrawCacheSurface(RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
1193 {
1194     auto cacheType = GetCacheType();
1195     canvas.save();
1196     Vector2f size = GetOptionalBufferSize();
1197     float scaleX = size.x_ / boundsWidth_;
1198     float scaleY = size.y_ / boundsHeight_;
1199     canvas.scale(scaleX, scaleY);
1200     auto cacheImage = GetCompletedImage(canvas, threadIndex, isUIFirst);
1201     if (cacheImage == nullptr) {
1202         canvas.restore();
1203         return;
1204     }
1205     if ((cacheType == CacheType::ANIMATE_PROPERTY && renderProperties_.IsShadowValid()) || isUIFirst) {
1206         auto samplingOptions = SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);
1207         canvas.drawImage(cacheImage, -shadowRectOffsetX_ * scaleX, -shadowRectOffsetY_ * scaleY, samplingOptions);
1208     } else {
1209         canvas.drawImage(cacheImage, 0.0, 0.0);
1210     }
1211     canvas.restore();
1212 }
1213 
GetCompletedImage(RSPaintFilterCanvas & canvas,uint32_t threadIndex,bool isUIFirst)1214 sk_sp<SkImage> RSRenderNode::GetCompletedImage(RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
1215 {
1216     if (isUIFirst) {
1217 #if defined(NEW_SKIA) && defined(RS_ENABLE_GL)
1218         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1219         if (!cacheCompletedBackendTexture_.isValid()) {
1220             RS_LOGE("invalid grBackendTexture_");
1221             return nullptr;
1222         }
1223         auto image = SkImage::MakeFromTexture(canvas.recordingContext(), cacheCompletedBackendTexture_,
1224             kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
1225         return image;
1226 #endif
1227     }
1228 
1229     if (!cacheCompletedSurface_) {
1230         RS_LOGE("DrawCacheSurface invalid cacheCompletedSurface");
1231         return nullptr;
1232     }
1233     auto completeImage = cacheCompletedSurface_->makeImageSnapshot();
1234     if (!completeImage) {
1235         RS_LOGE("Get complete image failed");
1236         return nullptr;
1237     }
1238     if (threadIndex == completedSurfaceThreadIndex_) {
1239         return completeImage;
1240     }
1241 #if defined(NEW_SKIA) && defined(RS_ENABLE_GL)
1242     GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin;
1243     auto backendTexture = completeImage->getBackendTexture(false, &origin);
1244     if (!backendTexture.isValid()) {
1245         RS_LOGE("get backendTexture failed");
1246         return nullptr;
1247     }
1248     auto cacheImage = SkImage::MakeFromTexture(canvas.recordingContext(), backendTexture, origin,
1249         completeImage->colorType(), completeImage->alphaType(), nullptr);
1250     return cacheImage;
1251 #else
1252     return completeImage;
1253 #endif
1254 }
1255 #else
DrawCacheSurface(RSPaintFilterCanvas & canvas,uint32_t threadIndex,bool isUIFirst)1256 void RSRenderNode::DrawCacheSurface(RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
1257 {
1258     auto cacheType = GetCacheType();
1259     canvas.Save();
1260     Vector2f size = GetOptionalBufferSize();
1261     float scaleX = size.x_ / boundsWidth_;
1262     float scaleY = size.y_ / boundsHeight_;
1263     canvas.Scale(scaleX, scaleY);
1264 #if defined(RS_ENABLE_GL)
1265     if (isUIFirst) {
1266         RS_LOGE("[%s:%d] Drawing is not supported", __func__, __LINE__);
1267         return;
1268     }
1269 #endif
1270     auto surface = GetCompletedCacheSurface(threadIndex, true);
1271     if (surface == nullptr || (boundsWidth_ == 0 || boundsHeight_ == 0)) {
1272         RS_LOGE("invalid complete cache surface");
1273         canvas.Restore();
1274         return;
1275     }
1276     auto image = surface->GetImageSnapshot();
1277     if (image == nullptr) {
1278         RS_LOGE("invalid complete cache image");
1279         canvas.Restore();
1280         return;
1281     }
1282     Drawing::Brush brush;
1283     canvas.AttachBrush(brush);
1284     if (cacheType == CacheType::ANIMATE_PROPERTY && renderProperties_.IsShadowValid()) {
1285         canvas.DrawImage(*image, -shadowRectOffsetX_ * scaleX,
1286             -shadowRectOffsetY_ * scaleY, Drawing::SamplingOptions());
1287     } else {
1288         canvas.DrawImage(*image, 0.0, 0.0, Drawing::SamplingOptions());
1289     }
1290     canvas.DetachBrush();
1291     canvas.Restore();
1292 }
1293 #endif
1294 
1295 #ifdef RS_ENABLE_GL
UpdateBackendTexture()1296 void RSRenderNode::UpdateBackendTexture()
1297 {
1298 #ifndef USE_ROSEN_DRAWING
1299     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1300     if (cacheSurface_ == nullptr) {
1301         return;
1302     }
1303     cacheBackendTexture_
1304         = cacheSurface_->getBackendTexture(SkSurface::BackendHandleAccess::kFlushRead_BackendHandleAccess);
1305 #else
1306     RS_LOGE("[%s:%d] Drawing is not supported", __func__, __LINE__);
1307 #endif
1308 }
1309 #endif
1310 
1311 #ifndef USE_ROSEN_DRAWING
GetCompletedCacheSurface(uint32_t threadIndex,bool needCheckThread)1312 sk_sp<SkSurface> RSRenderNode::GetCompletedCacheSurface(uint32_t threadIndex, bool needCheckThread)
1313 #else
1314 std::shared_ptr<Drawing::Surface> RSRenderNode::GetCompletedCacheSurface(uint32_t threadIndex, bool needCheckThread)
1315 #endif
1316 {
1317     {
1318         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1319         if (!needCheckThread || completedSurfaceThreadIndex_ == threadIndex || !cacheCompletedSurface_) {
1320             return cacheCompletedSurface_;
1321         }
1322     }
1323 
1324     // freeze cache scene
1325     if (clearCacheSurfaceFunc_) {
1326         clearCacheSurfaceFunc_(cacheSurface_, cacheCompletedSurface_, cacheSurfaceThreadIndex_,
1327             completedSurfaceThreadIndex_);
1328     }
1329     ClearCacheSurface();
1330     return nullptr;
1331 }
1332 
1333 #ifndef USE_ROSEN_DRAWING
GetCacheSurface(uint32_t threadIndex,bool needCheckThread)1334     sk_sp<SkSurface> RSRenderNode::GetCacheSurface(uint32_t threadIndex, bool needCheckThread)
1335 #else
1336     std::shared_ptr<Drawing::Surface> RSRenderNode::GetCacheSurface(uint32_t threadIndex, bool needCheckThread)
1337 #endif
1338 {
1339     {
1340         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1341         if (!needCheckThread || cacheSurfaceThreadIndex_ == threadIndex || !cacheSurface_) {
1342             return cacheSurface_;
1343         }
1344     }
1345 
1346     // freeze cache scene
1347     if (clearCacheSurfaceFunc_) {
1348         clearCacheSurfaceFunc_(cacheSurface_, cacheCompletedSurface_, cacheSurfaceThreadIndex_,
1349             completedSurfaceThreadIndex_);
1350     }
1351     ClearCacheSurface();
1352     return nullptr;
1353 }
1354 
CheckGroupableAnimation(const PropertyId & id,bool isAnimAdd)1355 void RSRenderNode::CheckGroupableAnimation(const PropertyId& id, bool isAnimAdd)
1356 {
1357     if (id <= 0 || GetType() != RSRenderNodeType::CANVAS_NODE) {
1358         return;
1359     }
1360     auto context = GetContext().lock();
1361     if (!context || !context->GetNodeMap().IsResidentProcessNode(GetId())) {
1362         return;
1363     }
1364     auto target = modifiers_.find(id);
1365     if (target == modifiers_.end() || !target->second) {
1366         return;
1367     }
1368     if (isAnimAdd) {
1369         if (GROUPABLE_ANIMATION_TYPE.count(target->second->GetType())) {
1370             MarkNodeGroup(NodeGroupType::GROUPED_BY_ANIM, true);
1371         } else if (CACHEABLE_ANIMATION_TYPE.count(target->second->GetType())) {
1372             hasCacheableAnim_ = true;
1373         }
1374         return;
1375     }
1376     bool hasGroupableAnim = false;
1377     hasCacheableAnim_ = false;
1378     for (auto& [_, animation] : animationManager_.animations_) {
1379         if (!animation || id == animation->GetPropertyId()) {
1380             continue;
1381         }
1382         auto itr = modifiers_.find(animation->GetPropertyId());
1383         if (itr == modifiers_.end() || !itr->second) {
1384             continue;
1385         }
1386         hasGroupableAnim = (hasGroupableAnim || (GROUPABLE_ANIMATION_TYPE.count(itr->second->GetType()) != 0));
1387         hasCacheableAnim_ = (hasCacheableAnim_ || (CACHEABLE_ANIMATION_TYPE.count(itr->second->GetType()) != 0));
1388     }
1389     MarkNodeGroup(NodeGroupType::GROUPED_BY_ANIM, hasGroupableAnim);
1390 }
1391 
IsForcedDrawInGroup() const1392 bool RSRenderNode::IsForcedDrawInGroup() const
1393 {
1394     return (nodeGroupType_ == NodeGroupType::GROUPED_BY_USER) && (renderProperties_.GetAlpha() < 1.f);
1395 }
1396 
IsSuggestedDrawInGroup() const1397 bool RSRenderNode::IsSuggestedDrawInGroup() const
1398 {
1399     return nodeGroupType_ != NodeGroupType::NONE;
1400 }
1401 
MarkNodeGroup(NodeGroupType type,bool isNodeGroup)1402 void RSRenderNode::MarkNodeGroup(NodeGroupType type, bool isNodeGroup)
1403 {
1404     if (type >= nodeGroupType_) {
1405         nodeGroupType_ = isNodeGroup ? type : NodeGroupType::NONE;
1406         SetDirty();
1407     }
1408 }
1409 
CheckDrawingCacheType()1410 void RSRenderNode::CheckDrawingCacheType()
1411 {
1412     if (nodeGroupType_ == NodeGroupType::NONE) {
1413         SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
1414     } else if ((nodeGroupType_ == NodeGroupType::GROUPED_BY_USER) && (renderProperties_.GetAlpha() < 1.f)) {
1415         SetDrawingCacheType(RSDrawingCacheType::FORCED_CACHE);
1416     } else {
1417         SetDrawingCacheType(RSDrawingCacheType::TARGETED_CACHE);
1418     }
1419 }
1420 
GetFilterRect() const1421 RectI RSRenderNode::GetFilterRect() const
1422 {
1423     auto& properties = GetRenderProperties();
1424     auto geoPtr = (properties.GetBoundsGeometry());
1425     if (!geoPtr) {
1426         return {};
1427     }
1428     if (properties.GetClipBounds() != nullptr) {
1429 #ifndef USE_ROSEN_DRAWING
1430         auto filterRect = properties.GetClipBounds()->GetSkiaPath().getBounds();
1431         auto absRect = geoPtr->GetAbsMatrix().mapRect(filterRect);
1432         return {absRect.x(), absRect.y(), absRect.width(), absRect.height()};
1433 #else
1434         auto filterRect = properties.GetClipBounds()->GetDrawingPath().GetBounds();
1435         Drawing::Rect absRect;
1436         geoPtr->GetAbsMatrix().MapRect(absRect, filterRect);
1437         return {absRect.GetLeft(), absRect.GetTop(), absRect.GetWidth(), absRect.GetHeight()};
1438 #endif
1439     } else {
1440         return geoPtr->GetAbsRect();
1441     }
1442 }
1443 
UpdateFilterCacheManagerWithCacheRegion(const std::optional<RectI> & clipRect) const1444 void RSRenderNode::UpdateFilterCacheManagerWithCacheRegion(const std::optional<RectI>& clipRect) const
1445 {
1446 #ifndef USE_ROSEN_DRAWING
1447     if (!RSProperties::FilterCacheEnabled) {
1448         return;
1449     }
1450     auto& renderProperties = GetRenderProperties();
1451     if (!renderProperties.NeedFilter()) {
1452         return;
1453     }
1454     auto filterRect = GetFilterRect();
1455     if (clipRect.has_value()) {
1456         filterRect.IntersectRect(*clipRect);
1457     }
1458     // background filter
1459     if (auto& manager = renderProperties.GetFilterCacheManager(false)) {
1460         manager->UpdateCacheStateWithFilterRegion(filterRect);
1461     }
1462     // foreground filter
1463     if (auto& manager = renderProperties.GetFilterCacheManager(true)) {
1464         manager->UpdateCacheStateWithFilterRegion(filterRect);
1465     }
1466 #endif
1467 }
1468 
OnTreeStateChanged()1469 void RSRenderNode::OnTreeStateChanged()
1470 {
1471     if (isOnTheTree_) {
1472         return;
1473     }
1474 #ifndef USE_ROSEN_DRAWING
1475     // clear filter cache when node is removed from tree
1476     if (auto& manager = renderProperties_.GetFilterCacheManager(false)) {
1477         manager->InvalidateCache();
1478     }
1479     if (auto& manager = renderProperties_.GetFilterCacheManager(true)) {
1480         manager->InvalidateCache();
1481     }
1482 #endif
1483 }
1484 
HasDisappearingTransition(bool recursive) const1485 bool RSRenderNode::HasDisappearingTransition(bool recursive) const
1486 {
1487     if (disappearingTransitionCount_ > 0) {
1488         return true;
1489     }
1490     if (recursive == false) {
1491         return false;
1492     }
1493     auto parent = GetParent().lock();
1494     if (parent == nullptr) {
1495         return false;
1496     }
1497     return parent->HasDisappearingTransition(true);
1498 }
1499 
GetChildren()1500 const std::list<RSRenderNode::SharedPtr>& RSRenderNode::GetChildren()
1501 {
1502     GenerateFullChildrenList();
1503     return fullChildrenList_;
1504 }
1505 
GetSortedChildren()1506 const std::list<RSRenderNode::SharedPtr>& RSRenderNode::GetSortedChildren()
1507 {
1508     GenerateFullChildrenList();
1509     SortChildren();
1510     return fullChildrenList_;
1511 }
1512 
GenerateFullChildrenList()1513 void RSRenderNode::GenerateFullChildrenList()
1514 {
1515     // if fullChildrenList_ is valid, just return
1516     if (isFullChildrenListValid_) {
1517         return;
1518     }
1519     // Node is currently used by sub thread, delay the operation
1520     if (NodeIsUsedBySubThread()) {
1521         return;
1522     }
1523     // maybe unnecessary, but just in case
1524     fullChildrenList_.clear();
1525     // both children_ and disappearingChildren_ are empty, no need to generate fullChildrenList_
1526     if (children_.empty() && disappearingChildren_.empty()) {
1527         isFullChildrenListValid_ = true;
1528         isChildrenSorted_ = true;
1529         return;
1530     }
1531 
1532     // Step 1: Copy all children into sortedChildren while checking and removing expired children.
1533     children_.remove_if([this](const auto& child) -> bool {
1534         auto existingChild = child.lock();
1535         if (existingChild == nullptr) {
1536             ROSEN_LOGI("RSRenderNode::GenerateSortedChildren removing expired child, this is rare but possible.");
1537             return true;
1538         }
1539         fullChildrenList_.emplace_back(std::move(existingChild));
1540         return false;
1541     });
1542 
1543     // Step 2: Insert disappearing children into sortedChildren at their original position.
1544     // Note:
1545     //     1. We don't need to check if the disappearing transition is finished; it's already handled in
1546     //     RSRenderTransition::OnDetach.
1547     //     2. We don't need to check if the disappearing child is expired; it's already been checked when moving from
1548     //     children_ to disappearingChildren_. We hold ownership of the shared_ptr of the child after that.
1549     std::for_each(disappearingChildren_.begin(), disappearingChildren_.end(), [this](const auto& pair) -> void {
1550         auto& disappearingChild = pair.first;
1551         const auto& origPos = pair.second;
1552 
1553         if (origPos < fullChildrenList_.size()) {
1554             fullChildrenList_.emplace(std::next(fullChildrenList_.begin(), origPos), disappearingChild);
1555         } else {
1556             fullChildrenList_.emplace_back(disappearingChild);
1557         }
1558     });
1559 
1560     // update flags
1561     isFullChildrenListValid_ = true;
1562     isChildrenSorted_ = false;
1563 }
1564 
SortChildren()1565 void RSRenderNode::SortChildren()
1566 {
1567     // if children are already sorted, just return
1568     if (isChildrenSorted_) {
1569         return;
1570     }
1571     // Node is currently used by sub thread, delay the operation
1572     if (NodeIsUsedBySubThread()) {
1573         return;
1574     }
1575     // sort all children by z-order (note: std::list::sort is stable) if needed
1576     fullChildrenList_.sort([](const auto& first, const auto& second) -> bool {
1577         return first->GetRenderProperties().GetPositionZ() < second->GetRenderProperties().GetPositionZ();
1578     });
1579     isChildrenSorted_ = true;
1580 }
1581 
ApplyChildrenModifiers()1582 void RSRenderNode::ApplyChildrenModifiers()
1583 {
1584     bool anyChildZOrderChanged = false;
1585     for (auto& child : GetChildren()) {
1586         anyChildZOrderChanged = child->ApplyModifiers() || anyChildZOrderChanged;
1587     }
1588     if (anyChildZOrderChanged) {
1589         isChildrenSorted_ = false;
1590     }
1591 }
1592 
GetChildrenCount() const1593 uint32_t RSRenderNode::GetChildrenCount() const
1594 {
1595     return children_.size();
1596 }
1597 
IsOnTheTree() const1598 bool RSRenderNode::IsOnTheTree() const
1599 {
1600     return isOnTheTree_;
1601 }
SetTunnelHandleChange(bool change)1602 void RSRenderNode::SetTunnelHandleChange(bool change)
1603 {
1604     isTunnelHandleChange_ = change;
1605 }
GetTunnelHandleChange() const1606 bool RSRenderNode::GetTunnelHandleChange() const
1607 {
1608     return isTunnelHandleChange_;
1609 }
HasChildrenOutOfRect() const1610 bool RSRenderNode::HasChildrenOutOfRect() const
1611 {
1612     return hasChildrenOutOfRect_;
1613 }
UpdateChildrenOutOfRectFlag(bool flag)1614 void RSRenderNode::UpdateChildrenOutOfRectFlag(bool flag)
1615 {
1616     hasChildrenOutOfRect_ = flag;
1617 }
ResetHasRemovedChild()1618 void RSRenderNode::ResetHasRemovedChild()
1619 {
1620     hasRemovedChild_ = false;
1621 }
HasRemovedChild() const1622 bool RSRenderNode::HasRemovedChild() const
1623 {
1624     return hasRemovedChild_;
1625 }
ResetChildrenRect()1626 void RSRenderNode::ResetChildrenRect()
1627 {
1628     childrenRect_ = RectI();
1629 }
GetChildrenRect() const1630 RectI RSRenderNode::GetChildrenRect() const
1631 {
1632     return childrenRect_;
1633 }
ChildHasFilter() const1634 bool RSRenderNode::ChildHasFilter() const
1635 {
1636     return childHasFilter_;
1637 }
SetChildHasFilter(bool childHasFilter)1638 void RSRenderNode::SetChildHasFilter(bool childHasFilter)
1639 {
1640     childHasFilter_ = childHasFilter;
1641 }
GetInstanceRootNodeId() const1642 NodeId RSRenderNode::GetInstanceRootNodeId() const
1643 {
1644     return instanceRootNodeId_;
1645 }
IsRenderUpdateIgnored() const1646 bool RSRenderNode::IsRenderUpdateIgnored() const
1647 {
1648     return isRenderUpdateIgnored_;
1649 }
GetAnimationManager()1650 RSAnimationManager& RSRenderNode::GetAnimationManager()
1651 {
1652     return animationManager_;
1653 }
GetOldDirty() const1654 RectI RSRenderNode::GetOldDirty() const
1655 {
1656     return oldDirty_;
1657 }
GetOldDirtyInSurface() const1658 RectI RSRenderNode::GetOldDirtyInSurface() const
1659 {
1660     return oldDirtyInSurface_;
1661 }
IsDirtyRegionUpdated() const1662 bool RSRenderNode::IsDirtyRegionUpdated() const
1663 {
1664     return isDirtyRegionUpdated_;
1665 }
IsShadowValidLastFrame() const1666 bool RSRenderNode::IsShadowValidLastFrame() const
1667 {
1668     return isShadowValidLastFrame_;
1669 }
SetStaticCached(bool isStaticCached)1670 void RSRenderNode::SetStaticCached(bool isStaticCached)
1671 {
1672     isStaticCached_ = isStaticCached;
1673 }
IsStaticCached() const1674 bool RSRenderNode::IsStaticCached() const
1675 {
1676     return isStaticCached_;
1677 }
UpdateCompletedCacheSurface()1678 void RSRenderNode::UpdateCompletedCacheSurface()
1679 {
1680     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1681     std::swap(cacheSurface_, cacheCompletedSurface_);
1682     std::swap(cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
1683 #ifndef USE_ROSEN_DRAWING
1684 #ifdef RS_ENABLE_GL
1685     std::swap(cacheBackendTexture_, cacheCompletedBackendTexture_);
1686     SetTextureValidFlag(true);
1687 #endif
1688 #endif
1689 }
SetTextureValidFlag(bool isValid)1690 void RSRenderNode::SetTextureValidFlag(bool isValid)
1691 {
1692 #ifndef USE_ROSEN_DRAWING
1693 #ifdef RS_ENABLE_GL
1694     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1695     isTextureValid_ = isValid;
1696 #endif
1697 #endif
1698 }
ClearCacheSurface()1699 void RSRenderNode::ClearCacheSurface()
1700 {
1701     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1702     cacheSurface_ = nullptr;
1703     cacheCompletedSurface_ = nullptr;
1704 }
SetCacheType(CacheType cacheType)1705 void RSRenderNode::SetCacheType(CacheType cacheType)
1706 {
1707     cacheType_ = cacheType;
1708 }
GetCacheType() const1709 CacheType RSRenderNode::GetCacheType() const
1710 {
1711     return cacheType_;
1712 }
GetShadowRectOffsetX() const1713 int RSRenderNode::GetShadowRectOffsetX() const
1714 {
1715     return shadowRectOffsetX_;
1716 }
GetShadowRectOffsetY() const1717 int RSRenderNode::GetShadowRectOffsetY() const
1718 {
1719     return shadowRectOffsetY_;
1720 }
SetDrawingCacheType(RSDrawingCacheType cacheType)1721 void RSRenderNode::SetDrawingCacheType(RSDrawingCacheType cacheType)
1722 {
1723     drawingCacheType_ = cacheType;
1724 }
GetDrawingCacheType() const1725 RSDrawingCacheType RSRenderNode::GetDrawingCacheType() const
1726 {
1727     return drawingCacheType_;
1728 }
SetDrawingCacheChanged(bool cacheChanged)1729 void RSRenderNode::SetDrawingCacheChanged(bool cacheChanged)
1730 {
1731     isDrawingCacheChanged_ = cacheChanged;
1732 }
GetDrawingCacheChanged() const1733 bool RSRenderNode::GetDrawingCacheChanged() const
1734 {
1735     return isDrawingCacheChanged_;
1736 }
SetIsMarkDriven(bool isMarkDriven)1737 void RSRenderNode::SetIsMarkDriven(bool isMarkDriven)
1738 {
1739     isMarkDriven_ = isMarkDriven;
1740 }
IsMarkDriven() const1741 bool RSRenderNode::IsMarkDriven() const
1742 {
1743     return isMarkDriven_;
1744 }
SetIsMarkDrivenRender(bool isMarkDrivenRender)1745 void RSRenderNode::SetIsMarkDrivenRender(bool isMarkDrivenRender)
1746 {
1747     isMarkDrivenRender_ = isMarkDrivenRender;
1748 }
IsMarkDrivenRender() const1749 bool RSRenderNode::IsMarkDrivenRender() const
1750 {
1751     return isMarkDrivenRender_;
1752 }
SetItemIndex(int index)1753 void RSRenderNode::SetItemIndex(int index)
1754 {
1755     itemIndex_ = index;
1756 }
GetItemIndex() const1757 int RSRenderNode::GetItemIndex() const
1758 {
1759     return itemIndex_;
1760 }
SetPaintState(bool paintState)1761 void RSRenderNode::SetPaintState(bool paintState)
1762 {
1763     paintState_ = paintState;
1764 }
GetPaintState() const1765 bool RSRenderNode::GetPaintState() const
1766 {
1767     return paintState_;
1768 }
SetIsContentChanged(bool isChanged)1769 void RSRenderNode::SetIsContentChanged(bool isChanged)
1770 {
1771     isContentChanged_ = isChanged;
1772 }
IsContentChanged() const1773 bool RSRenderNode::IsContentChanged() const
1774 {
1775     return isContentChanged_ || HasAnimation();
1776 }
HasAnimation() const1777 bool RSRenderNode::HasAnimation() const
1778 {
1779     return !animationManager_.animations_.empty();
1780 }
HasFilter() const1781 bool RSRenderNode::HasFilter() const
1782 {
1783     return hasFilter_;
1784 }
SetHasFilter(bool hasFilter)1785 void RSRenderNode::SetHasFilter(bool hasFilter)
1786 {
1787     hasFilter_ = hasFilter;
1788 }
GetSurfaceMutex() const1789 std::recursive_mutex& RSRenderNode::GetSurfaceMutex() const
1790 {
1791     return surfaceMutex_;
1792 }
HasHardwareNode() const1793 bool RSRenderNode::HasHardwareNode() const
1794 {
1795     return hasHardwareNode_;
1796 }
SetHasHardwareNode(bool hasHardwareNode)1797 void RSRenderNode::SetHasHardwareNode(bool hasHardwareNode)
1798 {
1799     hasHardwareNode_ = hasHardwareNode;
1800 }
HasAbilityComponent() const1801 bool RSRenderNode::HasAbilityComponent() const
1802 {
1803     return hasAbilityComponent_;
1804 }
SetHasAbilityComponent(bool hasAbilityComponent)1805 void RSRenderNode::SetHasAbilityComponent(bool hasAbilityComponent)
1806 {
1807     hasAbilityComponent_ = hasAbilityComponent;
1808 }
GetCacheSurfaceThreadIndex() const1809 uint32_t RSRenderNode::GetCacheSurfaceThreadIndex() const
1810 {
1811     return cacheSurfaceThreadIndex_;
1812 }
QuerySubAssignable(bool isRotation) const1813 bool RSRenderNode::QuerySubAssignable(bool isRotation) const
1814 {
1815     return !hasFilter_ && !hasAbilityComponent_ && !isRotation && !hasHardwareNode_;
1816 }
GetCompletedSurfaceThreadIndex() const1817 uint32_t RSRenderNode::GetCompletedSurfaceThreadIndex() const
1818 {
1819     return completedSurfaceThreadIndex_;
1820 }
1821 
IsMainThreadNode() const1822 bool RSRenderNode::IsMainThreadNode() const
1823 {
1824     return isMainThreadNode_;
1825 }
SetIsMainThreadNode(bool isMainThreadNode)1826 void RSRenderNode::SetIsMainThreadNode(bool isMainThreadNode)
1827 {
1828     isMainThreadNode_ = isMainThreadNode;
1829 }
IsScale() const1830 bool RSRenderNode::IsScale() const
1831 {
1832     return isScale_;
1833 }
SetIsScale(bool isScale)1834 void RSRenderNode::SetIsScale(bool isScale)
1835 {
1836     isScale_ = isScale;
1837 }
SetPriority(NodePriorityType priority)1838 void RSRenderNode::SetPriority(NodePriorityType priority)
1839 {
1840     priority_ = priority;
1841 }
GetPriority()1842 NodePriorityType RSRenderNode::GetPriority()
1843 {
1844     return priority_;
1845 }
IsAncestorDirty() const1846 bool RSRenderNode::IsAncestorDirty() const
1847 {
1848     return isAncestorDirty_;
1849 }
SetIsAncestorDirty(bool isAncestorDirty)1850 void RSRenderNode::SetIsAncestorDirty(bool isAncestorDirty)
1851 {
1852     isAncestorDirty_ = isAncestorDirty;
1853 }
HasCachedTexture() const1854 bool RSRenderNode::HasCachedTexture() const
1855 {
1856 #ifndef USE_ROSEN_DRAWING
1857 #ifdef RS_ENABLE_GL
1858     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1859     return isTextureValid_;
1860 #else
1861     return true;
1862 #endif
1863 #else
1864     return false;
1865 #endif
1866 }
SetDrawRegion(std::shared_ptr<RectF> rect)1867 void RSRenderNode::SetDrawRegion(std::shared_ptr<RectF> rect)
1868 {
1869     drawRegion_ = rect;
1870     renderProperties_.SetDrawRegion(rect);
1871 }
GetDrawRegion() const1872 std::shared_ptr<RectF> RSRenderNode::GetDrawRegion() const
1873 {
1874     return drawRegion_;
1875 }
GetNodeGroupType()1876 RSRenderNode::NodeGroupType RSRenderNode::GetNodeGroupType()
1877 {
1878     return nodeGroupType_;
1879 }
SetRSFrameRateRange(FrameRateRange range)1880 void RSRenderNode::SetRSFrameRateRange(FrameRateRange range)
1881 {
1882     rsRange_ = range;
1883 }
SetUIFrameRateRange(FrameRateRange range)1884 void RSRenderNode::SetUIFrameRateRange(FrameRateRange range)
1885 {
1886     uiRange_ = range;
1887 }
GetUIFrameRateRange() const1888 FrameRateRange RSRenderNode::GetUIFrameRateRange() const
1889 {
1890     return uiRange_;
1891 }
MarkNonGeometryChanged()1892 void RSRenderNode::MarkNonGeometryChanged()
1893 {
1894     geometryChangeNotPerceived_ = true;
1895 }
GetHgmModifierProfileList() const1896 std::vector<HgmModifierProfile> RSRenderNode::GetHgmModifierProfileList() const
1897 {
1898     return hgmModifierProfileList_;
1899 }
1900 } // namespace Rosen
1901 } // namespace OHOS
1902