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