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