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