1 /*
2 * Copyright (c) 2024 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 #include "drawing_demo.h"
16
17 #include <sstream>
18
19 #include "display_manager.h"
20 #include "test_case_factory.h"
21 #include "test_case/test_common.h"
22
23 using namespace OHOS::Rosen;
24
25 namespace OHOS {
26 namespace Rosen {
DrawingDemo(int argc,char * argv[])27 DrawingDemo::DrawingDemo(int argc, char* argv[])
28 {
29 argc_ = argc;
30 for (int i = 0; i < argc_; i++) {
31 std::string str = argv[i];
32 argv_.emplace_back(str);
33 }
34 };
35
~DrawingDemo()36 DrawingDemo::~DrawingDemo()
37 {
38 if (window_) {
39 window_->Hide();
40 window_->Destroy();
41 }
42 };
43
Test(TestDisplayCanvas * canvas)44 int DrawingDemo::Test(TestDisplayCanvas* canvas)
45 {
46 TestCommon::Log("eg: drawing_demo function [cpu | gpu] {caseName?} {displayTime?}");
47 TestCommon::Log("eg: drawing_demo performance [cpu | gpu] caseName count {displayTime?}");
48 if (argc_ <= INDEX_DRAWING_TYPE) {
49 return RET_PARAM_ERR;
50 }
51
52 testType_ = argv_[INDEX_TEST_TYPE];
53 drawingType_ = argv_[INDEX_DRAWING_TYPE];
54 if (testType_ == "function") {
55 if (drawingType_ == "cpu") {
56 return TestFunction(FUNCTION_CPU);
57 } else if (drawingType_ == "gpu") {
58 return TestFunction(FUNCTION_GPU_UPSCREEN);
59 }
60 } else if (testType_ == "performance") {
61 if (drawingType_ == "cpu") {
62 return TestPerformance(canvas, PERFORMANCE_CPU);
63 } else if (drawingType_ == "gpu") {
64 return TestPerformance(canvas, PERFORMANCE_GPU_UPSCREEN);
65 }
66 }
67 return RET_PARAM_ERR;
68 }
69
InitWindow()70 int DrawingDemo::InitWindow()
71 {
72 rsUiDirector_ = RSUIDirector::Create();
73 if (rsUiDirector_ == nullptr) {
74 TestCommon::Log("Failed to create rsUiDirector_");
75 return RET_FAILED;
76 }
77 rsUiDirector_->Init();
78 RSTransaction::FlushImplicitTransaction();
79 sleep(1);
80 auto surfaceNode = window_->GetSurfaceNode();
81 rsUiDirector_->SetRSSurfaceNode(surfaceNode);
82
83 rootNode_ = RSRootNode::Create();
84 if (rootNode_ == nullptr) {
85 TestCommon::Log("Failed to create rootNode");
86 return RET_FAILED;
87 }
88 rootNode_->SetBounds(0, 0, rect_.width_, rect_.height_);
89 rootNode_->SetFrame(0, 0, rect_.width_, rect_.height_);
90 rootNode_->SetBackgroundColor(Drawing::Color::COLOR_WHITE);
91 rsUiDirector_->SetRoot(rootNode_->GetId());
92
93 canvasNode_ = RSCanvasNode::Create();
94 if (canvasNode_ == nullptr) {
95 TestCommon::Log("Failed to create canvasNode");
96 return RET_FAILED;
97 }
98 canvasNode_->SetFrame(0, 0, rect_.width_, rect_.height_);
99 rootNode_->AddChild(canvasNode_, -1);
100 rsUiDirector_->SendMessages();
101 sleep(1);
102 return RET_OK;
103 }
104
CreateWindow()105 int DrawingDemo::CreateWindow()
106 {
107 TestCommon::Log("create window start");
108 sptr<Display> display = DisplayManager::GetInstance().GetDefaultDisplay();
109 if (display == nullptr) {
110 TestCommon::Log("Failed to get display!");
111 return RET_FAILED;
112 }
113 int32_t defaultWidth = display->GetWidth();
114 int32_t defaultHeight = display->GetHeight();
115 std::ostringstream stream;
116 stream << "display: " << defaultWidth << "*" << defaultHeight;
117 TestCommon::Log(stream.str());
118
119 std::string demoName = "drawing_demo";
120 RSSystemProperties::GetUniRenderEnabled();
121 sptr<WindowOption> option = new WindowOption();
122 option->SetWindowType(WindowType::WINDOW_TYPE_FLOAT);
123 option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
124 option->SetWindowRect({ 0, 0, defaultWidth, defaultHeight });
125
126 int count = 0;
127 do {
128 if (window_ != nullptr) {
129 window_->Hide();
130 window_->Destroy();
131 }
132 window_ = Window::Create(demoName, option);
133 if (window_ == nullptr) {
134 TestCommon::Log("Failed to create window");
135 return RET_FAILED;
136 }
137
138 window_->Show();
139 usleep(SLEEP_TIME);
140 rect_ = window_->GetRect();
141 count++;
142 } while (rect_.width_ == 0 && rect_.height_ == 0 && count < MAX_TRY_NUMBER);
143
144 if (rect_.width_ == 0 || rect_.height_ == 0) {
145 TestCommon::Log("Failed to create window, rect is 0!");
146 return RET_FAILED;
147 }
148
149 int ret = InitWindow();
150 if (ret != RET_OK) {
151 return ret;
152 }
153 stream.str("");
154 stream << "create window success: " << rect_.width_ << " * " << rect_.height_;
155 TestCommon::Log(stream.str());
156 return RET_OK;
157 }
158
GetFunctionalParam(std::unordered_map<std::string,std::function<std::shared_ptr<TestBase> ()>> & map)159 int DrawingDemo::GetFunctionalParam(std::unordered_map<std::string, std::function<std::shared_ptr<TestBase>()>>& map)
160 {
161 // drawing_demo functional {cpu | gpu} {caseName?} {displayTime?}
162 if (argc_ <= INDEX_CASE_NAME) {
163 caseName_ = ALL_TAST_CASE;
164 return RET_OK;
165 }
166
167 caseName_ = argv_[INDEX_CASE_NAME];
168 if (map.find(caseName_) == map.end()) {
169 TestCommon::Log("TestCase not exist, please try again. All testcase:");
170 for (auto iter : map) {
171 TestCommon::Log(iter.first);
172 }
173 return RET_PARAM_ERR;
174 }
175
176 if (argc_ > INDEX_FUNCTION_TIME) {
177 std::string displayTimeStr = argv_[INDEX_FUNCTION_TIME];
178 displayTime_ = std::stoi(displayTimeStr);
179 }
180 return RET_OK;
181 }
182
TestFunction(int type)183 int DrawingDemo::TestFunction(int type)
184 {
185 auto map = TestCaseFactory::GetFunctionCase();
186 int ret = GetFunctionalParam(map);
187 if (ret != RET_OK) {
188 return ret;
189 }
190
191 TestCommon::Log("TestFunction start!");
192 ret = CreateWindow();
193 if (ret != RET_OK) {
194 return ret;
195 }
196 for (auto iter : map) {
197 if ((caseName_ != ALL_TAST_CASE) && (caseName_ != iter.first)) {
198 continue;
199 }
200
201 auto canvas = canvasNode_->BeginRecording(rect_.width_, rect_.height_);
202 auto testCase = iter.second();
203 if (testCase == nullptr) {
204 std::ostringstream stream;
205 stream << "Failed to create testcase:" << iter.first;
206 TestCommon::Log(stream.str());
207 continue;
208 }
209
210 testCase->SetCanvas((TestDisplayCanvas*)(canvas));
211 if (type == FUNCTION_CPU) {
212 testCase->SetFileName(iter.first);
213 testCase->TestFunctionCpu();
214 } else if (type == FUNCTION_GPU_UPSCREEN) {
215 testCase->TestFunctionGpuUpScreen();
216 }
217 canvasNode_->FinishRecording();
218 rsUiDirector_->SendMessages();
219 if (type == FUNCTION_GPU_UPSCREEN) {
220 sleep(2); // Wait for 2 seconds to make the screen display normal
221 (void)TestCommon::PackingPixmap(window_->Snapshot(), iter.first);
222 }
223 }
224
225 int time = (caseName_ != ALL_TAST_CASE ? displayTime_ : 1);
226 std::ostringstream stream;
227 stream << "wait: " << time << "s";
228 TestCommon::Log(stream.str());
229 sleep(time);
230 TestCommon::Log("TestFunction end!");
231 return RET_OK;
232 }
233
GetPerformanceParam(std::shared_ptr<TestBase> & testCase)234 int DrawingDemo::GetPerformanceParam(std::shared_ptr<TestBase>& testCase)
235 {
236 // drawing_demo performance {cpu | gpu} caseName count {displaytime?}
237 if (argc_ <= INDEX_COUNT) {
238 return RET_PARAM_ERR;
239 }
240
241 caseName_ = argv_[INDEX_CASE_NAME];
242 auto map = TestCaseFactory::GetPerformanceCase();
243 auto iter = map.find(caseName_);
244 if (iter == map.end()) {
245 TestCommon::Log("TestCase not exist, please try again. All testcase:");
246 for (auto iter : map) {
247 TestCommon::Log(iter.first);
248 }
249 return RET_PARAM_ERR;
250 }
251 testCase = iter->second();
252 if (testCase == nullptr) {
253 TestCommon::Log("Failed to create testcase");
254 return RET_FAILED;
255 }
256
257 std::string testCountStr = argv_[INDEX_COUNT];
258 testCount_ = std::stoi(testCountStr);
259
260 if (argc_ > INDEX_PERFORMANCE_TIME) {
261 std::string displayTimeStr = argv_[INDEX_PERFORMANCE_TIME];
262 displayTime_ = std::stoi(displayTimeStr);
263 }
264 return RET_OK;
265 }
266
TestPerformance(TestDisplayCanvas * canvasExt,int type)267 int DrawingDemo::TestPerformance(TestDisplayCanvas* canvasExt, int type)
268 {
269 std::shared_ptr<TestBase> testCase = nullptr;
270 int ret = GetPerformanceParam(testCase);
271 if (ret != RET_OK || testCase == nullptr) {
272 return ret;
273 }
274
275 TestCommon::Log("TestPerformance start!");
276 TestDisplayCanvas* canvas = nullptr;
277 if (canvasExt == nullptr) {
278 ret = CreateWindow();
279 if (ret != RET_OK) {
280 return ret;
281 }
282 canvas = reinterpret_cast<TestDisplayCanvas*>(canvasNode_->BeginRecording(rect_.width_, rect_.height_));
283 if (canvas == nullptr) {
284 TestCommon::Log("Failed to get canvas");
285 return RET_FAILED;
286 }
287 } else {
288 canvas = canvasExt;
289 }
290
291 testCase->SetCanvas((TestDisplayCanvas*)(canvas));
292 testCase->SetTestCount(testCount_);
293
294 if (type == PERFORMANCE_CPU) {
295 testCase->TestPerformanceCpu();
296 } else if (type == PERFORMANCE_GPU_UPSCREEN) {
297 testCase->TestPerformanceGpuUpScreen();
298 }
299
300 if (canvasExt == nullptr) {
301 canvasNode_->FinishRecording();
302 rsUiDirector_->SendMessages();
303
304 std::ostringstream stream;
305 stream << "wait: " << displayTime_ << "s";
306 TestCommon::Log(stream.str());
307 sleep(displayTime_);
308 }
309
310 TestCommon::Log("TestPerformance end!");
311 return RET_OK;
312 }
313 } // namespace Rosen
314 } // namespace OHOS
315
main(int argc,char * argv[])316 int main(int argc, char* argv[])
317 {
318 std::shared_ptr<DrawingDemo> drawingDemo = std::make_shared<DrawingDemo>(argc, argv);
319 if (drawingDemo == nullptr) {
320 TestCommon::Log("Failed to create DrawingDemo");
321 return 0;
322 }
323 int ret = drawingDemo->Test(nullptr);
324 if (ret == RET_PARAM_ERR) {
325 TestCommon::Log("Invalid parameter, please confirm");
326 }
327 return ret;
328 }
329
330 #ifdef __cplusplus
331 extern "C" {
332 #endif
DrawingTest(void * canvas,int argc,char * argv[])333 int DrawingTest(void* canvas, int argc, char* argv[])
334 {
335 if (canvas == nullptr) {
336 TestCommon::Log("canvas is nullptr");
337 return 0;
338 }
339 std::shared_ptr<DrawingDemo> drawingDemo = std::make_shared<DrawingDemo>(argc, argv);
340 if (drawingDemo == nullptr) {
341 TestCommon::Log("Failed to create DrawingDemo");
342 return 0;
343 }
344 int ret = drawingDemo->Test((TestDisplayCanvas*)(canvas));
345 if (ret == RET_PARAM_ERR) {
346 TestCommon::Log("Invalid parameter, please confirm");
347 }
348 return ret;
349 }
350 #ifdef __cplusplus
351 }
352 #endif