1 /*
2 * Copyright (c) 2025 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 "rs_window_keyframe_node_info.h"
17 #include "pipeline/main_thread/rs_main_thread.h"
18 #include "pipeline/rs_canvas_render_node.h"
19 #include "pipeline/rs_root_render_node.h"
20 #include "platform/common/rs_log.h"
21
22 namespace OHOS::Rosen {
23
UpdateLinkedNodeId(NodeId srcNodeId,NodeId linkedNodeId)24 void RSWindowKeyframeNodeInfo::UpdateLinkedNodeId(NodeId srcNodeId, NodeId linkedNodeId)
25 {
26 if (srcNodeId == INVALID_NODEID || linkedNodeId == INVALID_NODEID) {
27 return;
28 }
29
30 linkedNodeMap_[linkedNodeId] = srcNodeId;
31 }
32
GetLinkedNodeCount() const33 size_t RSWindowKeyframeNodeInfo::GetLinkedNodeCount() const
34 {
35 return linkedNodeMap_.size();
36 }
37
ClearLinkedNodeInfo()38 void RSWindowKeyframeNodeInfo::ClearLinkedNodeInfo()
39 {
40 linkedNodeMap_.clear();
41 }
42
PrepareRootNodeOffscreen(RSSurfaceRenderNode & surfaceNode)43 bool RSWindowKeyframeNodeInfo::PrepareRootNodeOffscreen(RSSurfaceRenderNode& surfaceNode)
44 {
45 if (LIKELY(linkedNodeMap_.empty())) {
46 return false;
47 }
48
49 for (const auto& [linkedRootNodeId, sourceNodeId] : linkedNodeMap_) {
50 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
51 auto rootNode = nodeMap.GetRenderNode<RSRootRenderNode>(linkedRootNodeId);
52 auto canvasNode = nodeMap.GetRenderNode<RSCanvasRenderNode>(sourceNodeId);
53 if (rootNode == nullptr || canvasNode == nullptr) {
54 RS_LOGE("RSWindowKeyframeNodeInfo::PrepareRootNodeOffscreen rootNode or canvasNode is nullptr");
55 continue;
56 }
57 auto parentNode = rootNode->GetParent().lock();
58 if (parentNode == nullptr || parentNode->GetId() != surfaceNode.GetId()) {
59 continue;
60 }
61 auto rootNodeDrawable = rootNode->GetRenderDrawable();
62 auto& rootNodeStagingRenderParams = rootNode->GetStagingRenderParams();
63 auto& canvasNodeStagingRenderParams = canvasNode->GetStagingRenderParams();
64 if (rootNodeDrawable == nullptr || rootNodeStagingRenderParams == nullptr ||
65 canvasNodeStagingRenderParams == nullptr) {
66 RS_LOGE("RSWindowKeyframeNodeInfo::PrepareRootNodeOffscreen stageRenderParams or drawable is nullptr");
67 continue;
68 }
69
70 surfaceNode.SetHwcChildrenDisabledState();
71 rootNode->EnableWindowKeyFrame(true);
72
73 canvasNodeStagingRenderParams->SetLinkedRootNodeDrawable(rootNodeDrawable);
74 canvasNodeStagingRenderParams->SetShouldPaint(true);
75 canvasNodeStagingRenderParams->SetContentEmpty(false);
76 canvasNode->AddToPendingSyncList();
77
78 rootNodeStagingRenderParams->SetNeedSwapBuffer(!canvasNode->IsStaticCached());
79 rootNodeStagingRenderParams->SetCacheNodeFrameRect({0, 0, canvasNode->GetRenderProperties().GetFrameWidth(),
80 canvasNode->GetRenderProperties().GetFrameHeight()});
81 }
82
83 return true;
84 }
85
86 } // namespace OHOS::Rosen
87