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
16 #include "rs_graphic_test.h"
17 #include "rs_graphic_test_director.h"
18 #include "rs_graphic_test_utils.h"
19 #include "rs_parameter_parse.h"
20 #include "rs_trace.h"
21 #include "transaction/rs_interfaces.h"
22 #include "ui/rs_root_node.h"
23 #include "ui/rs_surface_node.h"
24
25 #include <chrono>
26 #include <filesystem>
27 #include <iostream>
28 #include <thread>
29
30 using namespace std;
31 namespace OHOS {
32 namespace Rosen {
33 namespace {
34 constexpr uint32_t SURFACE_COLOR = 0xffffffff;
35
ShouldRunCurrentTest()36 bool ShouldRunCurrentTest()
37 {
38 const ::testing::TestInfo* const testInfo =
39 ::testing::UnitTest::GetInstance()->current_test_info();
40 const auto& extInfo = ::OHOS::Rosen::TestDefManager::Instance().GetTestInfo(
41 testInfo->test_case_name(), testInfo->name());
42 const auto& params = RSParameterParse::Instance();
43 if (!extInfo) {
44 LOGE("RSGraphicTest no testinfo %{public}s-%{public}s",
45 testInfo->test_case_name(), testInfo->name());
46 return false;
47 }
48 if (!params.filterTestTypes.empty() && params.filterTestTypes.count(extInfo->testType) == 0) {
49 return false;
50 }
51
52 if (params.runTestMode != RSGraphicTestMode::ALL && extInfo->testMode != params.runTestMode) {
53 return false;
54 }
55
56 return true;
57 }
58 }
59
60 uint32_t RSGraphicTest::imageWriteId_ = 0;
61
SetUpTestCase()62 void RSGraphicTest::SetUpTestCase()
63 {
64 imageWriteId_ = 0;
65 }
66
TearDownTestCase()67 void RSGraphicTest::TearDownTestCase()
68 {
69 return;
70 }
71
GetScreenCapacity(const string testCase)72 UIPoint RSGraphicTest::GetScreenCapacity(const string testCase)
73 {
74 int testCnt = ::OHOS::Rosen::TestDefManager::Instance().GetTestCaseCnt(testCase);
75 int cl = 1;
76 int num = 1;
77 while (num < testCnt) {
78 cl++;
79 num = cl * cl;
80 }
81 int rl = ceil(static_cast<double>(testCnt / cl));
82 return {cl, rl};
83 }
84
GetPos(int id,int cl)85 UIPoint RSGraphicTest::GetPos(int id, int cl)
86 {
87 if (cl > 0) {
88 int x = id % cl;
89 int y = id / cl;
90 return {x, y};
91 }
92
93 return {0, 0};
94 }
95
SetUp()96 void RSGraphicTest::SetUp()
97 {
98 shouldRunTest_ = ShouldRunCurrentTest();
99 if (!shouldRunTest_) {
100 GTEST_SKIP();
101 return;
102 }
103
104 RSSurfaceNodeConfig config;
105 string surfaceNodeName = "TestSurface";
106 config.SurfaceNodeName = surfaceNodeName.append(to_string(imageWriteId_));
107 auto testSurface = RSSurfaceNode::Create(config, false);
108
109 testSurface->SetBounds({0, 0, GetScreenSize()[0], GetScreenSize()[1]});
110 testSurface->SetFrame({0, 0, GetScreenSize()[0], GetScreenSize()[1]});
111 testSurface->SetBackgroundColor(SURFACE_COLOR);
112 GetRootNode()->SetTestSurface(testSurface);
113
114 BeforeEach();
115
116 const ::testing::TestInfo* const testInfo =
117 ::testing::UnitTest::GetInstance()->current_test_info();
118 const auto& extInfo = ::OHOS::Rosen::TestDefManager::Instance().GetTestInfo(
119 testInfo->test_case_name(), testInfo->name());
120 if (!extInfo->isMultiple) {
121 cout << "SetUp:isMultiple is false" << endl;
122 return;
123 }
124
125 cout << "SetUp:isMultiple is true" << endl;
126 auto capacity = GetScreenCapacity(string(testInfo->test_case_name()));
127 auto size = GetScreenSize();
128 cout << "SetUp:capacity:" << capacity.x_ << "*" << capacity.y_ << endl;
129 cout << "SetUp:size:" << size.x_ << "*" << size.y_ << endl;
130 if (imageWriteId_ == 0) {
131 SetScreenSurfaceBounds({0, 0, capacity.x_*size.x_, capacity.y_*size.y_});
132 cout << "ScreenSurfaceBounds:[" << capacity.x_*size.x_ << "*" << capacity.y_*size.y_ << "]" << endl;
133 }
134 auto pos = GetPos(extInfo->testId, capacity.x_);
135 cout << "pos:id:" << imageWriteId_ << "[" << pos.x_ << "." << pos.y_ << "]" << endl;
136
137 testSurface->SetBounds({pos.x_*size.x_, pos.y_*size.y_, size.x_, size.y_});
138 testSurface->SetFrame({pos.x_*size.x_, pos.y_*size.y_, size.x_, size.y_});
139 }
140
WaitOtherTest()141 bool RSGraphicTest::WaitOtherTest()
142 {
143 if (IsSingleTest()) {
144 return false;
145 }
146 const ::testing::TestInfo* const testInfo =
147 ::testing::UnitTest::GetInstance()->current_test_info();
148 const auto& extInfo = ::OHOS::Rosen::TestDefManager::Instance().GetTestInfo(
149 testInfo->test_case_name(), testInfo->name());
150 int testCaseCnt = ::OHOS::Rosen::TestDefManager::Instance().GetTestCaseCnt(
151 string(testInfo->test_case_name()));
152 if (!extInfo->isMultiple) {
153 return false;
154 }
155 if (++imageWriteId_ < testCaseCnt) {
156 return true;
157 }
158 return false;
159 }
160
TearDown()161 void RSGraphicTest::TearDown()
162 {
163 if (!shouldRunTest_) {
164 return;
165 }
166
167 const ::testing::TestInfo* const testInfo =
168 ::testing::UnitTest::GetInstance()->current_test_info();
169 const auto& extInfo = ::OHOS::Rosen::TestDefManager::Instance().GetTestInfo(
170 testInfo->test_case_name(), testInfo->name());
171
172 if (WaitOtherTest()) {
173 return;
174 }
175
176 StartUIAnimation();
177 RSGraphicTestDirector::Instance().FlushMessage();
178 WaitTimeout(RSParameterParse::Instance().testCaseWaitTime);
179
180 bool isManualTest = false;
181 if (extInfo) {
182 isManualTest = (extInfo->testMode == RSGraphicTestMode::MANUAL);
183 } else {
184 LOGE("RSGraphicTest no testinfo %{public}s-%{public}s", testInfo->test_case_name(), testInfo->name());
185 return;
186 }
187
188 if (isManualTest) {
189 WaitTimeout(RSParameterParse::Instance().manualTestWaitTime);
190 } else {
191 auto pixelMap = RSGraphicTestDirector::Instance().TakeScreenCaptureAndWait(
192 RSParameterParse::Instance().surfaceCaptureWaitTime);
193 if (pixelMap) {
194 std::string filename = GetImageSavePath(extInfo->filePath);
195 filename += testInfo->test_case_name();
196 if (!extInfo->isMultiple) {
197 filename += std::string("_") + testInfo->name();
198 }
199 filename += std::string(".png");
200 if (std::filesystem::exists(filename)) {
201 LOGW("RSGraphicTest file exists %{public}s", filename.c_str());
202 }
203 if (!WriteToPngWithPixelMap(filename, *pixelMap)) {
204 LOGE("RSGraphicTest::TearDown write image failed %{public}s-%{public}s",
205 testInfo->test_case_name(), testInfo->name());
206 }
207 std::cout << "png write to " << filename << std::endl;
208 }
209 }
210
211 AfterEach();
212 WaitTimeout(RSParameterParse::Instance().testCaseWaitTime);
213
214 GetRootNode()->ResetTestSurface();
215 RSGraphicTestDirector::Instance().FlushMessage();
216 WaitTimeout(RSParameterParse::Instance().testCaseWaitTime);
217 }
218
RegisterNode(std::shared_ptr<RSNode> node)219 void RSGraphicTest::RegisterNode(std::shared_ptr<RSNode> node)
220 {
221 nodes_.push_back(node);
222 GetRootNode()->RegisterNode(node);
223 }
224
AddFileRenderNodeTreeToNode(std::shared_ptr<RSNode> node,const std::string & filePath)225 void RSGraphicTest::AddFileRenderNodeTreeToNode(std::shared_ptr<RSNode> node, const std::string& filePath)
226 {
227 //need flush client node to rs firstly
228 RSGraphicTestDirector::Instance().FlushMessage();
229 WaitTimeout(RSParameterParse::Instance().testCaseWaitTime);
230
231 std::cout << "load subbtree to node file path is " << filePath << std::endl;
232 RSInterfaces::GetInstance().TestLoadFileSubTreeToNode(node->GetId(), filePath);
233 RSGraphicTestDirector::Instance().FlushMessage();
234 WaitTimeout(RSParameterParse::Instance().testCaseWaitTime);
235 }
236
GetRootNode() const237 std::shared_ptr<RSGraphicRootNode> RSGraphicTest::GetRootNode() const
238 {
239 return RSGraphicTestDirector::Instance().GetRootNode();
240 }
241
GetScreenSize() const242 Vector2f RSGraphicTest::GetScreenSize() const
243 {
244 return RSGraphicTestDirector::Instance().GetScreenSize();
245 }
246
SetSurfaceBounds(const Vector4f & bounds)247 void RSGraphicTest::SetSurfaceBounds(const Vector4f& bounds)
248 {
249 RSGraphicTestDirector::Instance().SetSurfaceBounds(bounds);
250 }
251
SetScreenSurfaceBounds(const Vector4f & bounds)252 void RSGraphicTest::SetScreenSurfaceBounds(const Vector4f& bounds)
253 {
254 RSGraphicTestDirector::Instance().SetScreenSurfaceBounds(bounds);
255 }
256
SetSurfaceColor(const RSColor & color)257 void RSGraphicTest::SetSurfaceColor(const RSColor& color)
258 {
259 RSGraphicTestDirector::Instance().SetSurfaceColor(color);
260 }
261
SetScreenSize(float width,float height)262 void RSGraphicTest::SetScreenSize(float width, float height)
263 {
264 RSGraphicTestDirector::Instance().SetScreenSize(width, height);
265 }
266
IsSingleTest()267 bool RSGraphicTest::IsSingleTest()
268 {
269 return RSGraphicTestDirector::Instance().IsSingleTest();
270 }
271
GetImageSavePath(const std::string path)272 std::string RSGraphicTest::GetImageSavePath(const std::string path)
273 {
274 std::string imagePath = "/data/local/";
275 size_t posCnt = path.rfind("/") + 1;
276 std::string subPath = path.substr(0, posCnt);
277 imagePath.append(subPath);
278
279 namespace fs = std::filesystem;
280 if (!fs::exists(imagePath)) {
281 if (!fs::create_directories(imagePath)) {
282 LOGE("RSGraphicTestDirector create dir failed");
283 }
284 } else {
285 if (!fs::is_directory(imagePath)) {
286 LOGE("RSGraphicTestDirector path is not dir");
287 }
288 }
289
290 return imagePath;
291 }
292
StartUIAnimation()293 void RSGraphicTest::StartUIAnimation()
294 {
295 RSGraphicTestDirector::Instance().StartRunUIAnimation();
296 }
297 } // namespace Rosen
298 } // namespace OHOS