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