1 /*
2 * Copyright (c) 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 <iostream>
17 #include <random>
18 #include <string>
19
20
21 #include "refbase.h"
22 #include "render_context/render_context.h"
23 #include "transaction/rs_transaction.h"
24 #include "ui/rs_surface_extractor.h"
25 #include "ui/rs_surface_node.h"
26 #include "window.h"
27
28 namespace OHOS {
29 namespace Rosen {
30 namespace Test {
31 constexpr int DEFAULT_DISPLAY_ID = 0;
32 constexpr int WINDOW_LEFT = 100;
33 constexpr int WINDOW_TOP = 200;
34 constexpr int WINDOW_WIDTH = 360;
35 constexpr int WINDOW_HEIGHT = 360;
36 constexpr int BUFFER_WIDTH = 360;
37 constexpr int BUFFER_HEIGHT = 360;
38 constexpr float MIN_SCALE = 0.5f;
39 constexpr float MAX_SCALE = 2.0f;
40
GetRandomScale()41 float GetRandomScale()
42 {
43 static std::random_device seed;
44 std::mt19937_64 gen(seed());
45 std::uniform_real_distribution<> distribution(MIN_SCALE, MAX_SCALE);
46 return distribution(gen);
47 }
48
49 // we can make this demo and run it on the device,
50 // to visualize the surface's scale effects.
51 class RsSurfaceNodeScaleTestDemo {
52 public:
RsSurfaceNodeScaleTestDemo()53 RsSurfaceNodeScaleTestDemo()
54 {
55 #ifdef RS_ENABLE_GPU
56 renderContext_ = std::make_unique<RenderContext>();
57 renderContext_->InitializeEglContext();
58 #endif // RS_ENABLE_GPU
59
60 sptr<WindowOption> option(new WindowOption());
61 option->SetDisplayId(DEFAULT_DISPLAY_ID);
62 option->SetWindowRect( {WINDOW_LEFT, WINDOW_TOP, WINDOW_WIDTH, WINDOW_HEIGHT} );
63 option->SetWindowType(WindowType::APP_MAIN_WINDOW_BASE);
64 option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
65 option->SetWindowName("scale_demo");
66 window_ = Window::Create(option->GetWindowName(), option);
67 if (window_ != nullptr) {
68 surfaceNode_ = window_->GetSurfaceNode();
69 // surface bounds is window rect.
70 surfaceNode_->SetBounds(WINDOW_LEFT, WINDOW_TOP, WINDOW_WIDTH, WINDOW_HEIGHT);
71 RSTransaction::FlushImplicitTransaction();
72 window_->Show();
73 } else {
74 std::cout << "Failed to create window!" << std::endl;
75 }
76 }
77
~RsSurfaceNodeScaleTestDemo()78 ~RsSurfaceNodeScaleTestDemo() noexcept
79 {
80 if (window_ != nullptr) {
81 window_->Hide();
82 window_->Destroy();
83 }
84 }
85
Run()86 void Run()
87 {
88 if (surfaceNode_ == nullptr) {
89 return;
90 }
91
92 auto rsSurface = RSSurfaceExtractor::ExtractRSSurface(surfaceNode_);
93 if (rsSurface == nullptr) {
94 return;
95 }
96
97 #ifdef RS_ENABLE_GPU
98 if (renderContext_ != nullptr) {
99 rsSurface->SetRenderContext(renderContext_.get());
100 }
101 #endif // RS_ENABLE_GPU
102
103 // test 50 frames.
104 for (int i = 0; i < 50; ++i) {
105 // get random scales and set them with pivot(start point or center point).
106 float scaleX = GetRandomScale();
107 float scaleY = GetRandomScale();
108 surfaceNode_->SetScale(scaleX, scaleY);
109 // default pivot: center
110 float pivotX = 0.5f; // centerX: 0.5
111 float pivotY = 0.5f; // centerY: 0.5
112 std::string pivotInfo;
113 // make pivot to start point if (i % 2 == 0)
114 if (i % 2 == 0) {
115 pivotX = 0.0f;
116 pivotY = 0.0f;
117 pivotInfo = "Pivot: start(0, 0)";
118 }
119 surfaceNode_->SetPivot(pivotX, pivotY);
120 RSTransaction::FlushImplicitTransaction();
121
122 auto frame = rsSurface->RequestFrame(BUFFER_WIDTH, BUFFER_HEIGHT);
123 if (frame == nullptr) {
124 std::cout << "Failed to create frame!" << std::endl;
125 return;
126 }
127 auto canvas = frame->GetCanvas();
128 if (canvas == nullptr) {
129 std::cout << "Failed to create canvas!" << std::endl;
130 return;
131 }
132 canvas->Clear(Drawing::Color::COLOR_WHITE);
133 std::cout << "Drawing does not support TextBlob" << std::endl;
134 frame->SetDamageRegion(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT);
135 rsSurface->FlushFrame(frame);
136
137 sleep(2); // sleep 2s
138 }
139 }
140
141 private:
142 #ifdef RS_ENABLE_GPU
143 std::unique_ptr<RenderContext> renderContext_;
144 #endif // RS_ENABLE_GPU
145
146 sptr<Window> window_;
147 std::shared_ptr<RSSurfaceNode> surfaceNode_;
148 };
149 } // namespace Test
150 } // namespace Rosen
151 } // namespace OHOS
152
main()153 int main()
154 {
155 std::cout << "rs surface node scale demo start!" << std::endl;
156 OHOS::Rosen::Test::RsSurfaceNodeScaleTestDemo demo;
157 demo.Run();
158 std::cout << "rs surface node scale demo end!" << std::endl;
159 return 0;
160 }
161