• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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