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