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