• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <iostream>
17 
18 #include "dm/display_manager.h"
19 #include "event_handler.h"
20 #include "rs_trace.h"
21 #include "securec.h"
22 
23 #include "draw/canvas.h"
24 #include "image/bitmap.h"
25 #include "transaction/rs_interfaces.h"
26 #include "transaction/rs_transaction.h"
27 #include "ui/rs_canvas_node.h"
28 #include "ui/rs_root_node.h"
29 #include "ui/rs_surface_node.h"
30 #include "ui/rs_ui_context.h"
31 #include "ui/rs_ui_director.h"
32 
33 using namespace OHOS;
34 using namespace OHOS::Rosen;
35 uint64_t screenId = 0;
36 const Rosen::RSAnimationTimingCurve ANIMATION_TIMING_CURVE =
37     Rosen::RSAnimationTimingCurve::CreateCubicCurve(0.2f, 0.0f, 0.2f, 1.0f);
38 
39 namespace {
40 
Init(std::shared_ptr<RSUIDirector> rsUiDirector,int width,int height,std::vector<std::shared_ptr<RSCanvasNode>> & nodes,std::shared_ptr<RSNode> & rootNode)41 void Init(std::shared_ptr<RSUIDirector> rsUiDirector, int width, int height,
42     std::vector<std::shared_ptr<RSCanvasNode>>& nodes, std::shared_ptr<RSNode>& rootNode)
43 {
44     std::cout << "rs multi instance demo Init Rosen Backend!" << std::endl;
45     auto rsUIContext = rsUiDirector->GetRSUIContext();
46     rootNode = RSRootNode::Create(false, false, rsUIContext);
47     rootNode->SetBounds(0, 0, width, height);
48     rootNode->SetFrame(0, 0, width, height);
49     rootNode->SetBackgroundColor(Drawing::Color::COLOR_YELLOW);
50 
51     nodes.emplace_back(RSCanvasNode::Create(false, false, rsUIContext));
52     nodes[0]->SetBounds(0, 0, 100, 100);
53     nodes[0]->SetFrame(0, 0, 100, 100);
54     nodes[0]->SetBackgroundColor(Drawing::Color::COLOR_BLUE);
55 
56     rootNode->AddChild(nodes[0], -1);
57 
58     nodes.emplace_back(RSCanvasNode::Create(false, false, rsUIContext));
59     nodes[1]->SetBounds(0, 200, 100, 100);
60     nodes[1]->SetFrame(0, 200, 100, 100);
61     nodes[1]->SetBackgroundColor(Drawing::Color::COLOR_GREEN);
62 
63     rootNode->AddChild(nodes[0], -1);
64     rootNode->AddChild(nodes[1], -1);
65     rsUiDirector->SetRSRootNode(rootNode->ReinterpretCastTo<RSRootNode>());
66 }
67 
68 class SubThread {
69 public:
SubThread(uint32_t threadIndex)70     SubThread(uint32_t threadIndex) : threadIndex_(threadIndex) {}
71     ~SubThread() = default;
Start()72     void Start()
73     {
74         std::string name = "SubThread" + std::to_string(threadIndex_);
75         runner_ = AppExecFwk::EventRunner::Create(name);
76         handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
77     }
PostTask(const std::function<void ()> & task,const std::string & name=std::string ())78     void PostTask(const std::function<void()>& task, const std::string& name = std::string())
79     {
80         if (handler_) {
81             handler_->PostImmediateTask(task, name);
82         }
83     }
84 
85 private:
86     std::shared_ptr<AppExecFwk::EventRunner> runner_ = nullptr;
87     std::shared_ptr<AppExecFwk::EventHandler> handler_ = nullptr;
88     uint32_t threadIndex_ = 0;
89 };
90 
InitSurface()91 bool InitSurface()
92 {
93     SubThread subThread1 = SubThread(1);
94     SubThread subThread2 = SubThread(2);
95     subThread1.Start();
96     subThread2.Start();
97     std::shared_ptr<RSUIDirector> rsUiDirector;
98     std::shared_ptr<RSUIDirector> rsUiDirector2;
99     std::shared_ptr<RSNode> rootNode;
100     std::vector<std::shared_ptr<RSCanvasNode>> nodes;
101     std::shared_ptr<RSSurfaceNode> surfaceNode;
102     // stage 1
103     std::function<void()> task = [&rsUiDirector, &nodes, &rootNode, &surfaceNode]() {
104         std::cout << "Stage 1" << std::endl;
105         rsUiDirector = RSUIDirector::Create();
106         rsUiDirector->Init(true, true);
107         auto uiContext = rsUiDirector->GetRSUIContext();
108         if (uiContext) {
109             std::cout << "stage 1 RSUIDirector::Create success" << std::endl;
110             std::cout << "stage 1 get RSUIContext by RSUIDirector success" << std::endl;
111             std::cout << "stage 1 RSUIContext token is " << uiContext->GetToken() << std::endl;
112         } else {
113             std::cout << "RSUIContext::Create failed" << std::endl;
114         }
115         RSSurfaceNodeConfig surfaceNodeConfig;
116         surfaceNodeConfig.SurfaceNodeName = "AppMain_Window";
117         RSSurfaceNodeType surfaceNodeType = RSSurfaceNodeType::APP_WINDOW_NODE;
118         std::cout << "RSSurfaceNode::Create" << std::endl;
119         surfaceNode = RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType, true, false, uiContext);
120         std::cout << "Create node by RSUIContext success" << std::endl;
121         surfaceNode->SetFrameGravity(Gravity::RESIZE_ASPECT_FILL);
122         surfaceNode->SetPositionZ(RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
123         surfaceNode->SetBounds(0, 0, 600, 600);
124         surfaceNode->SetBackgroundColor(SK_ColorRED);
125         rsUiDirector->SetRSSurfaceNode(surfaceNode);
126         Init(rsUiDirector, 300, 300, nodes, rootNode);
127         surfaceNode->AttachToDisplay(screenId);
128         auto transaction = uiContext->GetRSTransaction();
129         if (!transaction) {
130             std::cout << "!transaction" << std::endl;
131             return;
132         }
133         transaction->FlushImplicitTransaction();
134         std::cout << "find node by nodeMap" << std::endl;
135         auto node11 = RSNodeMap::Instance().GetNode(rootNode->GetId());
136         std::string result = !!node11 ? "true" : "false";
137         std::cout << "find node by global nodeMap result is " << result << std::endl;
138         auto node32 = uiContext->GetNodeMap().GetNode(rootNode->GetId());
139         result = !!node32 ? "true" : "false";
140         std::cout << "find node by nodeMapnew result is " << result << std::endl;
141         // change property in nodes [setter using modifier]
142         sleep(2);
143         std::cout << "change Node properties " << std::endl;
144         nodes[0]->SetBounds(0, 0, 200, 200);
145         nodes[0]->SetFrame(0, 0, 200, 200);
146         nodes[0]->SetBorderColor(Drawing::Color::COLOR_BLACK);
147         nodes[0]->SetBorderWidth(10);
148         nodes[0]->SetBorderStyle((uint32_t)BorderStyle::SOLID);
149         std::cout << "send message by local transaction" << std::endl;
150         transaction->FlushImplicitTransaction();
151         sleep(3);
152         std::cout << "window1 animation start" << std::endl;
153         auto propertyCallback = [&]() {
154             std::cout << "window1 animation1 " << std::endl;
155             nodes[0]->SetBounds(100, 0, 100, 100);
156             nodes[0]->SetFrame(100, 0, 100, 100);
157             nodes[0]->SetBackgroundColor(Drawing::Color::COLOR_RED);
158         };
159         auto finishCallback = [&]() {};
160         RSAnimationTimingProtocol protocol;
161         protocol.SetDuration(1000);
162         RSNode::Animate(uiContext, protocol, ANIMATION_TIMING_CURVE, propertyCallback, finishCallback);
163         transaction->FlushImplicitTransaction();
164         sleep(6);
165         auto propertyCallback2 = [&]() {
166             std::cout << "window1 animation2" << std::endl;
167             nodes[0]->SetBounds(0, 0, 200, 200);
168             nodes[0]->SetFrame(0, 0, 200, 200);
169             nodes[0]->SetBackgroundColor(Drawing::Color::COLOR_BLACK);
170         };
171         auto finishCallback2 = [&]() {};
172         RSNode::Animate(uiContext, protocol, ANIMATION_TIMING_CURVE, propertyCallback2, finishCallback2);
173         transaction->FlushImplicitTransaction();
174         sleep(2);
175         std::cout << "window1 hide" << std::endl;
176         surfaceNode->SetVisible(false);
177         transaction->FlushImplicitTransaction();
178     };
179     subThread1.PostTask(task, "stage 1");
180     sleep(8);
181     // stage 2
182     std::shared_ptr<RSNode> rootNode2;
183     std::vector<std::shared_ptr<RSCanvasNode>> nodes2;
184     std::shared_ptr<RSSurfaceNode> surfaceNode2;
185     std::function<void()> task2 = [&rsUiDirector2, &nodes2, &rootNode2, &surfaceNode2, &nodes, &rootNode,
186                                       &rsUiDirector]() {
187         std::cout << " " << std::endl;
188         std::cout << "Stage 2" << std::endl;
189         rsUiDirector2 = RSUIDirector::Create();
190         rsUiDirector2->Init(true, true);
191         auto uiContext = rsUiDirector2->GetRSUIContext();
192         if (uiContext) {
193             std::cout << "stage 2 RSUIDirector::Create success" << std::endl;
194             std::cout << "stage 2 get RSUIContext by RSUIDirector success" << std::endl;
195             std::cout << "stage 2 RSUIContext token is " << uiContext->GetToken() << std::endl;
196             std::cout << "stage 2 token is not same as stage 1" << std::endl;
197         } else {
198             std::cout << "RSUIContext::Create failed" << std::endl;
199         }
200         // stage 2 find node
201         std::cout << "find node in thread B" << std::endl;
202         auto node32 = uiContext->GetNodeMap().GetNode(rootNode->GetId());
203         std::string result = !!node32 ? "true" : "false";
204         // change property by thread2
205         nodes[0]->SetBounds(0, 0, 400, 200);
206         nodes[0]->SetFrame(0, 0, 400, 200);
207         nodes[0]->SetBorderColor(Drawing::Color::COLOR_RED);
208         nodes[0]->SetBorderWidth(10);
209         nodes[0]->SetBorderStyle((uint32_t)BorderStyle::SOLID);
210         std::cout << "modifier property in thread 2 failed" << std::endl;
211         auto transaction = uiContext->GetRSTransaction();
212         transaction->FlushImplicitTransaction();
213         RSSurfaceNodeConfig surfaceNodeConfig;
214         surfaceNodeConfig.SurfaceNodeName = "AppMain_Window2";
215         RSSurfaceNodeType surfaceNodeType = RSSurfaceNodeType::APP_WINDOW_NODE;
216         std::cout << "stage 2 RSSurfaceNode::Create" << std::endl;
217         surfaceNode2 = RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType, true, false, uiContext);
218         surfaceNode2->SetFrameGravity(Gravity::RESIZE_ASPECT_FILL);
219         surfaceNode2->SetPositionZ(RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
220         surfaceNode2->SetBounds(700, 700, 600, 600);
221         surfaceNode2->SetBackgroundColor(SK_ColorRED);
222         rsUiDirector2->SetRSSurfaceNode(surfaceNode2);
223         Init(rsUiDirector2, 400, 400, nodes2, rootNode2);
224         surfaceNode2->AttachToDisplay(screenId);
225         auto uiContext2 = rsUiDirector->GetRSUIContext();
226         uiContext2->GetRSTransaction()->FlushImplicitTransaction();
227         sleep(1);
228         std::cout << "send Message By window1 flush failed" << std::endl;
229         transaction->FlushImplicitTransaction();
230         sleep(2);
231         std::cout << "window2 animation start" << std::endl;
232         auto propertyCallback = [&]() {
233             std::cout << "window2 animation " << std::endl;
234             nodes2[0]->SetBounds(100, 0, 100, 100);
235             nodes2[0]->SetFrame(100, 0, 100, 100);
236             nodes2[0]->SetBackgroundColor(Drawing::Color::COLOR_BLACK);
237         };
238         auto finishCallback = [&]() {};
239         RSAnimationTimingProtocol protocol;
240         protocol.SetDuration(1000);
241         RSNode::Animate(uiContext, protocol, ANIMATION_TIMING_CURVE, propertyCallback, finishCallback);
242         transaction->FlushImplicitTransaction();
243         sleep(3);
244         auto propertyCallback2 = [&]() {
245             std::cout << "window2 animation2" << std::endl;
246             nodes2[0]->SetBounds(0, 0, 200, 200);
247             nodes2[0]->SetFrame(0, 0, 200, 200);
248             nodes2[0]->SetBackgroundColor(Drawing::Color::COLOR_RED);
249         };
250         auto finishCallback2 = [&]() {};
251         RSNode::Animate(uiContext2, protocol, ANIMATION_TIMING_CURVE, propertyCallback2, finishCallback2);
252         transaction->FlushImplicitTransaction();
253         std::cout << "window2 animation2 failed because uiContext1 can not effect window2" << std::endl;
254         sleep(3);
255         std::cout << "window2 hide" << std::endl;
256         surfaceNode2->SetVisible(false);
257         transaction->FlushImplicitTransaction();
258     };
259     subThread2.PostTask(task2, "stage 2");
260     sleep(10);
261 
262     // stage 3
263     std::shared_ptr<RSNode> rootNode3;
264     std::vector<std::shared_ptr<RSCanvasNode>> nodes3;
265     std::shared_ptr<RSSurfaceNode> surfaceNode3;
266     std::shared_ptr<RSNode> rootNode4;
267     std::vector<std::shared_ptr<RSCanvasNode>> nodes4;
268     std::shared_ptr<RSSurfaceNode> surfaceNode4;
269     std::shared_ptr<RSUIDirector> rsUiDirector3;
270     std::shared_ptr<RSUIDirector> rsUiDirector4;
271     std::function<void()> task3 = [&rsUiDirector3, &rootNode3, &rootNode4, &surfaceNode3, &surfaceNode4, &nodes3,
272                                       &rsUiDirector4, &nodes4] {
273         std::cout << " " << std::endl;
274         std::cout << "stage 3 " << std::endl;
275         rsUiDirector3 = RSUIDirector::Create();
276         rsUiDirector3->Init(true, true);
277         auto uiContext3 = rsUiDirector3->GetRSUIContext();
278         if (uiContext3) {
279             std::cout << "stage 3 RSUIDirector 1 success" << std::endl;
280             std::cout << "stage 3 RSUIContext token is " << uiContext3->GetToken() << std::endl;
281         } else {
282             std::cout << "RSUIContext::Create failed" << std::endl;
283         }
284         rsUiDirector4 = RSUIDirector::Create();
285         rsUiDirector4->Init(true, true);
286         auto uiContext4 = rsUiDirector4->GetRSUIContext();
287         if (uiContext4) {
288             std::cout << "stage 3 RSUIDirector 2 success" << std::endl;
289             std::cout << "stage 3 RSUIContext 2 token is " << uiContext4->GetToken() << std::endl;
290             std::cout << "stage 3 RsUIContext 2 token is not same as RSUIContext token" << std::endl;
291         } else {
292             std::cout << "RSUIContext::Create failed" << std::endl;
293         }
294         RSSurfaceNodeConfig surfaceNodeConfig;
295         surfaceNodeConfig.SurfaceNodeName = "AppMain_Window3";
296         RSSurfaceNodeType surfaceNodeType = RSSurfaceNodeType::APP_WINDOW_NODE;
297         std::cout << "stage 3 RSSurfaceNode::Create" << std::endl;
298         surfaceNode3 = RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType, true, false, uiContext3);
299         surfaceNode3->SetFrameGravity(Gravity::RESIZE_ASPECT_FILL);
300         surfaceNode3->SetPositionZ(RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
301         surfaceNode3->SetBounds(0, 1200, 600, 600);
302         surfaceNode3->SetBackgroundColor(SK_ColorRED);
303         rsUiDirector3->SetRSSurfaceNode(surfaceNode3);
304         Init(rsUiDirector3, 400, 400, nodes3, rootNode3);
305         surfaceNode3->AttachToDisplay(screenId);
306         RSSurfaceNodeConfig surfaceNodeConfig2;
307         surfaceNodeConfig2.SurfaceNodeName = "AppMain_Window4";
308         RSSurfaceNodeType surfaceNodeType2 = RSSurfaceNodeType::APP_WINDOW_NODE;
309         surfaceNode4 = RSSurfaceNode::Create(surfaceNodeConfig2, surfaceNodeType2, true, false, uiContext4);
310         surfaceNode4->SetFrameGravity(Gravity::RESIZE_ASPECT_FILL);
311         surfaceNode4->SetPositionZ(RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
312         surfaceNode4->SetBounds(900, 1200, 500, 500);
313         surfaceNode4->SetBackgroundColor(SK_ColorRED);
314         rsUiDirector4->SetRSSurfaceNode(surfaceNode4);
315         Init(rsUiDirector4, 300, 300, nodes4, rootNode4);
316         surfaceNode4->AttachToDisplay(screenId);
317         auto transaction3 = uiContext3->GetRSTransaction();
318         transaction3->FlushImplicitTransaction();
319         std::cout << "window 4 message flush failed because uicontext3 can not flush window4" << std::endl;
320         sleep(2);
321         auto transaction4 = uiContext4->GetRSTransaction();
322         transaction4->FlushImplicitTransaction();
323         std::cout << "window 4 message flush success" << std::endl;
324         sleep(2);
325         auto propertyCallback = [&]() {
326             std::cout << "window3 animation" << std::endl;
327             nodes3[0]->SetBounds(100, 0, 100, 100);
328             nodes3[0]->SetFrame(100, 0, 100, 100);
329             nodes3[0]->SetBackgroundColor(Drawing::Color::COLOR_BLACK);
330         };
331         auto finishCallback = [&]() {};
332         RSAnimationTimingProtocol protocol;
333         protocol.SetDuration(1000);
334         RSNode::Animate(uiContext3, protocol, ANIMATION_TIMING_CURVE, propertyCallback, finishCallback);
335         auto propertyCallback2 = [&]() {
336             std::cout << "window4 animation" << std::endl;
337             nodes4[0]->SetBounds(100, 0, 100, 100);
338             nodes4[0]->SetFrame(100, 0, 100, 100);
339             nodes4[0]->SetBackgroundColor(Drawing::Color::COLOR_BLACK);
340         };
341         auto finishCallback4 = [&]() {};
342         RSNode::Animate(uiContext3, protocol, ANIMATION_TIMING_CURVE, propertyCallback2, finishCallback4);
343         transaction3->FlushImplicitTransaction();
344         transaction4->FlushImplicitTransaction();
345         std::cout << "window 4 can not do animation" << std::endl;
346         sleep(2);
347         nodes3[1]->AddChild(nodes4[1], -1);
348         std::cout << "window 3 window 4 can't add tree" << std::endl;
349         sleep(2);
350         std::cout << "window3 hide" << std::endl;
351         surfaceNode3->SetVisible(false);
352         transaction3->FlushImplicitTransaction();
353         sleep(1);
354         std::cout << "window4 hide" << std::endl;
355         surfaceNode4->SetVisible(false);
356         transaction4->FlushImplicitTransaction();
357     };
358     subThread1.PostTask(task3, "stage 3");
359     sleep(10);
360     return true;
361 }
362 } // namespace
363 
main()364 int main()
365 {
366     std::cout << "rs multi instance demo start!" << std::endl;
367     InitSurface();
368     std::cout << "rs multi instance demo end!" << std::endl;
369     return 0;
370 }