• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "core/components_ng/render/adapter/form_render_window.h"
17 
18 #include <memory>
19 
20 #include "base/log/log.h"
21 #include "core/common/container.h"
22 #include "core/common/container_scope.h"
23 #include "core/common/thread_checker.h"
24 #include "core/components_ng/base/frame_node.h"
25 
26 #ifdef ENABLE_ROSEN_BACKEND
27 #include "core/components_ng/render/adapter/rosen_render_context.h"
28 #include "transaction/rs_interfaces.h"
29 #endif
30 
31 namespace {
32 #ifdef ENABLE_ROSEN_BACKEND
33 constexpr float ONE_SECOND_IN_NANO = 1000000000.0f;
34 
GetDisplayRefreshRate()35 float GetDisplayRefreshRate()
36 {
37     return 60.0f;
38 }
39 #endif
40 } // namespace
41 
42 namespace OHOS::Ace {
43 
44 #ifdef ENABLE_ROSEN_BACKEND
45 std::mutex FormRenderWindow::globalMutex_;
46 #endif
47 
FormRenderWindow(RefPtr<TaskExecutor> taskExecutor,int32_t id)48 FormRenderWindow::FormRenderWindow(RefPtr<TaskExecutor> taskExecutor, int32_t id)
49     : taskExecutor_(taskExecutor), id_(id)
50 {
51 #ifdef ENABLE_ROSEN_BACKEND
52     ContainerScope scope(id);
53     auto container = Container::Current();
54     if (receiver_ == nullptr) {
55         auto& rsClient = Rosen::RSInterfaces::GetInstance();
56         receiver_ = rsClient.CreateVSyncReceiver("Form");
57         if (receiver_ == nullptr) {
58             LOGE("Form Create VSync receiver failed.");
59             return;
60         }
61         receiver_->Init();
62     }
63 
64     int64_t refreshPeriod = static_cast<int64_t>(ONE_SECOND_IN_NANO / GetDisplayRefreshRate());
65     onVsyncCallback_ = [weakTask = taskExecutor_, id = id_, refreshPeriod](int64_t timeStampNanos, void* data) {
66         auto taskExecutor = weakTask.Upgrade();
67         auto onVsync = [id, timeStampNanos, refreshPeriod] {
68             ContainerScope scope(id);
69             // use container to get window can make sure the window is valid
70             auto container = Container::Current();
71             CHECK_NULL_VOID(container);
72             auto window = container->GetWindow();
73             CHECK_NULL_VOID(window);
74             window->OnVsync(static_cast<uint64_t>(timeStampNanos), 0);
75             auto pipeline = container->GetPipelineContext();
76             if (pipeline) {
77                 pipeline->OnIdle(timeStampNanos + refreshPeriod);
78             }
79         };
80 
81         auto uiTaskRunner = SingleTaskExecutor::Make(taskExecutor, TaskExecutor::TaskType::JS);
82         if (uiTaskRunner.IsRunOnCurrentThread()) {
83             onVsync();
84             return;
85         }
86 
87         uiTaskRunner.PostTask([callback = std::move(onVsync)]() {
88             callback();
89         });
90     };
91 
92     frameCallback_.userData_ = nullptr;
93     frameCallback_.callback_ = onVsyncCallback_;
94 
95     receiver_->RequestNextVSync(frameCallback_);
96 
97     rsUIDirector_ = OHOS::Rosen::RSUIDirector::Create();
98     {
99         std::lock_guard<std::mutex> lock(globalMutex_);
100         rsUIDirector_->Init(); // Func Init Thread unsafe.
101     }
102 
103     std::string surfaceNodeName = "ArkTSCardNode";
104     struct Rosen::RSSurfaceNodeConfig surfaceNodeConfig = {.SurfaceNodeName = surfaceNodeName};
105     rsSurfaceNode_ = OHOS::Rosen::RSSurfaceNode::Create(surfaceNodeConfig, true);
106     rsUIDirector_->SetRSSurfaceNode(rsSurfaceNode_);
107 
108     rsUIDirector_->SetUITaskRunner([weakTaskExecutor = taskExecutor_, id = id_](const std::function<void()>& task) {
109         ContainerScope scope(id);
110         auto taskExecutor = weakTaskExecutor.Upgrade();
111         CHECK_NULL_VOID_NOLOG(taskExecutor);
112         taskExecutor->PostTask(task, TaskExecutor::TaskType::UI);
113     });
114 #else
115     taskExecutor_ = nullptr;
116     id_ = 0;
117 #endif
118 }
119 
RequestFrame()120 void FormRenderWindow::RequestFrame()
121 {
122 #ifdef ENABLE_ROSEN_BACKEND
123     receiver_->RequestNextVSync(frameCallback_);
124 #endif
125 }
126 
Destroy()127 void FormRenderWindow::Destroy()
128 {
129     LOG_DESTROY();
130 #ifdef ENABLE_ROSEN_BACKEND
131     frameCallback_.userData_ = nullptr;
132     frameCallback_.callback_ = nullptr;
133     rsUIDirector_->Destroy();
134     rsUIDirector_.reset();
135     callbacks_.clear();
136 #endif
137 }
138 
SetRootFrameNode(const RefPtr<NG::FrameNode> & root)139 void FormRenderWindow::SetRootFrameNode(const RefPtr<NG::FrameNode>& root)
140 {
141     CHECK_NULL_VOID(root);
142 #ifdef ENABLE_ROSEN_BACKEND
143     auto rosenRenderContext = AceType::DynamicCast<NG::RosenRenderContext>(root->GetRenderContext());
144     CHECK_NULL_VOID(rosenRenderContext);
145     if (rosenRenderContext->GetRSNode()) {
146         auto rootSRNode = rosenRenderContext->GetRSNode();
147         const auto& calcLayoutConstraint = root->GetLayoutProperty()->GetCalcLayoutConstraint();
148         auto width = static_cast<float>(calcLayoutConstraint->maxSize->Width()->GetDimension().Value());
149         auto height = static_cast<float>(calcLayoutConstraint->maxSize->Height()->GetDimension().Value());
150         rootSRNode->SetBounds(0, 0, width, height);
151         rsUIDirector_->SetRoot(rosenRenderContext->GetRSNode()->GetId());
152     }
153     rsUIDirector_->SendMessages();
154 #endif
155 }
156 
OnShow()157 void FormRenderWindow::OnShow()
158 {
159 #ifdef ENABLE_ROSEN_BACKEND
160     Window::OnShow();
161     rsUIDirector_->GoForeground();
162 #endif
163 }
164 
OnHide()165 void FormRenderWindow::OnHide()
166 {
167 #ifdef ENABLE_ROSEN_BACKEND
168     Window::OnHide();
169     rsUIDirector_->GoBackground();
170     rsUIDirector_->SendMessages();
171 #endif
172 }
173 
FlushTasks()174 void FormRenderWindow::FlushTasks()
175 {
176 #ifdef ENABLE_ROSEN_BACKEND
177     rsUIDirector_->SendMessages();
178 #endif
179 }
180 } // namespace OHOS::Ace
181