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 "ui/rs_ui_director.h"
17
18 #include "rs_trace.h"
19 #include "sandbox_utils.h"
20
21 #include "animation/rs_animation_manager_map.h"
22 #include "animation/rs_ui_animation_manager.h"
23 #include "command/rs_animation_command.h"
24 #include "command/rs_message_processor.h"
25 #include "modifier/rs_modifier_manager.h"
26 #include "pipeline/rs_frame_report.h"
27 #include "pipeline/rs_node_map.h"
28 #include "pipeline/rs_render_thread.h"
29 #include "platform/common/rs_log.h"
30 #include "transaction/rs_application_agent_impl.h"
31 #include "transaction/rs_interfaces.h"
32 #include "transaction/rs_transaction_proxy.h"
33 #include "ui/rs_root_node.h"
34 #include "ui/rs_surface_extractor.h"
35 #include "ui/rs_surface_node.h"
36
37 #ifdef _WIN32
38 #include <windows.h>
39 #define gettid GetCurrentThreadId
40 #endif
41
42 #ifdef __APPLE__
43 #define gettid getpid
44 #endif
45
46 #ifdef __gnu_linux__
47 #include <sys/types.h>
48 #include <sys/syscall.h>
49 #define gettid []() -> int32_t { return static_cast<int32_t>(syscall(SYS_gettid)); }
50 #endif
51
52 namespace OHOS {
53 namespace Rosen {
54 static TaskRunner g_uiTaskRunner;
55
Create()56 std::shared_ptr<RSUIDirector> RSUIDirector::Create()
57 {
58 return std::shared_ptr<RSUIDirector>(new RSUIDirector());
59 }
60
~RSUIDirector()61 RSUIDirector::~RSUIDirector()
62 {
63 Destroy();
64 }
65
Init(bool shouldCreateRenderThread)66 void RSUIDirector::Init(bool shouldCreateRenderThread)
67 {
68 AnimationCommandHelper::SetFinishCallbackProcessor(AnimationCallbackProcessor);
69
70 if (shouldCreateRenderThread) {
71 auto renderThreadClient = RSIRenderClient::CreateRenderThreadClient();
72 auto transactionProxy = RSTransactionProxy::GetInstance();
73 if (transactionProxy != nullptr) {
74 transactionProxy->SetRenderThreadClient(renderThreadClient);
75 }
76
77 RsFrameReport::GetInstance().Init();
78 if (!cacheDir_.empty()) {
79 RSRenderThread::Instance().SetCacheDir(cacheDir_);
80 }
81 RSRenderThread::Instance().Start();
82 }
83 RSApplicationAgentImpl::Instance().RegisterRSApplicationAgent();
84
85 GoForeground();
86 }
87
GoForeground()88 void RSUIDirector::GoForeground()
89 {
90 ROSEN_LOGD("RSUIDirector::GoForeground");
91 if (!isActive_) {
92 RSRenderThread::Instance().UpdateWindowStatus(true);
93 isActive_ = true;
94 if (auto node = RSNodeMap::Instance().GetNode<RSRootNode>(root_)) {
95 node->SetEnableRender(true);
96 }
97 }
98 }
99
GoBackground()100 void RSUIDirector::GoBackground()
101 {
102 ROSEN_LOGD("RSUIDirector::GoBackground");
103 if (isActive_) {
104 RSRenderThread::Instance().UpdateWindowStatus(false);
105 isActive_ = false;
106 if (auto node = RSNodeMap::Instance().GetNode<RSRootNode>(root_)) {
107 node->SetEnableRender(false);
108 }
109 // clean bufferQueue cache
110 auto surfaceNode = surfaceNode_.lock();
111 RSRenderThread::Instance().PostTask([surfaceNode]() {
112 if (surfaceNode != nullptr) {
113 std::shared_ptr<RSSurface> rsSurface = RSSurfaceExtractor::ExtractRSSurface(surfaceNode);
114 rsSurface->ClearBuffer();
115 }
116 });
117 #ifdef ACE_ENABLE_GL
118 RSRenderThread::Instance().PostTask([this]() {
119 auto renderContext = RSRenderThread::Instance().GetRenderContext();
120 if (renderContext != nullptr) {
121 #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__gnu_linux__)
122 renderContext->ClearRedundantResources();
123 #endif
124 }
125 });
126 #endif
127 }
128 }
129
Destroy()130 void RSUIDirector::Destroy()
131 {
132 if (root_ != 0) {
133 if (auto node = RSNodeMap::Instance().GetNode<RSRootNode>(root_)) {
134 node->RemoveFromTree();
135 }
136 root_ = 0;
137 }
138 GoBackground();
139 }
140
SetRSSurfaceNode(std::shared_ptr<RSSurfaceNode> surfaceNode)141 void RSUIDirector::SetRSSurfaceNode(std::shared_ptr<RSSurfaceNode> surfaceNode)
142 {
143 surfaceNode_ = surfaceNode;
144 AttachSurface();
145 }
146
SetAbilityBGAlpha(uint8_t alpha)147 void RSUIDirector::SetAbilityBGAlpha(uint8_t alpha)
148 {
149 auto node = surfaceNode_.lock();
150 if (!node) {
151 ROSEN_LOGI("RSUIDirector::SetAbilityBGAlpha, surfaceNode_ is nullptr");
152 return;
153 }
154 node->SetAbilityBGAlpha(alpha);
155 }
156
SetRTRenderForced(bool isRenderForced)157 void RSUIDirector::SetRTRenderForced(bool isRenderForced)
158 {
159 RSRenderThread::Instance().SetRTRenderForced(isRenderForced);
160 }
161
SetContainerWindow(bool hasContainerWindow,float density)162 void RSUIDirector::SetContainerWindow(bool hasContainerWindow, float density)
163 {
164 auto node = surfaceNode_.lock();
165 if (!node) {
166 ROSEN_LOGI("RSUIDirector::SetContainerWindow, surfaceNode_ is nullptr");
167 return;
168 }
169 node->SetContainerWindow(hasContainerWindow, density);
170 }
171
SetRoot(NodeId root)172 void RSUIDirector::SetRoot(NodeId root)
173 {
174 if (root_ == root) {
175 ROSEN_LOGW("RSUIDirector::SetRoot, root_ is not change");
176 return;
177 }
178 root_ = root;
179 AttachSurface();
180 }
181
AttachSurface()182 void RSUIDirector::AttachSurface()
183 {
184 auto node = RSNodeMap::Instance().GetNode<RSRootNode>(root_);
185 auto surfaceNode = surfaceNode_.lock();
186 if (node != nullptr && surfaceNode != nullptr) {
187 node->AttachRSSurfaceNode(surfaceNode);
188 ROSEN_LOGD("RSUIDirector::AttachSurface [%" PRIu64 "]", surfaceNode->GetId());
189 } else {
190 ROSEN_LOGD("RSUIDirector::AttachSurface not ready");
191 }
192 }
193
SetAppFreeze(bool isAppFreeze)194 void RSUIDirector::SetAppFreeze(bool isAppFreeze)
195 {
196 auto surfaceNode = surfaceNode_.lock();
197 if (surfaceNode != nullptr) {
198 surfaceNode->SetAppFreeze(isAppFreeze);
199 }
200 }
201
SetTimeStamp(uint64_t timeStamp,const std::string & abilityName)202 void RSUIDirector::SetTimeStamp(uint64_t timeStamp, const std::string& abilityName)
203 {
204 timeStamp_ = timeStamp;
205 abilityName_ = abilityName;
206 }
207
SetCacheDir(const std::string & cacheFilePath)208 void RSUIDirector::SetCacheDir(const std::string& cacheFilePath)
209 {
210 cacheDir_ = cacheFilePath;
211 }
212
RunningCustomAnimation(uint64_t timeStamp)213 bool RSUIDirector::RunningCustomAnimation(uint64_t timeStamp)
214 {
215 bool hasRunningAnimation = false;
216 auto animationManager = RSAnimationManagerMap::Instance()->GetAnimationManager(gettid());
217 if (animationManager != nullptr) {
218 hasRunningAnimation = animationManager->Animate(timeStamp);
219 animationManager->Draw();
220 }
221 return hasRunningAnimation;
222 }
223
SetUITaskRunner(const TaskRunner & uiTaskRunner)224 void RSUIDirector::SetUITaskRunner(const TaskRunner& uiTaskRunner)
225 {
226 g_uiTaskRunner = uiTaskRunner;
227 }
228
SendMessages()229 void RSUIDirector::SendMessages()
230 {
231 ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "SendCommands");
232 auto transactionProxy = RSTransactionProxy::GetInstance();
233 if (transactionProxy != nullptr) {
234 transactionProxy->FlushImplicitTransaction(timeStamp_, abilityName_);
235 }
236 ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
237 }
238
RecvMessages(bool needProcess)239 void RSUIDirector::RecvMessages(bool needProcess)
240 {
241 if (GetRealPid() == -1) {
242 return;
243 }
244 static const uint32_t pid = static_cast<uint32_t>(GetRealPid());
245 if (!RSMessageProcessor::Instance().HasTransaction(pid)) {
246 return;
247 }
248 auto transactionDataPtr = std::make_shared<RSTransactionData>(RSMessageProcessor::Instance().GetTransaction(pid));
249 if (needProcess) {
250 RecvMessages(transactionDataPtr);
251 }
252 }
253
RecvMessages(std::shared_ptr<RSTransactionData> cmds)254 void RSUIDirector::RecvMessages(std::shared_ptr<RSTransactionData> cmds)
255 {
256 if (g_uiTaskRunner == nullptr) {
257 ROSEN_LOGE("RSUIDirector::RecvMessages, Notify ui message failed, uiTaskRunner is null");
258 return;
259 }
260 if (cmds == nullptr || cmds->IsEmpty()) {
261 return;
262 }
263
264 g_uiTaskRunner([cmds]() { RSUIDirector::ProcessMessages(cmds); });
265 }
266
ProcessMessages(std::shared_ptr<RSTransactionData> cmds)267 void RSUIDirector::ProcessMessages(std::shared_ptr<RSTransactionData> cmds)
268 {
269 static RSContext context; // RSCommand->process() needs it
270 cmds->Process(context);
271 }
272
AnimationCallbackProcessor(NodeId nodeId,AnimationId animId)273 void RSUIDirector::AnimationCallbackProcessor(NodeId nodeId, AnimationId animId)
274 {
275 // try find the node by nodeId
276 if (auto nodePtr = RSNodeMap::Instance().GetNode<RSNode>(nodeId)) {
277 if (!nodePtr->AnimationFinish(animId)) {
278 ROSEN_LOGE("RSUIDirector::AnimationCallbackProcessor, could not find animation %" PRIu64 " on node %" PRIu64
279 ".", animId, nodeId);
280 }
281 return;
282 }
283
284 // if node not found, try fallback node
285 auto& fallbackNode = RSNodeMap::Instance().GetAnimationFallbackNode();
286 if (fallbackNode && fallbackNode->AnimationFinish(animId)) {
287 ROSEN_LOGD("RSUIDirector::AnimationCallbackProcessor, found animation %" PRIu64 " on fallback node.", animId);
288 } else {
289 ROSEN_LOGE("RSUIDirector::AnimationCallbackProcessor, could not find animation %" PRIu64 " on fallback node.",
290 animId);
291 }
292 }
293 } // namespace Rosen
294 } // namespace OHOS
295