1 /*
2 * Copyright (c) 2021-2022 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 "ui/rs_root_node.h"
17
18 #include "command/rs_root_node_command.h"
19 #include "pipeline/rs_node_map.h"
20 #include "platform/common/rs_log.h"
21 #include "transaction/rs_interfaces.h"
22 #include "transaction/rs_transaction_proxy.h"
23 #include "ui/rs_surface_node.h"
24 #include "ui/rs_ui_context.h"
25 #include "ui/rs_ui_director.h"
26
27 namespace OHOS {
28 namespace Rosen {
29 namespace {
RegisterTypefaceCallback()30 bool RegisterTypefaceCallback()
31 {
32 static std::once_flag flag;
33 std::call_once(flag, []() {
34 std::function<bool (std::shared_ptr<Drawing::Typeface>)> registerTypefaceFunc =
35 [] (std::shared_ptr<Drawing::Typeface> typeface) -> bool {
36 static Rosen::RSInterfaces& rsInterface = Rosen::RSInterfaces::GetInstance();
37 return rsInterface.RegisterTypeface(typeface);
38 };
39 Drawing::Typeface::RegisterCallBackFunc(registerTypefaceFunc);
40
41 std::function<bool (std::shared_ptr<Drawing::Typeface>)> unregisterTypefaceFunc =
42 [] (std::shared_ptr<Drawing::Typeface> typeface) -> bool {
43 static Rosen::RSInterfaces& rsInterface = Rosen::RSInterfaces::GetInstance();
44 return rsInterface.UnRegisterTypeface(typeface);
45 };
46 Drawing::Typeface::UnRegisterCallBackFunc(unregisterTypefaceFunc);
47 });
48 return true;
49 }
50
51 class TypefaceAutoRegister {
52 public:
TypefaceAutoRegister()53 TypefaceAutoRegister()
54 {
55 RegisterTypefaceCallback();
56 }
57
~TypefaceAutoRegister()58 ~TypefaceAutoRegister()
59 {
60 Drawing::Typeface::RegisterCallBackFunc(nullptr);
61 Drawing::Typeface::UnRegisterCallBackFunc(nullptr);
62 }
63 };
64
65 #ifndef ARKUI_X_ENABLE
66 // Prohibiting resigter the callback function in advance when arkui-x use custom's font
67 TypefaceAutoRegister g_typefaceAutoRegister;
68 #endif
69 }
70
Create(bool isRenderServiceNode,bool isTextureExportNode,std::shared_ptr<RSUIContext> rsUIContext)71 std::shared_ptr<RSNode> RSRootNode::Create(
72 bool isRenderServiceNode, bool isTextureExportNode, std::shared_ptr<RSUIContext> rsUIContext)
73 {
74 RegisterTypefaceCallback();
75
76 std::shared_ptr<RSRootNode> node(new RSRootNode(isRenderServiceNode, isTextureExportNode, rsUIContext));
77 if (rsUIContext != nullptr) {
78 rsUIContext->GetMutableNodeMap().RegisterNode(node);
79 auto transaction = rsUIContext->GetRSTransaction();
80 if (transaction == nullptr) {
81 return node;
82 }
83 std::unique_ptr<RSCommand> command = std::make_unique<RSRootNodeCreate>(node->GetId(), isTextureExportNode);
84 transaction->AddCommand(command, node->IsRenderServiceNode());
85 } else {
86 RSNodeMap::MutableInstance().RegisterNode(node);
87 auto transactionProxy = RSTransactionProxy::GetInstance();
88 if (transactionProxy == nullptr) {
89 return node;
90 }
91 std::unique_ptr<RSCommand> command = std::make_unique<RSRootNodeCreate>(node->GetId(), isTextureExportNode);
92 transactionProxy->AddCommand(command, node->IsRenderServiceNode());
93 }
94 return node;
95 }
96
RegisterNodeMap()97 void RSRootNode::RegisterNodeMap()
98 {
99 auto rsContext = GetRSUIContext();
100 if (rsContext == nullptr) {
101 return;
102 }
103 auto& nodeMap = rsContext->GetMutableNodeMap();
104 nodeMap.RegisterNode(shared_from_this());
105 }
106
RSRootNode(bool isRenderServiceNode,bool isSamelayerRender,std::shared_ptr<RSUIContext> rsUIContext)107 RSRootNode::RSRootNode(bool isRenderServiceNode, bool isSamelayerRender, std::shared_ptr<RSUIContext> rsUIContext)
108 : RSCanvasNode(isRenderServiceNode, isSamelayerRender, rsUIContext) {}
109
AttachRSSurfaceNode(std::shared_ptr<RSSurfaceNode> surfaceNode) const110 void RSRootNode::AttachRSSurfaceNode(std::shared_ptr<RSSurfaceNode> surfaceNode) const
111 {
112 if (!IsUniRenderEnabled() || isTextureExportNode_) {
113 std::unique_ptr<RSCommand> command = std::make_unique<RSRootNodeAttachRSSurfaceNode>(GetId(),
114 surfaceNode->GetId(), surfaceNode->GetRSUIContext() ? surfaceNode->GetRSUIContext()->GetToken() : 0);
115 AddCommand(command, false);
116 } else {
117 std::unique_ptr<RSCommand> command =
118 std::make_unique<RSRootNodeAttachToUniSurfaceNode>(GetId(), surfaceNode->GetId());
119 AddCommand(command, true);
120 }
121 }
122
SetEnableRender(bool flag) const123 void RSRootNode::SetEnableRender(bool flag) const
124 {
125 std::unique_ptr<RSCommand> command = std::make_unique<RSRootNodeSetEnableRender>(GetId(), flag);
126 auto transaction = GetRSTransaction();
127 if (transaction != nullptr) {
128 transaction->AddCommand(command, IsRenderServiceNode());
129 if (!isTextureExportNode_) {
130 transaction->FlushImplicitTransaction();
131 }
132 } else {
133 auto transactionProxy = RSTransactionProxy::GetInstance();
134 if (transactionProxy != nullptr) {
135 transactionProxy->AddCommand(command, IsRenderServiceNode());
136 if (!isTextureExportNode_) {
137 transactionProxy->FlushImplicitTransaction();
138 }
139 }
140 }
141 }
142
OnBoundsSizeChanged() const143 void RSRootNode::OnBoundsSizeChanged() const
144 {
145 if (IsUniRenderEnabled() && !isTextureExportNode_) {
146 return;
147 }
148 // Planning: we should use frame size instead of bounds size to calculate the surface size.
149 auto bounds = GetStagingProperties().GetBounds();
150 // Set RootNode Surface Size with animation final value. NOTE: this logic is only used in RenderThreadVisitor
151 std::unique_ptr<RSCommand> command =
152 std::make_unique<RSRootNodeUpdateSuggestedBufferSize>(GetId(), bounds.z_, bounds.w_);
153 AddCommand(command, false);
154 }
155 } // namespace Rosen
156 } // namespace OHOS
157