1 /*
2 * Copyright (c) 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 #include <algorithm>
16 #include <chrono>
17 #include <regex>
18 #include "rs_round_corner_config.h"
19
20 using std::chrono::high_resolution_clock;
21 using std::chrono::microseconds;
22
23 namespace OHOS {
24 namespace Rosen {
25 namespace rs_rcd {
26 const char REG_NUM[] = "^[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)$"; // regular expression of check number
27
RegexMatch(const std::string & str,const std::string & pattern)28 bool XMLReader::RegexMatch(const std::string& str, const std::string& pattern)
29 {
30 std::smatch result;
31 std::regex r(pattern);
32 return std::regex_match(str, result, r);
33 }
34
RegexMatchNum(std::string & str)35 bool XMLReader::RegexMatchNum(std::string& str)
36 {
37 // remove space from string before match
38 str.erase(remove(str.begin(), str.end(), ' '), str.end());
39 return RegexMatch(str, std::string(REG_NUM));
40 }
41
FindNode(const xmlNodePtr & src,const std::string & index)42 xmlNodePtr XMLReader::FindNode(const xmlNodePtr& src, const std::string& index)
43 {
44 xmlNodePtr startPtr = src->children;
45 while (startPtr != nullptr) {
46 auto name = startPtr->name;
47 if (xmlStrEqual(name, BAD_CAST(index.c_str())) == 1) {
48 return startPtr;
49 }
50 startPtr = startPtr->next;
51 }
52 RS_LOGD("[%{public}s] can not found node %{public}s! \n", __func__, index.c_str());
53 return nullptr;
54 }
55
ReadAttrStr(const xmlNodePtr & src,const std::string & attr)56 std::string XMLReader::ReadAttrStr(const xmlNodePtr& src, const std::string& attr)
57 {
58 auto result = reinterpret_cast<char*>((xmlGetProp(src, BAD_CAST(attr.c_str()))));
59 if (result == nullptr) {
60 RS_LOGE("[%{public}s] can not found attribute %{public}s! \n", __func__, attr.c_str());
61 return std::string("");
62 }
63 std::string str(result);
64 xmlFree(result);
65 return str;
66 }
67
ReadAttrInt(const xmlNodePtr & src,const std::string & attr)68 int XMLReader::ReadAttrInt(const xmlNodePtr& src, const std::string& attr)
69 {
70 auto result = reinterpret_cast<char*>((xmlGetProp(src, BAD_CAST(attr.c_str()))));
71 if (result == nullptr) {
72 RS_LOGE("[%{public}s] can not found attribute %{public}s! \n", __func__, attr.c_str());
73 return 0;
74 }
75 std::string num(result);
76 xmlFree(result);
77 if (RegexMatchNum(num)) {
78 return std::atoi(num.c_str());
79 }
80 RS_LOGE("[%{public}s] attribute %{public}s can not convert to int! \n", __func__, attr.c_str());
81 return 0;
82 }
83
ReadAttrFloat(const xmlNodePtr & src,const std::string & attr)84 float XMLReader::ReadAttrFloat(const xmlNodePtr& src, const std::string& attr)
85 {
86 auto result = reinterpret_cast<char*>((xmlGetProp(src, BAD_CAST(attr.c_str()))));
87 if (result == nullptr) {
88 RS_LOGE("[%{public}s] can not found attribute %{public}s! \n", __func__, attr.c_str());
89 return 0.0f;
90 }
91 std::string num(result);
92 xmlFree(result);
93 if (RegexMatchNum(num)) {
94 return std::atof(num.c_str());
95 }
96 RS_LOGE("[%{public}s] attribute %{public}s can not convert to float! \n", __func__, attr.c_str());
97 return 0;
98 }
99
ReadAttrBool(const xmlNodePtr & src,const std::string & attr)100 bool XMLReader::ReadAttrBool(const xmlNodePtr& src, const std::string& attr)
101 {
102 auto result = reinterpret_cast<char*>((xmlGetProp(src, BAD_CAST(attr.c_str()))));
103 if (result == nullptr) {
104 RS_LOGE("[%{public}s] can not found attribute %{public}s! \n", __func__, attr.c_str());
105 return false;
106 }
107 auto istrue = strcmp(result, "true") == 0 ? true : false;
108 xmlFree(result);
109 return istrue;
110 }
111
ReadXmlNode(const xmlNodePtr & ptr,const std::string & supportAttr,const std::string & modeAttr)112 bool SupportConfig::ReadXmlNode(const xmlNodePtr& ptr, const std::string& supportAttr, const std::string& modeAttr)
113 {
114 auto a1 = xmlGetProp(ptr, BAD_CAST(supportAttr.c_str()));
115 if (a1 == nullptr) {
116 RS_LOGE("[%{public}s] can not found supportAttr %{public}s! \n", __func__, supportAttr.c_str());
117 return false;
118 }
119 support = XMLReader::ReadAttrBool(ptr, supportAttr);
120 mode = XMLReader::ReadAttrInt(ptr, modeAttr);
121 xmlFree(a1);
122 return true;
123 }
124
ReadXmlNode(const xmlNodePtr & ptr,const std::vector<std::string> & attrArray)125 bool RoundCornerLayer::ReadXmlNode(const xmlNodePtr& ptr, const std::vector<std::string>& attrArray)
126 {
127 const int layerAttrSize = 7;
128 if (attrArray.size() < layerAttrSize || ptr == nullptr) {
129 RS_LOGE("[%{public}s] attribute size less than 7! \n", __func__);
130 return false;
131 }
132 const int fileIndex = 0;
133 const int offsetXIndex = 1;
134 const int offsetYIndex = 2;
135 const int binFileIndex = 3;
136 const int bufferSizeIndex = 4;
137 const int cldWidthIndex = 5;
138 const int cldHeightIndex = 6;
139 fileName = XMLReader::ReadAttrStr(ptr, attrArray[fileIndex]);
140 offsetX = XMLReader::ReadAttrInt(ptr, attrArray[offsetXIndex]);
141 offsetY = XMLReader::ReadAttrInt(ptr, attrArray[offsetYIndex]);
142 binFileName = XMLReader::ReadAttrStr(ptr, attrArray[binFileIndex]);
143 bufferSize = XMLReader::ReadAttrInt(ptr, attrArray[bufferSizeIndex]);
144 cldWidth = XMLReader::ReadAttrInt(ptr, attrArray[cldWidthIndex]);
145 cldHeight = XMLReader::ReadAttrInt(ptr, attrArray[cldHeightIndex]);
146 return true;
147 }
148
ReadXmlNode(const xmlNodePtr & portraitNodePtr)149 bool RogPortrait::ReadXmlNode(const xmlNodePtr& portraitNodePtr)
150 {
151 if (portraitNodePtr == nullptr) {
152 RS_LOGE("[%{public}s] input node is null! \n", __func__);
153 return false;
154 }
155 std::vector<std::string> attrList = { ATTR_FILENAME, ATTR_OFFSET_X, ATTR_OFFSET_Y,
156 ATTR_BINFILENAME, ATTR_BUFFERSIZE, ATTR_CLDWIDTH, ATTR_CLDHEIGHT };
157
158 auto layerUpPtr = XMLReader::FindNode(portraitNodePtr, std::string(NODE_LAYERUP));
159 if (layerUpPtr == nullptr) {
160 RS_LOGE("[%{public}s] layerUpPtr node is null! \n", __func__);
161 return false;
162 }
163 layerUp.ReadXmlNode(layerUpPtr, attrList);
164
165 auto layerDownPtr = XMLReader::FindNode(portraitNodePtr, std::string(NODE_LAYERDOWN));
166 if (layerDownPtr == nullptr) {
167 RS_LOGE("[%{public}s] layerDownPtr node is null! \n", __func__);
168 return false;
169 }
170 layerDown.ReadXmlNode(layerDownPtr, attrList);
171
172 auto layerHidePtr = XMLReader::FindNode(portraitNodePtr, std::string(NODE_LAYERHIDE));
173 if (layerHidePtr == nullptr) {
174 RS_LOGE("[%{public}s] layerHidePtr node is null! \n", __func__);
175 return false;
176 }
177 layerHide.ReadXmlNode(layerHidePtr, attrList);
178 return true;
179 }
180
ReadXmlNode(const xmlNodePtr & landNodePtr)181 bool RogLandscape::ReadXmlNode(const xmlNodePtr& landNodePtr)
182 {
183 if (landNodePtr == nullptr) {
184 RS_LOGE("[%{public}s] landNodePtr node is null! \n", __func__);
185 return false;
186 }
187 std::vector<std::string> attrList = { ATTR_FILENAME, ATTR_OFFSET_X, ATTR_OFFSET_Y,
188 ATTR_BINFILENAME, ATTR_BUFFERSIZE, ATTR_CLDWIDTH, ATTR_CLDHEIGHT };
189 auto layerUpPtr = XMLReader::FindNode(landNodePtr, std::string(NODE_LAYERUP));
190 if (layerUpPtr == nullptr) {
191 RS_LOGE("[%{public}s] layerUpPtr node is null! \n", __func__);
192 return false;
193 }
194 layerUp.ReadXmlNode(layerUpPtr, attrList);
195 return true;
196 }
197
ReadXmlNode(const xmlNodePtr & rogNodePtr)198 bool ROGSetting::ReadXmlNode(const xmlNodePtr& rogNodePtr)
199 {
200 if (rogNodePtr == nullptr) {
201 RS_LOGE("[%{public}s] rogNodePtr node is null! \n", __func__);
202 return false;
203 }
204 width = XMLReader::ReadAttrInt(rogNodePtr, std::string(ATTR_WIDTH));
205 height = XMLReader::ReadAttrInt(rogNodePtr, std::string(ATTR_HEIGHT));
206
207 auto portPtr = XMLReader::FindNode(rogNodePtr, NODE_PORTRAIT);
208 if (portPtr != nullptr) {
209 RogPortrait p;
210 p.ReadXmlNode(portPtr);
211 portraitMap[NODE_PORTRAIT] = p;
212 }
213
214 auto portSidePtr = XMLReader::FindNode(rogNodePtr, NODE_PORTRAIT_SIDEREGION);
215 if (portSidePtr != nullptr) {
216 RogPortrait p;
217 p.ReadXmlNode(portSidePtr);
218 portraitMap[NODE_PORTRAIT_SIDEREGION] = p;
219 }
220
221 auto landPtr = XMLReader::FindNode(rogNodePtr, NODE_LANDSCAPE);
222 if (landPtr != nullptr) {
223 RogLandscape p;
224 p.ReadXmlNode(landPtr);
225 landscapeMap[NODE_LANDSCAPE] = p;
226 }
227
228 auto landSidePtr = XMLReader::FindNode(rogNodePtr, NODE_LANDSCAPE_SIDEREGION);
229 if (landSidePtr != nullptr) {
230 RogLandscape p;
231 p.ReadXmlNode(landSidePtr);
232 landscapeMap[NODE_LANDSCAPE_SIDEREGION] = p;
233 }
234 return true;
235 }
236
ReadXmlNode(const xmlNodePtr & surfaceConfigNodePtr)237 bool SurfaceConfig::ReadXmlNode(const xmlNodePtr& surfaceConfigNodePtr)
238 {
239 if (surfaceConfigNodePtr == nullptr) {
240 RS_LOGE("[%{public}s] surfaceConfigNodePtr node is null! \n", __func__);
241 return false;
242 }
243
244 auto topSurfacePtr = XMLReader::FindNode(surfaceConfigNodePtr, std::string(NODE_TOPSURFACE));
245 if (topSurfacePtr == nullptr) {
246 RS_LOGE("[%{public}s] topSurfacePtr node is null! \n", __func__);
247 return false;
248 }
249 topSurface.ReadXmlNode(topSurfacePtr, std::string(ATTR_SUPPORT), std::string(ATTR_DISPLAYMODE));
250
251 auto bottomSurfacePtr = XMLReader::FindNode(surfaceConfigNodePtr, std::string(NODE_BOTTOMSURFACE));
252 if (bottomSurfacePtr == nullptr) {
253 RS_LOGE("[%{public}s] bottomSurfacePtr node is null! \n", __func__);
254 return false;
255 }
256 bottomSurface.ReadXmlNode(bottomSurfacePtr, std::string(ATTR_SUPPORT), std::string(ATTR_DISPLAYMODE));
257 return true;
258 }
259
ReadXmlNode(const xmlNodePtr & sideRegionNodePtr)260 bool SideRegionConfig::ReadXmlNode(const xmlNodePtr& sideRegionNodePtr)
261 {
262 if (sideRegionNodePtr == nullptr) {
263 RS_LOGE("[%{public}s] sideRegionNodePtr node is null! \n", __func__);
264 return false;
265 }
266 auto sideRegionPtr = XMLReader::FindNode(sideRegionNodePtr, std::string(NODE_SIDEREGION));
267 if (sideRegionPtr == nullptr) {
268 RS_LOGE("[%{public}s] sideRegionPtr node is null! \n", __func__);
269 return false;
270 }
271 sideRegion.ReadXmlNode(sideRegionPtr, std::string(ATTR_SUPPORT), std::string(ATTR_DISPLAYMODE));
272 return true;
273 }
274
ReadXmlNode(const xmlNodePtr & ptr,const std::string & supportAttr)275 bool HardwareComposer::ReadXmlNode(const xmlNodePtr& ptr, const std::string& supportAttr)
276 {
277 auto a1 = xmlGetProp(ptr, BAD_CAST(supportAttr.c_str()));
278 if (a1 == nullptr) {
279 RS_LOGE("[%{public}s] supportAttr node is null! \n", __func__);
280 return false;
281 }
282 support = XMLReader::ReadAttrBool(ptr, supportAttr);
283 xmlFree(a1);
284 return true;
285 }
286
ReadXmlNode(const xmlNodePtr & hardwareComposerNodeptr)287 bool HardwareComposerConfig::ReadXmlNode(const xmlNodePtr& hardwareComposerNodeptr)
288 {
289 if (hardwareComposerNodeptr == nullptr) {
290 RS_LOGE("[%{public}s] hardwareComposerNodeptr node is null! \n", __func__);
291 return false;
292 }
293 auto hardwareComposerPtr = XMLReader::FindNode(hardwareComposerNodeptr, std::string(NODE_HARDWARECOMPOSER));
294 if (hardwareComposerPtr == nullptr) {
295 RS_LOGE("[%{public}s] hardwareComposerPtr node is null! \n", __func__);
296 return false;
297 }
298 hardwareComposer.ReadXmlNode(hardwareComposerPtr, std::string(ATTR_SUPPORT));
299 return true;
300 }
301
~LCDModel()302 LCDModel::~LCDModel()
303 {
304 for (auto& rog : rogs) {
305 if (rog != nullptr) {
306 delete rog;
307 rog = nullptr;
308 }
309 }
310 }
311
ReadXmlNode(const xmlNodePtr & lcdNodePtr)312 bool LCDModel::ReadXmlNode(const xmlNodePtr& lcdNodePtr)
313 {
314 if (lcdNodePtr == nullptr) {
315 RS_LOGE("[%{public}s] input lcdNodePtr node is null! \n", __func__);
316 return false;
317 }
318 name = XMLReader::ReadAttrStr(lcdNodePtr, std::string(ATTR_NAME));
319 auto surfaceConfigPtr = XMLReader::FindNode(lcdNodePtr, std::string(NODE_SURFACECONFIG));
320 if (surfaceConfigPtr == nullptr) {
321 RS_LOGW("no surfaceConfig found \n");
322 }
323 surfaceConfig.ReadXmlNode(surfaceConfigPtr);
324
325 auto sideRegionConfigPtr = XMLReader::FindNode(lcdNodePtr, std::string(NODE_SIDEREGIONCONFIG));
326 if (sideRegionConfigPtr == nullptr) {
327 RS_LOGW("no sideRegionConfig found \n");
328 }
329 sideRegionConfig.ReadXmlNode(sideRegionConfigPtr);
330
331 auto hardwareComposerConfigPtr = XMLReader::FindNode(lcdNodePtr, std::string(NODE_HARDWARECOMPOSERCONFIG));
332 if (hardwareComposerConfigPtr == nullptr) {
333 RS_LOGW("no harewareComposer found \n");
334 }
335 hardwareConfig.ReadXmlNode(hardwareComposerConfigPtr);
336
337 xmlNodePtr startPtr = lcdNodePtr->children;
338 while (startPtr != nullptr) {
339 auto name = startPtr->name;
340 if (xmlStrEqual(name, BAD_CAST(NODE_ROG)) == 1) {
341 ROGSetting *rog = new ROGSetting();
342 if (rog->ReadXmlNode(startPtr)) {
343 rogs.push_back(rog);
344 } else {
345 delete rog;
346 rog = nullptr;
347 }
348 }
349 startPtr = startPtr->next;
350 }
351 return true;
352 }
353
GetSurfaceConfig() const354 SurfaceConfig LCDModel::GetSurfaceConfig() const
355 {
356 return surfaceConfig;
357 }
358
GetSideRegionConfig() const359 SideRegionConfig LCDModel::GetSideRegionConfig() const
360 {
361 return sideRegionConfig;
362 }
363
GetHardwareComposerConfig() const364 HardwareComposerConfig LCDModel::GetHardwareComposerConfig() const
365 {
366 return hardwareConfig;
367 }
368
GetRog(const int w,const int h) const369 ROGSetting* LCDModel::GetRog(const int w, const int h) const
370 {
371 for (auto rog : rogs) {
372 if (rog == nullptr) {
373 continue;
374 }
375 if (rog->width == w && rog->height == h) {
376 return rog;
377 }
378 }
379 return nullptr;
380 }
381
PrintLayer(const std::string & name,const rs_rcd::RoundCornerLayer & layer)382 void RCDConfig::PrintLayer(const std::string& name, const rs_rcd::RoundCornerLayer& layer)
383 {
384 RS_LOGD("%{public}s->Filename: %{public}s, Offset: %{public}d, %{public}d \n",
385 name.c_str(), layer.fileName.c_str(), layer.offsetX, layer.offsetY);
386 RS_LOGD("BinFilename: %{public}s, BufferSize: %{public}d, cldSize:%{public}d, %{public}d \n",
387 layer.binFileName.c_str(), layer.bufferSize, layer.cldWidth, layer.cldHeight);
388 }
389
PrintParseRog(rs_rcd::ROGSetting * rog)390 void RCDConfig::PrintParseRog(rs_rcd::ROGSetting* rog)
391 {
392 if (rog == nullptr) {
393 RS_LOGE("no model input \n");
394 return;
395 }
396 for (auto kv : rog->portraitMap) {
397 auto port = kv.second;
398 RS_LOGD("rog: %{public}d, %{public}d, %{public}s: \n", rog->width, rog->height, kv.first.c_str());
399 PrintLayer(std::string("layerUp "), port.layerUp);
400 PrintLayer(std::string("layerDown"), port.layerDown);
401 PrintLayer(std::string("layerHide"), port.layerHide);
402 }
403 for (auto kv : rog->landscapeMap) {
404 auto port = kv.second;
405 RS_LOGD("rog: %{public}d, %{public}d, %{public}s: \n", rog->width, rog->height, kv.first.c_str());
406 PrintLayer(std::string("layerUp "), port.layerUp);
407 }
408 }
409
Load(const std::string & configFile)410 bool RCDConfig::Load(const std::string& configFile)
411 {
412 auto begin = high_resolution_clock::now();
413 xmlKeepBlanksDefault(0);
414 pDoc = xmlReadFile(configFile.c_str(), "", XML_PARSE_RECOVER);
415 if (pDoc == nullptr) {
416 RS_LOGE("RoundCornerDisplay read xml failed \n");
417 CloseXML();
418 return false;
419 }
420 RS_LOGI("RoundCornerDisplay read xml ok \n");
421 pRoot = xmlDocGetRootElement(pDoc);
422 if (pRoot == nullptr) {
423 RS_LOGE("RoundCornerDisplay get xml root failed \n");
424 CloseXML();
425 return false;
426 }
427 xmlNodePtr startPtr = pRoot->children;
428 while (startPtr != nullptr) {
429 auto name = startPtr->name;
430 if (xmlStrEqual(name, BAD_CAST(NODE_LCDMODEL)) == 1) {
431 LCDModel* lcdModel = new LCDModel();
432 if (lcdModel->ReadXmlNode(startPtr)) {
433 lcdModels.push_back(lcdModel);
434 } else {
435 delete lcdModel;
436 lcdModel = nullptr;
437 }
438 }
439 startPtr = startPtr->next;
440 }
441 CloseXML();
442 auto interval = std::chrono::duration_cast<microseconds>(high_resolution_clock::now() - begin);
443 RS_LOGI("RoundCornerDisplay read xml time cost %{public}lld us \n", interval.count());
444 return true;
445 }
446
GetLcdModel(const std::string & name) const447 LCDModel* RCDConfig::GetLcdModel(const std::string& name) const
448 {
449 if (name.empty()) {
450 RS_LOGE("[%{public}s] name is null! \n", __func__);
451 return nullptr;
452 }
453 for (auto model : lcdModels) {
454 if (model == nullptr) {
455 continue;
456 }
457 if (model->name.compare(name) == 0) {
458 return model;
459 }
460 }
461 RS_LOGE("[%{public}s] lcd not found in name %{public}s! \n", __func__, name.c_str());
462 return nullptr;
463 }
464
CloseXML()465 void RCDConfig::CloseXML()
466 {
467 if (pDoc != nullptr) {
468 xmlFreeDoc(pDoc);
469 pDoc = nullptr;
470 }
471 xmlCleanupParser();
472 xmlMemoryDump();
473 }
474
~RCDConfig()475 RCDConfig::~RCDConfig()
476 {
477 for (auto& modelPtr : lcdModels) {
478 if (modelPtr != nullptr) {
479 delete modelPtr;
480 modelPtr = nullptr;
481 }
482 }
483 }
484 } // namespace rs_rcd
485 } // namespace Rosen
486 } // OHOS