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