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