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 <event_handler.h>
17 #include <iostream>
18 #include <surface.h>
19
20 #include "wm/window.h"
21
22 #include "accesstoken_kit.h"
23 #ifdef SUPPORT_ACCESS_TOKEN
24 #include "nativetoken_kit.h"
25 #include "token_setproc.h"
26 #endif
27 #include "render/rs_border.h"
28 #include "transaction/rs_transaction.h"
29 #include "ui/rs_display_node.h"
30 #include "ui/rs_root_node.h"
31 #include "ui/rs_surface_extractor.h"
32 #include "ui/rs_surface_node.h"
33 #include "ui/rs_ui_director.h"
34
35 using namespace OHOS;
36 using namespace OHOS::Rosen;
37 using namespace std;
38
39 std::shared_ptr<RSNode> rootNode;
40 std::vector<std::shared_ptr<RSCanvasNode>> nodes;
41
Init(std::shared_ptr<RSUIDirector> rsUiDirector,int width,int height)42 void Init(std::shared_ptr<RSUIDirector> rsUiDirector, int width, int height)
43 {
44 std::cout << "rs app demo Init Rosen Backend!" << std::endl;
45
46 rootNode = RSRootNode::Create();
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());
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());
59 nodes[1]->SetBounds(0, 200, 200, 200);
60 nodes[1]->SetFrame(0, 200, 200, 200);
61 nodes[1]->SetBackgroundColor(Drawing::Color::COLOR_BLUE);
62
63 rootNode->AddChild(nodes[0], -1);
64 rootNode->AddChild(nodes[1], -1);
65 rsUiDirector->SetRSRootNode(rootNode->ReinterpretCastTo<RSRootNode>());
66 }
67
68 class MyData : public RSAnimatableArithmetic<MyData> {
69 public:
MyData()70 MyData() : data(0.f) {}
MyData(const float num)71 explicit MyData(const float num) : data(num) {}
72 virtual ~MyData() = default;
73
Add(const MyData & value) const74 MyData Add(const MyData& value) const override
75 {
76 float res = data + value.data;
77 return MyData(res);
78 }
Minus(const MyData & value) const79 MyData Minus(const MyData& value) const override
80 {
81 float res = data - value.data;
82 return MyData(res);
83 }
Multiply(const float scale) const84 MyData Multiply(const float scale) const override
85 {
86 float res = data * scale;
87 return MyData(res);
88 }
IsEqual(const MyData & value) const89 bool IsEqual(const MyData& value) const override
90 {
91 return data == value.data;
92 }
93
94 float data;
95 };
96
97 class MyModifier : public RSOverlayStyleModifier {
98 public:
99 MyModifier() = default;
100 ~MyModifier() = default;
Draw(RSDrawingContext & context) const101 void Draw(RSDrawingContext& context) const override
102 {
103 Drawing::Bitmap bitmap;
104 bitmap.Build(100, 100, Drawing::BitmapFormat {
105 Drawing::ColorType::COLORTYPE_N32, Drawing::AlphaType::ALPHATYPE_PREMUL});
106 Drawing::Surface surface;
107 surface.Bind(bitmap);
108 auto tempCanvas = surface.GetCanvas();
109 tempCanvas->Clear(0xffff3f7f);
110
111 Drawing::Brush tempBrush;
112 tempBrush.SetColor(Drawing::Color(0xff3fff7f));
113 tempCanvas->AttachBrush(tempBrush);
114 tempCanvas->DrawRect(Drawing::Rect(0, 0, 50, 50));
115
116 tempBrush.SetColor(Drawing::Color(0xffff3f7f));
117 tempCanvas->AttachBrush(tempBrush);
118 tempCanvas->DrawRect(Drawing::Rect(50, 50, 100, 100));
119 tempCanvas->DetachBrush();
120
121 auto image = surface.GetImageSnapshot();
122 if (image == nullptr) {
123 return;
124 }
125 Drawing::SamplingOptions sampling;
126 Drawing::Matrix matrix;
127 Drawing::Brush brush;
128 brush.SetShaderEffect(Drawing::ShaderEffect::CreateImageShader(
129 *image, Drawing::TileMode::REPEAT, Drawing::TileMode::REPEAT, sampling, matrix));
130 auto animatableProperty = std::static_pointer_cast<RSAnimatableProperty<MyData>>(property_);
131 brush.SetAlphaF(animatableProperty->Get().data);
132
133 std::cout << "MyModifier Draw property get " << animatableProperty->Get().data << std::endl;
134 context.canvas->AttachBrush(brush);
135 context.canvas->DrawRect(Drawing::Rect(0, 0, context.width, context.height));
136 context.canvas->DetachBrush();
137 }
138 };
139
140 class TransModifier : public RSGeometryTransModifier {
141 public:
142 TransModifier() = default;
143 ~TransModifier() = default;
144
GeometryEffect(float width,float height) const145 Drawing::Matrix GeometryEffect(float width, float height) const override
146 {
147 Drawing::Matrix matrix;
148 if (distance_) {
149 matrix.PreTranslate(distance_->Get(), distance_->Get());
150 std::cout << "TransModifier GeometryEffect, distance:"<< distance_->Get() << std::endl;
151 }
152
153 return matrix;
154 }
155
SetTrans(float distance)156 void SetTrans(float distance)
157 {
158 if (distance_ == nullptr) {
159 distance_ = std::make_shared<RSAnimatableProperty<float>>(distance);
160 AttachProperty(distance_);
161 } else {
162 distance_->Set(distance);
163 }
164 }
165 private:
166 std::shared_ptr<RSAnimatableProperty<float>> distance_;
167 };
168
169 class CustomModifier : public RSContentStyleModifier {
170 public:
171 CustomModifier() = default;
172 ~CustomModifier() = default;
173
Draw(RSDrawingContext & context) const174 void Draw(RSDrawingContext& context) const override
175 {
176 if (!alpha_ || !width_ || !height_ || !backgroundColor_) {
177 Drawing::Rect rect;
178 Drawing::Brush brush;
179 context.canvas->AttachBrush(brush);
180 context.canvas->DrawRect(rect);
181 context.canvas->DetachBrush();
182 return;
183 }
184 Drawing::Rect rect(0, 0, width_->Get(), height_->Get());
185 Drawing::Brush brush;
186 brush.SetColor(backgroundColor_->Get().AsArgbInt());
187 brush.SetAlphaF(alpha_->Get());
188 context.canvas->AttachBrush(brush);
189 context.canvas->DrawRect(rect);
190 context.canvas->DetachBrush();
191
192 std::cout << "Draw Get alpha_ " << alpha_->Get() << std::endl;
193 std::cout << "Draw Get width_ " << width_->Get() << std::endl;
194 std::cout << "Draw Get height_ " << height_->Get() << std::endl;
195 std::cout << "Draw Get backgroundColor_ " << std::hex << backgroundColor_->Get().AsArgbInt() << std::endl;
196 }
197
SetAlpha(float alpha)198 void SetAlpha(float alpha)
199 {
200 if (alpha_ == nullptr) {
201 alpha_ = std::make_shared<RSAnimatableProperty<float>>(alpha);
202 AttachProperty(alpha_);
203 } else {
204 alpha_->Set(alpha);
205 }
206 }
207
SetWidth(float width)208 void SetWidth(float width)
209 {
210 if (width_ == nullptr) {
211 width_ = std::make_shared<RSAnimatableProperty<float>>(width);
212 AttachProperty(width_);
213 } else {
214 width_->Set(width);
215 }
216 }
217
SetHeight(float height)218 void SetHeight(float height)
219 {
220 if (height_ == nullptr) {
221 height_ = std::make_shared<RSAnimatableProperty<float>>(height);
222 AttachProperty(height_);
223 } else {
224 height_->Set(height);
225 }
226 }
227
SetBackgroundColor(Color color)228 void SetBackgroundColor(Color color)
229 {
230 if (backgroundColor_ == nullptr) {
231 backgroundColor_ = std::make_shared<RSAnimatableProperty<Color>>(color);
232 AttachProperty(backgroundColor_);
233 } else {
234 backgroundColor_->Set(color);
235 }
236 }
237
238 private:
239 std::shared_ptr<RSAnimatableProperty<float>> alpha_;
240 std::shared_ptr<RSAnimatableProperty<float>> width_;
241 std::shared_ptr<RSAnimatableProperty<float>> height_;
242 std::shared_ptr<RSAnimatableProperty<Color>> backgroundColor_;
243 };
244
245 class NodeModifier : public RSNodeModifier {
246 public:
247 NodeModifier() = default;
248 virtual ~NodeModifier() = default;
249
Modify(RSNode & target) const250 void Modify(RSNode& target) const override
251 {
252 target.SetAlpha(alpha_->Get());
253 target.SetScale(scale_->Get());
254 target.SetBackgroundColor(color_->Get().AsArgbInt());
255 }
256
SetAlpha(float alpha)257 void SetAlpha(float alpha)
258 {
259 if (alpha_ == nullptr) {
260 alpha_ = std::make_shared<RSAnimatableProperty<float>>(alpha);
261 AttachProperty(alpha_);
262 } else {
263 alpha_->Set(alpha);
264 }
265 }
266
SetScale(Vector2f scale)267 void SetScale(Vector2f scale)
268 {
269 if (scale_ == nullptr) {
270 scale_ = std::make_shared<RSAnimatableProperty<Vector2f>>(scale);
271 AttachProperty(scale_);
272 } else {
273 scale_->Set(scale);
274 }
275 }
276
SetColor(Color color)277 void SetColor(Color color)
278 {
279 if (color_ == nullptr) {
280 color_ = std::make_shared<RSAnimatableProperty<Color>>(color);
281 AttachProperty(color_);
282 } else {
283 color_->Set(color);
284 }
285 }
286
287 private:
288 std::shared_ptr<RSAnimatableProperty<float>> alpha_;
289 std::shared_ptr<RSAnimatableProperty<Vector2f>> scale_;
290 std::shared_ptr<RSAnimatableProperty<Color>> color_;
291 };
292
InitNativeTokenInfo()293 void InitNativeTokenInfo()
294 {
295 #ifdef SUPPORT_ACCESS_TOKEN
296 uint64_t tokenId;
297 const char *perms[1];
298 perms[0] = "ohos.permission.SYSTEM_FLOAT_WINDOW";
299 NativeTokenInfoParams infoInstance = {
300 .dcapsNum = 0,
301 .permsNum = 1,
302 .aclsNum = 0,
303 .dcaps = NULL,
304 .perms = perms,
305 .acls = NULL,
306 .processName = "rs_uni_render_pixelmap_demo",
307 .aplStr = "system_basic",
308 };
309 tokenId = GetAccessTokenId(&infoInstance);
310 SetSelfTokenID(tokenId);
311 Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
312 #endif
313 }
314
main()315 int main()
316 {
317 #ifdef SUPPORT_ACCESS_TOKEN
318 InitNativeTokenInfo();
319
320 int cnt = 0;
321
322 // Init demo env
323 std::cout << "rs app demo start!" << std::endl;
324 sptr<WindowOption> option = new WindowOption();
325 option->SetWindowType(WindowType::WINDOW_TYPE_FLOAT);
326 option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
327 option->SetWindowRect({ 0, 0, 720, 1280 });
328 auto window = Window::Create("app_demo", option);
329 window->Show();
330 sleep(2);
331 auto rect = window->GetRect();
332 while (rect.width_ == 0 && rect.height_ == 0) {
333 std::cout << "rs app demo create window failed: " << rect.width_ << " " << rect.height_ << std::endl;
334 window->Hide();
335 window->Destroy();
336 window = Window::Create("app_demo", option);
337 window->Show();
338 rect = window->GetRect();
339 }
340 std::cout << "rs app demo create window " << rect.width_ << " " << rect.height_ << std::endl;
341 auto surfaceNode = window->GetSurfaceNode();
342
343 // Build rosen renderThread & create nodes
344 std::cout << "rs app demo stage " << cnt++ << std::endl;
345 auto rsUiDirector = RSUIDirector::Create();
346 rsUiDirector->Init();
347 auto runner = OHOS::AppExecFwk::EventRunner::Create(true);
348 auto handler = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
349 rsUiDirector->SetUITaskRunner(
350 [handler](const std::function<void()>& task, uint32_t delay) { handler->PostTask(task); });
351 runner->Run();
352 RSTransaction::FlushImplicitTransaction();
353 rsUiDirector->SetRSSurfaceNode(surfaceNode);
354 Init(rsUiDirector, rect.width_, rect.height_);
355
356 // change property in nodes [setter using modifier]
357 std::cout << "rs app demo stage " << cnt++ << std::endl;
358 nodes[0]->SetBounds(0, 0, 200, 200);
359 nodes[0]->SetFrame(0, 0, 200, 200);
360 nodes[0]->SetBorderColor(Drawing::Color::COLOR_BLACK);
361 nodes[0]->SetBorderWidth(10);
362 nodes[0]->SetBorderStyle((uint32_t)BorderStyle::SOLID);
363 rsUiDirector->SendMessages();
364 sleep(1);
365
366 std::cout << "rs app demo stage " << cnt++ << std::endl;
367
368 // multi-property modifier
369 auto customModifier = std::make_shared<CustomModifier>();
370 // add modifier to node
371 nodes[0]->AddModifier(customModifier);
372 // init property
373 customModifier->SetAlpha(0);
374 customModifier->SetWidth(0);
375 customModifier->SetHeight(0);
376 customModifier->SetBackgroundColor(Color(0, 0, 255));
377
378 RSAnimationTimingProtocol protocol;
379 protocol.SetDuration(3000);
380
381 // create property animation
382 RSNode::Animate(protocol, RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
383 customModifier->SetAlpha(0.8);
384 customModifier->SetWidth(720);
385 customModifier->SetHeight(1280);
386 customModifier->SetBackgroundColor(Color(255, 0, 0));
387 }, []() {
388 std::cout<<"custom animation 1 finish callback"<<std::endl;
389 });
390
391 int64_t startNum = 80825861106;
392 bool hasRunningAnimation = true;
393 while (hasRunningAnimation) {
394 hasRunningAnimation = rsUiDirector->FlushAnimation(startNum);
395 rsUiDirector->FlushModifier();
396 rsUiDirector->SendMessages();
397 startNum += 100000000;
398 usleep(100000);
399 }
400 sleep(2);
401
402 auto nodeModifier = std::make_shared<NodeModifier>();
403 nodes[1]->AddModifier(nodeModifier);
404 nodeModifier->SetAlpha(1);
405 nodeModifier->SetScale(Vector2f(1.f, 1.f));
406 nodeModifier->SetColor(Color(0, 255, 0));
407 rsUiDirector->FlushAnimation(0);
408 rsUiDirector->FlushModifier();
409 rsUiDirector->SendMessages();
410 sleep(3);
411
412 // create property animation
413 RSNode::Animate(protocol, RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
414 nodeModifier->SetAlpha(0.2);
415 nodeModifier->SetScale(Vector2f(3.f, 3.f));
416 nodeModifier->SetColor(Color(255, 0, 255));
417 }, []() {
418 std::cout<<"custom animation 2 finish callback"<<std::endl;
419 });
420
421 hasRunningAnimation = true;
422 while (hasRunningAnimation) {
423 hasRunningAnimation = rsUiDirector->FlushAnimation(startNum);
424 rsUiDirector->FlushModifier();
425 rsUiDirector->SendMessages();
426 startNum += 100000000;
427 usleep(100000);
428 }
429
430 // dump property via modifiers
431 std::cout << "rs app demo stage " << cnt++ << std::endl;
432 std::cout << nodes[0]->GetStagingProperties().Dump() << std::endl;
433 std::cout << "rs app demo end!" << std::endl;
434 sleep(3);
435
436 window->Hide();
437 window->Destroy();
438 #endif
439 return 0;
440 }
441