1 /*
2  * Copyright (c) 2022-2023 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 
19 #include "property/rs_properties_def.h"
20 #include "refbase.h"
21 #include "render_context/render_context.h"
22 #include "transaction/rs_transaction.h"
23 #include "ui/rs_surface_extractor.h"
24 #include "ui/rs_surface_node.h"
25 #include "window.h"
26 
27 namespace OHOS {
28 namespace Rosen {
29 namespace Test {
30 #define RS_GRAVITY_CASE_STR(value) case value: return #value
GravityString(Gravity gravity)31 const char* GravityString(Gravity gravity)
32 {
33     switch (gravity) {
34         RS_GRAVITY_CASE_STR(Gravity::BOTTOM);
35         RS_GRAVITY_CASE_STR(Gravity::BOTTOM_LEFT);
36         RS_GRAVITY_CASE_STR(Gravity::BOTTOM_RIGHT);
37         RS_GRAVITY_CASE_STR(Gravity::LEFT);
38         RS_GRAVITY_CASE_STR(Gravity::RIGHT);
39         RS_GRAVITY_CASE_STR(Gravity::TOP_LEFT);
40         RS_GRAVITY_CASE_STR(Gravity::TOP_RIGHT);
41         RS_GRAVITY_CASE_STR(Gravity::CENTER);
42         RS_GRAVITY_CASE_STR(Gravity::TOP);
43         RS_GRAVITY_CASE_STR(Gravity::RESIZE);
44         RS_GRAVITY_CASE_STR(Gravity::RESIZE_ASPECT);
45         RS_GRAVITY_CASE_STR(Gravity::RESIZE_ASPECT_TOP_LEFT);
46         RS_GRAVITY_CASE_STR(Gravity::RESIZE_ASPECT_BOTTOM_RIGHT);
47         RS_GRAVITY_CASE_STR(Gravity::RESIZE_ASPECT_FILL);
48         RS_GRAVITY_CASE_STR(Gravity::RESIZE_ASPECT_FILL_TOP_LEFT);
49         RS_GRAVITY_CASE_STR(Gravity::RESIZE_ASPECT_FILL_BOTTOM_RIGHT);
50         default: return "Unknown";
51     }
52 }
53 
54 // we can make this demo and run it on the device,
55 // to visualize the surface's all gravity effects in the window area,
56 // as its enum name indicates.
57 class RsSurfaceNodeGravityTestDemo {
58 public:
RsSurfaceNodeGravityTestDemo()59     RsSurfaceNodeGravityTestDemo()
60     {
61 #ifdef RS_ENABLE_GPU
62         renderContext_ = std::make_unique<RenderContext>();
63         renderContext_->InitializeEglContext();
64 #endif // RS_ENABLE_GPU
65 
66         sptr<WindowOption> option(new WindowOption());
67         option->SetDisplayId(0); // default displayId is 0
68         option->SetWindowRect({0, 0, 600, 600}); // test window size is 600*600
69         option->SetWindowType(WindowType::APP_MAIN_WINDOW_BASE);
70         option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
71         option->SetWindowName("gravity_demo");
72         window_ = Window::Create(option->GetWindowName(), option);
73         if (window_ != nullptr) {
74             surfaceNode_ = window_->GetSurfaceNode();
75             surfaceNode_->SetBounds(0, 0, 600, 600); // surface bounds is window rect.
76             surfaceNode_->SetBackgroundColor(0xffff0000); // set background color to red.
77             RSTransaction::FlushImplicitTransaction();
78             window_->Show();
79         } else {
80             std::cout << "Failed to create window!" << std::endl;
81         }
82 
83         availableGravities_ = {
84             Gravity::CENTER, Gravity::TOP, Gravity::BOTTOM, Gravity::LEFT, Gravity::RIGHT, Gravity::TOP_LEFT,
85             Gravity::TOP_RIGHT, Gravity::BOTTOM_LEFT, Gravity::BOTTOM_RIGHT, Gravity::RESIZE, Gravity::RESIZE_ASPECT,
86             Gravity::RESIZE_ASPECT_TOP_LEFT, Gravity::RESIZE_ASPECT_BOTTOM_RIGHT, Gravity::RESIZE_ASPECT_FILL,
87             Gravity::RESIZE_ASPECT_FILL_TOP_LEFT, Gravity::RESIZE_ASPECT_FILL_BOTTOM_RIGHT, Gravity::DEFAULT
88         };
89     }
90 
~RsSurfaceNodeGravityTestDemo()91     ~RsSurfaceNodeGravityTestDemo() noexcept
92     {
93         if (window_ != nullptr) {
94             window_->Hide();
95             window_->Destroy();
96         }
97     }
98 
Run()99     void Run()
100     {
101         if (surfaceNode_ == nullptr) {
102             return;
103         }
104 
105         auto rsSurface = RSSurfaceExtractor::ExtractRSSurface(surfaceNode_);
106         if (rsSurface == nullptr) {
107             return;
108         }
109 
110 #ifdef RS_ENABLE_GPU
111         if (renderContext_ != nullptr) {
112             rsSurface->SetRenderContext(renderContext_.get());
113         }
114 #endif // RS_ENABLE_GPU
115 
116         std::size_t gravityIdx = 0;
117         // test 50 frames.
118         for (int i = 0; i < 50; ++i) {
119             if (gravityIdx >= availableGravities_.size()) {
120                 gravityIdx = 0;
121             }
122             auto gravity = availableGravities_[gravityIdx++];
123             surfaceNode_->SetFrameGravity(gravity);
124             RSTransaction::FlushImplicitTransaction();
125 
126             // make the surfaceBuffer(400*400) smaller than the window size to test gravity.
127             auto frame = rsSurface->RequestFrame(400, 400);
128             if (frame == nullptr) {
129                 std::cout << "Failed to create frame!" << std::endl;
130                 return;
131             }
132             auto canvas = frame->GetCanvas();
133             if (canvas == nullptr) {
134                 std::cout << "Failed to create canvas!" << std::endl;
135                 return;
136             }
137             canvas->Clear(Drawing::Color::COLOR_WHITE);
138             std::cout << "Drawing does not support TextBlob" << std::endl;
139             frame->SetDamageRegion(0, 0, 400, 400);
140             rsSurface->FlushFrame(frame);
141 
142             sleep(2);
143         }
144     }
145 
146 private:
147 #ifdef RS_ENABLE_GPU
148     std::unique_ptr<RenderContext> renderContext_;
149 #endif // RS_ENABLE_GPU
150 
151     sptr<Window> window_;
152     std::shared_ptr<RSSurfaceNode> surfaceNode_;
153     std::vector<Gravity> availableGravities_;
154 };
155 } // namespace Test
156 } // namespace Rosen
157 } // namespace OHOS
158 
main()159 int main()
160 {
161     std::cout << "rs gravity demo start!" << std::endl;
162     OHOS::Rosen::Test::RsSurfaceNodeGravityTestDemo demo;
163     demo.Run();
164     std::cout << "rs gravity demo end!" << std::endl;
165     return 0;
166 }
167