增加图形xml配置文件读取

Signed-off-by: wangjincheng <wangjincheng13@huawei.com>
This commit is contained in:
wangjincheng 2024-08-20 15:58:13 +08:00
parent e27e40ce5f
commit 7ad20dbe01
13 changed files with 1049 additions and 0 deletions

View File

@ -17,6 +17,7 @@ import("graphic_config.gni")
group("default") {
public_deps = [ ":graphic.rc" ]
public_deps += [ "etc:graphic_config" ]
if (graphic_2d_feature_bootanimation_enable) {
public_deps += [ "frameworks/bootanimation:bootanimation" ]

View File

@ -18,3 +18,10 @@ ohos_prebuilt_etc("ohos.para.dac") {
part_name = "graphic_2d"
module_install_dir = "etc/param"
}
ohos_prebuilt_etc("graphic_config") {
source = "graphic_config.xml"
relative_install_dir = "graphic"
part_name = "graphic_2d"
subsystem_name = "graphic"
}

20
etc/graphic_config.xml Normal file
View File

@ -0,0 +1,20 @@
<?xml version='1.0' encoding="utf-8"?>
<!--
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-->
<Configs>
<blurEffect>
<blurSwitchOpen enable="true"></blurSwitchOpen>
</blurEffect>
</Configs>

View File

@ -92,9 +92,11 @@ ohos_shared_library("librender_service") {
"core/pipeline/round_corner_display/rs_round_corner_display.cpp",
"core/pipeline/rs_base_render_engine.cpp",
"core/pipeline/rs_base_render_util.cpp",
"core/pipeline/rs_base_xml_config.cpp",
"core/pipeline/rs_composer_adapter.cpp",
"core/pipeline/rs_divided_render_util.cpp",
"core/pipeline/rs_draw_frame.cpp",
"core/pipeline/rs_graphic_config.cpp",
"core/pipeline/rs_hardware_thread.cpp",
"core/pipeline/rs_main_thread.cpp",
"core/pipeline/rs_physical_screen_processor.cpp",
@ -287,6 +289,7 @@ ohos_shared_library("librender_service") {
external_deps = [
"c_utils:utils",
"config_policy:configpolicy_util",
"drivers_interface_display:libdisplay_commontype_proxy_1.0",
"eventhandler:libeventhandler",
"ffrt:libffrt",

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "rs_base_xml_config.h"
namespace OHOS {
namespace Rosen {
std::recursive_mutex RSBaseXmlConfig::configItemMutex;
const RSBaseXmlConfig::ConfigItem RSBaseXmlConfig::ConfigItem::defaultItem;
} // namespace Rosen
} // namespace OHOS

View File

@ -0,0 +1,262 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef RS_CORE_PIPELINE_BASE_XML_CONFIG_H
#define RS_CORE_PIPELINE_BASE_XML_CONFIG_H
#include <map>
#include <mutex>
#include <string>
#include <vector>
namespace OHOS {
namespace Rosen {
class RSBaseXmlConfig {
public:
enum class ValueType {
UNDIFINED,
MAP,
BOOL,
STRING,
STRINGS,
INTS,
FLOATS,
POSITIVE_FLOATS,
};
struct ConfigItem {
std::map<std::string, ConfigItem>* property = nullptr;
ValueType type = ValueType::UNDIFINED;
union {
std::map<std::string, ConfigItem>* mapValue = nullptr;
bool boolValue;
std::string stringValue;
std::vector<int>* intsValue;
std::vector<float>* floatsValue;
std::vector<std::string>* stringsValue;
};
ConfigItem() {}
~ConfigItem()
{
Destroy();
};
void Destroy()
{
ClearValue();
if (property) {
delete property;
property = nullptr;
}
}
void ClearValue()
{
switch (type) {
case ValueType::MAP:
delete mapValue;
mapValue = nullptr;
break;
case ValueType::STRING:
stringValue.~basic_string();
break;
case ValueType::INTS:
delete intsValue;
intsValue = nullptr;
break;
case ValueType::FLOATS:
delete floatsValue;
floatsValue = nullptr;
break;
case ValueType::STRINGS:
delete stringsValue;
stringsValue = nullptr;
break;
default:
break;
}
}
ConfigItem(const ConfigItem& value)
{
*this = value;
}
ConfigItem& operator=(const ConfigItem& value)
{
Destroy();
switch (value.type) {
case ValueType::MAP:
mapValue = new std::map<std::string, ConfigItem>(*value.mapValue);
break;
case ValueType::BOOL:
boolValue = value.boolValue;
break;
case ValueType::STRING:
new(&stringValue)std::string(value.stringValue);
break;
case ValueType::INTS:
intsValue = new std::vector<int>(*value.intsValue);
break;
case ValueType::FLOATS:
floatsValue = new std::vector<float>(*value.floatsValue);
break;
case ValueType::STRINGS:
stringsValue = new std::vector<std::string>(*value.stringsValue);
break;
default:
break;
}
type = value.type;
if (value.property) {
property = new std::map<std::string, ConfigItem>(*value.property);
}
return *this;
}
ConfigItem(ConfigItem&& value) noexcept
{
*this = std::move(value);
}
ConfigItem& operator=(ConfigItem&& value) noexcept
{
Destroy();
switch (value.type) {
case ValueType::MAP:
mapValue = value.mapValue;
value.mapValue = nullptr;
break;
case ValueType::BOOL:
boolValue = value.boolValue;
break;
case ValueType::STRING:
new(&stringValue)std::string(std::move(value.stringValue));
break;
case ValueType::INTS:
intsValue = value.intsValue;
value.intsValue = nullptr;
break;
case ValueType::FLOATS:
floatsValue = value.floatsValue;
value.floatsValue = nullptr;
break;
case ValueType::STRINGS:
stringsValue = value.stringsValue;
value.stringsValue = nullptr;
break;
default:
break;
}
type = value.type;
property = value.property;
value.type = ValueType::UNDIFINED;
value.property = nullptr;
return *this;
}
void SetProperty(const std::map<std::string, ConfigItem>& prop)
{
if (property) {
delete property;
}
property = new std::map<std::string, ConfigItem>(prop);
}
// set map value
void SetValue(const std::map<std::string, ConfigItem>& value)
{
ClearValue();
type = ValueType::MAP;
mapValue = new std::map<std::string, ConfigItem>(value);
}
// set bool value
void SetValue(bool value)
{
ClearValue();
type = ValueType::BOOL;
boolValue = value;
}
// set string value
void SetValue(const std::string& value)
{
ClearValue();
type = ValueType::STRING;
new(&stringValue)std::string(value);
}
// set ints value
void SetValue(const std::vector<int>& value)
{
ClearValue();
type = ValueType::INTS;
intsValue = new std::vector<int>(value);
}
// set floats value
void SetValue(const std::vector<float>& value)
{
ClearValue();
type = ValueType::FLOATS;
floatsValue = new std::vector<float>(value);
}
// set strings value
void SetValue(const std::vector<std::string>& value)
{
ClearValue();
type = ValueType::STRINGS;
stringsValue = new std::vector<std::string>(value);
}
bool IsInts() const
{
return type == ValueType::INTS;
}
bool IsFloats() const
{
return type == ValueType::FLOATS;
}
bool IsString() const
{
return type == ValueType::STRING;
}
bool IsStrings() const
{
return type == ValueType::STRINGS;
}
bool IsBool() const
{
return type == ValueType::BOOL;
}
bool IsMap() const
{
return type == ValueType::MAP;
}
const ConfigItem& operator[](const std::string& key) const
{
if (type != ValueType::MAP) {
return defaultItem;
}
if (mapValue->count(key) == 0) {
return defaultItem;
}
return mapValue->at(key);
}
const ConfigItem& GetProp(const std::string& key) const
{
if (!property) {
return defaultItem;
}
if (property->count(key) == 0) {
return defaultItem;
}
return property->at(key);
}
static const ConfigItem defaultItem;
};
static std::recursive_mutex configItemMutex;
};
} // namespace Rosen
} // namespace OHOS
#endif // RS_CORE_PIPELINE_BASE_XML_CONFIG_H

View File

@ -0,0 +1,318 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "rs_graphic_config.h"
#include "config_policy_utils.h"
#include "platform/common/rs_log.h"
namespace OHOS {
namespace Rosen {
RSGraphicConfig::ConfigItem RSGraphicConfig::config_;
const std::map<std::string, RSGraphicConfig::ValueType> RSGraphicConfig::configItemTypeMap_ = {
{ "blurEffect", RSGraphicConfig::ValueType::MAP },
{ "blurSwitchOpen", RSGraphicConfig::ValueType::UNDIFINED },
};
static inline bool IsNumber(std::string str)
{
if (str.size() == 0) {
return false;
}
for (int32_t i = 0; i < static_cast<int32_t>(str.size()); i++) {
if (str.at(i) < '0' || str.at(i) > '9') {
return false;
}
}
return true;
}
static bool IsFloatingNumber(std::string str, bool allowNeg = false)
{
if (str.size() == 0) {
return false;
}
int32_t i = 0;
if (allowNeg && str.at(i) == '-') {
i++;
}
for (; i < static_cast<int32_t>(str.size()); i++) {
if ((str.at(i) < '0' || str.at(i) > '9') &&
(str.at(i) != '.' || std::count(str.begin(), str.end(), '.') > 1)) {
return false;
}
}
return true;
}
static std::vector<std::string> Split(std::string str, std::string pattern)
{
if (str.empty() || pattern.empty()) {
return {};
}
int32_t position;
std::vector<std::string> result;
str += pattern;
int32_t strLen = static_cast<int32_t>(str.size());
int32_t patternLen = static_cast<int32_t>(pattern.size());
for (int32_t i = 0; i < strLen; i = position + patternLen) {
position = static_cast<int32_t>(str.find(pattern, i));
if (position >= strLen || position < 0) {
break;
}
std::string tmp = str.substr(i, position - i);
result.push_back(tmp);
}
return result;
}
std::vector<std::string> RSGraphicConfig::SplitNodeContent(const xmlNodePtr& node, const std::string& pattern)
{
xmlChar* content = xmlNodeGetContent(node);
if (content == nullptr) {
RS_LOGE("[GraphicConfig] read xml node error: nodeName:(%{public}s)", node->name);
return std::vector<std::string>();
}
std::string contentStr = reinterpret_cast<const char*>(content);
xmlFree(content);
if (contentStr.size() == 0) {
return std::vector<std::string>();
}
return Split(contentStr, pattern);
}
std::string RSGraphicConfig::GetConfigPath(const std::string& configFileName)
{
char buf[PATH_MAX];
char* configPath = GetOneCfgFile(configFileName.c_str(), buf, PATH_MAX);
char tmpPath[PATH_MAX] = { 0 };
if (!configPath || strlen(configPath) == 0 || strlen(configPath) >= PATH_MAX || !realpath(configPath, tmpPath)) {
RS_LOGI("[GraphicConfig] can not get customization config file");
return "/system/" + configFileName;
}
return std::string(tmpPath);
}
void RSGraphicConfig::ReadConfig(const xmlNodePtr& rootPtr, std::map<std::string, ConfigItem>& mapValue)
{
for (xmlNodePtr curNodePtr = rootPtr->xmlChildrenNode; curNodePtr != nullptr; curNodePtr = curNodePtr->next) {
if (!IsValidNode(*curNodePtr)) {
RS_LOGE("[GraphicConfig]: invalid node!");
continue;
}
std::string nodeName = reinterpret_cast<const char*>(curNodePtr->name);
if (configItemTypeMap_.count(nodeName)) {
std::map<std::string, ConfigItem> property = ReadProperty(curNodePtr);
if (property.size() > 0) {
mapValue[reinterpret_cast<const char*>(curNodePtr->name)].SetProperty(property);
}
switch (configItemTypeMap_.at(nodeName)) {
case ValueType::INTS: {
std::vector<int> v = ReadIntNumbersConfigInfo(curNodePtr);
mapValue[reinterpret_cast<const char*>(curNodePtr->name)].SetValue(v);
break;
}
case ValueType::FLOATS: {
std::vector<float> v = ReadFloatNumbersConfigInfo(curNodePtr, true);
mapValue[reinterpret_cast<const char*>(curNodePtr->name)].SetValue(v);
break;
}
case ValueType::POSITIVE_FLOATS: {
std::vector<float> v = ReadFloatNumbersConfigInfo(curNodePtr, false);
mapValue[reinterpret_cast<const char*>(curNodePtr->name)].SetValue(v);
break;
}
case ValueType::STRING: {
std::string v = ReadStringConfigInfo(curNodePtr);
mapValue[reinterpret_cast<const char*>(curNodePtr->name)].SetValue(v);
break;
}
case ValueType::STRINGS: {
std::vector<std::string> v = ReadStringsConfigInfo(curNodePtr);
mapValue[reinterpret_cast<const char*>(curNodePtr->name)].SetValue(v);
break;
}
case ValueType::MAP: {
std::map<std::string, ConfigItem> v;
ReadConfig(curNodePtr, v);
mapValue[reinterpret_cast<const char*>(curNodePtr->name)].SetValue(v);
break;
}
default:
break;
}
}
}
}
bool RSGraphicConfig::LoadConfigXml()
{
auto configFilePath = GetConfigPath("etc/graphic/graphic_config.xml");
xmlDocPtr docPtr = nullptr;
{
std::lock_guard<std::recursive_mutex> lock(configItemMutex);
docPtr = xmlReadFile(configFilePath.c_str(), nullptr, XML_PARSE_NOBLANKS);
}
RS_LOGI("[GraphicConfig] filePath: %{public}s", configFilePath.c_str());
if (docPtr == nullptr) {
RS_LOGE("[GraphicConfig] load xml error!");
return false;
}
xmlNodePtr rootPtr = xmlDocGetRootElement(docPtr);
if (rootPtr == nullptr || rootPtr->name == nullptr ||
xmlStrcmp(rootPtr->name, reinterpret_cast<const xmlChar*>("Configs"))) {
RS_LOGE("[GraphicConfig] get root element failed!");
xmlFreeDoc(docPtr);
return false;
}
std::map<std::string, ConfigItem> configMap;
config_.SetValue(configMap);
ReadConfig(rootPtr, *config_.mapValue);
xmlFreeDoc(docPtr);
return true;
}
bool RSGraphicConfig::IsValidNode(const xmlNode& currNode)
{
if (currNode.name == nullptr || currNode.type == XML_COMMENT_NODE) {
return false;
}
return true;
}
std::map<std::string, RSBaseXmlConfig::ConfigItem> RSGraphicConfig::ReadProperty(const xmlNodePtr& currNode)
{
std::map<std::string, ConfigItem> property;
xmlChar* propVal = xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("enable"));
if (propVal != nullptr) {
if (!xmlStrcmp(propVal, reinterpret_cast<const xmlChar*>("true"))) {
property["enable"].SetValue(true);
} else if (!xmlStrcmp(propVal, reinterpret_cast<const xmlChar*>("false"))) {
property["enable"].SetValue(false);
}
xmlFree(propVal);
}
propVal = xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("name"));
if (propVal != nullptr) {
property["name"].SetValue(std::string(reinterpret_cast<const char*>(propVal)));
xmlFree(propVal);
}
return property;
}
std::vector<int> RSGraphicConfig::ReadIntNumbersConfigInfo(const xmlNodePtr& currNode)
{
std::vector<int> intsValue;
auto numbers = SplitNodeContent(currNode);
for (auto& num : numbers) {
if (!IsNumber(num)) {
RS_LOGE("[GraphicConfig] read int number error: nodeName:(%{public}s)", currNode->name);
return {};
}
intsValue.push_back(std::stoi(num));
}
return intsValue;
}
std::vector<std::string> RSGraphicConfig::ReadStringsConfigInfo(const xmlNodePtr& currNode)
{
return SplitNodeContent(currNode);
}
std::vector<float> RSGraphicConfig::ReadFloatNumbersConfigInfo(const xmlNodePtr& currNode, bool allowNeg)
{
std::vector<float> floatsValue;
auto numbers = SplitNodeContent(currNode);
for (auto& num : numbers) {
if (!IsFloatingNumber(num, allowNeg)) {
RS_LOGE("[GraphicConfig] read float number error: nodeName:(%{public}s)", currNode->name);
return {};
}
floatsValue.push_back(std::stof(num));
}
return floatsValue;
}
std::string RSGraphicConfig::ReadStringConfigInfo(const xmlNodePtr& currNode)
{
std::string stringValue;
xmlChar* context = xmlNodeGetContent(currNode);
if (context == nullptr) {
RS_LOGE("[GraphicConfig] read xml node error: nodeName:(%{public}s)", currNode->name);
return {};
}
stringValue = std::string(reinterpret_cast<const char*>(context));
xmlFree(context);
return stringValue;
}
void RSGraphicConfig::DumpConfig(const std::map<std::string, ConfigItem>& config)
{
for (auto& conf : config) {
RS_LOGI("[GraphicConfig] %{public}s", conf.first.c_str());
std::map<std::string, ConfigItem> propMap;
if (conf.second.property) {
propMap = *conf.second.property;
}
for (auto prop : propMap) {
switch (prop.second.type) {
case ValueType::BOOL:
RS_LOGI("[GraphicConfig] Prop: %{public}s %{public}u", prop.first.c_str(), prop.second.boolValue);
break;
case ValueType::STRING:
RS_LOGI("[GraphicConfig] Prop: %{public}s %{public}s", prop.first.c_str(),
prop.second.stringValue.c_str());
break;
default:
break;
}
}
switch (conf.second.type) {
case ValueType::INTS:
for (auto& num : *conf.second.intsValue) {
RS_LOGI("[GraphicConfig] Num: %{public}d", num);
}
break;
case ValueType::MAP:
if (conf.second.mapValue) {
DumpConfig(*conf.second.mapValue);
}
break;
case ValueType::STRING:
RS_LOGI("[GraphicConfig] %{public}s", conf.second.stringValue.c_str());
break;
case ValueType::BOOL:
RS_LOGI("[GraphicConfig] %{public}u", conf.second.boolValue);
break;
case ValueType::FLOATS:
for (auto& num : *conf.second.floatsValue) {
RS_LOGI("[GraphicConfig] Num: %{public}f", num);
}
break;
default:
break;
}
}
}
} // namespace Rosen
} // namespace OHOS

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef RS_CORE_PIPELINE_GRAPHIC_CONFIG_H
#define RS_CORE_PIPELINE_GRAPHIC_CONFIG_H
#include <refbase.h>
#include "rs_base_xml_config.h"
#include "libxml/parser.h"
#include "libxml/tree.h"
namespace OHOS {
namespace Rosen {
class RSGraphicConfig : public RefBase, public RSBaseXmlConfig {
public:
RSGraphicConfig() = delete;
~RSGraphicConfig() = default;
static bool LoadConfigXml();
static const ConfigItem& GetConfig()
{
return config_;
}
static void DumpConfig(const std::map<std::string, ConfigItem>& config);
private:
static ConfigItem config_;
static const std::map<std::string, ValueType> configItemTypeMap_;
static bool IsValidNode(const xmlNode& currNode);
static std::map<std::string, ConfigItem> ReadProperty(const xmlNodePtr& currNode);
static std::vector<int> ReadIntNumbersConfigInfo(const xmlNodePtr& currNode);
static std::vector<std::string> ReadStringsConfigInfo(const xmlNodePtr& currNode);
static std::vector<float> ReadFloatNumbersConfigInfo(const xmlNodePtr& currNode, bool allowNeg);
static std::string ReadStringConfigInfo(const xmlNodePtr& currNode);
static void ReadConfig(const xmlNodePtr& rootPtr, std::map<std::string, ConfigItem>& mapValue);
static std::string GetConfigPath(const std::string& configFileName);
static std::vector<std::string> SplitNodeContent(const xmlNodePtr& node, const std::string& pattern = " ");
};
} // namespace Rosen
} // namespace OHOS
#endif // RS_CORE_PIPELINE_GRAPHIC_CONFIG_H

View File

@ -418,6 +418,13 @@ void RSMainThread::Init()
};
Drawing::DrawOpItem::SetTypefaceQueryCallBack(customTypefaceQueryfunc);
if (RSGraphicConfig::LoadConfigXml()) {
if (RSGraphicConfig::GetConfig().IsMap()) {
RSGraphicConfig::DumpConfig(*RSGraphicConfig::GetConfig().mapValue);
}
ConfigureRenderService();
}
isUniRender_ = RSUniRenderJudgement::IsUniRender();
SetDeviceType();
qosPidCal_ = deviceType_ == DeviceType::PC;
@ -4040,5 +4047,23 @@ void RSMainThread::SetHardwareTaskNum(uint32_t num)
{
rsVSyncDistributor_->SetHardwareTaskNum(num);
}
void RSMainThread::ConfigureRenderService()
{
const auto& config = RSGraphicConfig::GetConfig();
RSGraphicConfig::ConfigItem item = config["blurEffect"];
if (item.IsMap()) {
auto subItem = item["blurSwitchOpen"].GetProp("enable");
if (subItem.IsBool()) {
isBlurSwitchOpen_ = subItem.boolValue;
RS_LOGI("RSMainThread::ConfigureRenderService isBlurSwitchOpen_:%{public}d", isBlurSwitchOpen_);
}
}
}
bool RSMainThread::IsBlurSwitchOpen() const
{
return isBlurSwitchOpen_;
}
} // namespace Rosen
} // namespace OHOS

View File

@ -44,6 +44,7 @@
#include "params/rs_render_thread_params.h"
#include "pipeline/rs_context.h"
#include "pipeline/rs_draw_frame.h"
#include "pipeline/rs_graphic_config.h"
#include "pipeline/rs_uni_render_judgement.h"
#include "platform/common/rs_event_manager.h"
#include "platform/drawing/rs_vsync_client.h"
@ -341,6 +342,8 @@ public:
void SetAncoForceDoDirect(bool direct);
bool IsBlurSwitchOpen() const;
bool IsSystemAnimatedScenesListEmpty() const
{
return systemAnimatedScenesList_.empty();
@ -469,6 +472,7 @@ private:
void PrepareUiCaptureTasks(std::shared_ptr<RSUniRenderVisitor> uniVisitor);
void UIExtensionNodesTraverseAndCallback();
bool CheckUIExtensionCallbackDataChanged() const;
void ConfigureRenderService();
std::shared_ptr<AppExecFwk::EventRunner> runner_ = nullptr;
std::shared_ptr<AppExecFwk::EventHandler> handler_ = nullptr;
@ -683,6 +687,9 @@ private:
bool isPartialRenderEnabledOfLastFrame_ = false;
bool isRegionDebugEnabledOfLastFrame_ = false;
bool initUiFwkTable_ = false;
// graphic config
bool isBlurSwitchOpen_ = true;
};
} // namespace OHOS::Rosen
#endif // RS_MAIN_THREAD

View File

@ -25,6 +25,7 @@ group("unittest") {
":RSComposerAdapterTest",
":RSDividedRenderUtilTest",
":RSDropFrameProcessorTest",
":RSGraphic_Config_Test",
":RSHardwareThreadTest",
":RSMainThreadTest",
":RSPhysicalScreenProcessorTest",
@ -1209,6 +1210,20 @@ ohos_unittest("RSPointerRenderManagerTest") {
}
}
## Build RSGraphic_Config_Test
ohos_unittest("RSGraphic_Config_Test") {
module_out_path = module_output_path
sources = [ "rs_graphic_config_test.cpp" ]
deps = [ ":rs_test_common" ]
external_deps = [
"c_utils:utils",
"hilog:libhilog",
]
if (defined(global_parts_info) && defined(global_parts_info.sensors_sensor)) {
external_deps += [ "sensor:sensor_interface_native" ]
}
}
## Build rs_test_common.a {{{
config("rs_test_common_public_config") {
include_dirs = [

View File

@ -0,0 +1,300 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include "pipeline/rs_main_thread.h"
using namespace testing;
using namespace testing::ext;
namespace OHOS {
namespace Rosen {
using ConfigItem = RSGraphicConfig::ConfigItem;
const std::string XML_STR = R"(<?xml version='1.0' encoding="utf-8"?>
<Configs>
<testMap>
<testBooL enable="true"></testBooL>
</testMap>
<testString>testString</testString>
<testStrings>testStrings1 testStrings2 testStrings3</testStrings>
<testInts>1 2 3</testInts>
<testFloats>0.1 0.2 -0.3</testFloats>
<testPositiveFloats>0.1 0.2 0.3</testPositiveFloats>
<testInvalidPositiveFloats>0.1 0.2 -0.3</testInvalidPositiveFloats>
<testUndifined></testUndifined>
</Configs>
)";
const std::string XML_INVALID_INPUT_STR = R"(<?xml version='1.0' encoding="utf-8"?>
<Configs>
<testMap>
<testBooL></testBooL>
</testMap>
<testString></testString>
<testStrings></testStrings>
<testInts>a b c</testInts>
<testFloats>a b c</testFloats>
<testPositiveFloats>a b c</testPositiveFloats>
</Configs>
)";
class RSGraphicConfigTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp() override;
void TearDown() override;
ConfigItem ReadConfig(const std::string& xmlStr);
};
void RSGraphicConfigTest::SetUpTestCase() {}
void RSGraphicConfigTest::TearDownTestCase() {}
void RSGraphicConfigTest::SetUp() {}
void RSGraphicConfigTest::TearDown() {}
void SetConfigMap(std::map<std::string, RSGraphicConfig::ValueType>* nonConstConfigMap)
{
*nonConstConfigMap = {
{ "testMap", RSGraphicConfig::ValueType::MAP },
{ "testBooL", RSGraphicConfig::ValueType::UNDIFINED },
{ "testString", RSGraphicConfig::ValueType::STRING },
{ "testStrings", RSGraphicConfig::ValueType::STRINGS },
{ "testInts", RSGraphicConfig::ValueType::INTS },
{ "testFloats", RSGraphicConfig::ValueType::FLOATS },
{ "testPositiveFloats", RSGraphicConfig::ValueType::POSITIVE_FLOATS },
{ "testInvalidPositiveFloats", RSGraphicConfig::ValueType::POSITIVE_FLOATS },
{ "testUndifined", RSGraphicConfig::ValueType::UNDIFINED },
};
}
void ResetConfigMap(std::map<std::string, RSGraphicConfig::ValueType>* nonConstConfigMap)
{
*nonConstConfigMap = {
{ "blurEffect", RSGraphicConfig::ValueType::MAP },
{ "blurSwitchOpen", RSGraphicConfig::ValueType::UNDIFINED },
};
}
ConfigItem RSGraphicConfigTest::ReadConfig(const std::string& xmlStr)
{
ConfigItem config;
xmlDocPtr docPtr = xmlParseMemory(xmlStr.c_str(), xmlStr.length() + 1);
if (docPtr == nullptr) {
return config;
}
xmlNodePtr rootPtr = xmlDocGetRootElement(docPtr);
if (rootPtr == nullptr || rootPtr->name == nullptr ||
xmlStrcmp(rootPtr->name, reinterpret_cast<const xmlChar*>("Configs"))) {
xmlFreeDoc(docPtr);
return config;
}
std::map<std::string, ConfigItem> configMap;
config.SetValue(configMap);
RSGraphicConfig::ReadConfig(rootPtr, *config.mapValue);
xmlFreeDoc(docPtr);
return config;
}
namespace {
/* *
* @tc.name: LoadConfigXml
* @tc.desc: test LoadConfigXml.
* @tc.type: FUNC
*/
HWTEST_F(RSGraphicConfigTest, LoadConfigXml, TestSize.Level2)
{
ASSERT_TRUE(RSGraphicConfig::LoadConfigXml());
}
/* *
* @tc.name: ReadConfig
* @tc.desc: test ReadConfig.
* @tc.type: FUNC
*/
HWTEST_F(RSGraphicConfigTest, ReadConfig, TestSize.Level2)
{
auto nonConstConfigMap =
const_cast<std::map<std::string, RSGraphicConfig::ValueType>*>(&RSGraphicConfig::configItemTypeMap_);
SetConfigMap(nonConstConfigMap);
RSGraphicConfig::config_ = ReadConfig(XML_STR);
RSGraphicConfig::ConfigItem item = RSGraphicConfig::config_["testMap"];
ASSERT_TRUE(item.IsMap());
item = RSGraphicConfig::config_["testMap"]["testBooL"].GetProp("enable");
ASSERT_TRUE(item.IsBool());
ASSERT_TRUE(item.boolValue);
item = RSGraphicConfig::config_["testString"];
ASSERT_TRUE(item.IsString());
ASSERT_EQ("testString", item.stringValue);
item = RSGraphicConfig::config_["testStrings"];
ASSERT_TRUE(item.IsStrings());
ASSERT_TRUE(item.stringsValue->size() == 3);
auto stringValues = *item.stringsValue;
ASSERT_EQ("testStrings1", stringValues[0]);
ASSERT_EQ("testStrings2", stringValues[1]);
ASSERT_EQ("testStrings3", stringValues[2]);
item = RSGraphicConfig::config_["testInts"];
ASSERT_TRUE(item.IsInts());
ASSERT_TRUE(item.intsValue->size() == 3);
auto intValues = *item.intsValue;
ASSERT_EQ(1, intValues[0]);
ASSERT_EQ(2, intValues[1]);
ASSERT_EQ(3, intValues[2]);
item = RSGraphicConfig::config_["testFloats"];
ASSERT_TRUE(item.IsFloats());
ASSERT_TRUE(item.floatsValue->size() == 3);
auto floatValues = *item.floatsValue;
ASSERT_TRUE(std::abs(0.1 - floatValues[0]) < std::numeric_limits<float>::epsilon());
ASSERT_TRUE(std::abs(0.2 - floatValues[1]) < std::numeric_limits<float>::epsilon());
ASSERT_TRUE(std::abs(-0.3 - floatValues[2]) < std::numeric_limits<float>::epsilon());
item = RSGraphicConfig::config_["testPositiveFloats"];
ASSERT_TRUE(item.IsFloats());
ASSERT_TRUE(item.floatsValue->size() == 3);
floatValues = *item.floatsValue;
ASSERT_TRUE(std::abs(0.1 - floatValues[0]) < std::numeric_limits<float>::epsilon());
ASSERT_TRUE(std::abs(0.2 - floatValues[1]) < std::numeric_limits<float>::epsilon());
ASSERT_TRUE(std::abs(0.3 - floatValues[2]) < std::numeric_limits<float>::epsilon());
item = RSGraphicConfig::config_["testInvalidPositiveFloats"];
ASSERT_TRUE(item.IsFloats());
ASSERT_TRUE(item.floatsValue->size() == 0);
item = RSGraphicConfig::config_["testUndifined"];
ASSERT_TRUE(item.type == RSBaseXmlConfig::ValueType::UNDIFINED);
ResetConfigMap(nonConstConfigMap);
}
/* *
* @tc.name: ReadConfig1
* @tc.desc: test ReadConfig invalid value input.
* @tc.type: FUNC
*/
HWTEST_F(RSGraphicConfigTest, ReadConfig1, TestSize.Level2)
{
auto nonConstConfigMap =
const_cast<std::map<std::string, RSGraphicConfig::ValueType>*>(&RSGraphicConfig::configItemTypeMap_);
SetConfigMap(nonConstConfigMap);
RSGraphicConfig::config_ = ReadConfig(XML_INVALID_INPUT_STR);
RSGraphicConfig::ConfigItem item = RSGraphicConfig::config_["testMap"];
ASSERT_TRUE(item.IsMap());
item = RSGraphicConfig::config_["testMap"]["testBooL"].GetProp("enable");
ASSERT_FALSE(item.IsBool());
item = RSGraphicConfig::config_["testString"];
ASSERT_TRUE(item.IsString());
ASSERT_EQ("", item.stringValue);
item = RSGraphicConfig::config_["testStrings"];
ASSERT_TRUE(item.IsStrings());
ASSERT_TRUE(item.stringsValue->size() == 0);
item = RSGraphicConfig::config_["testInts"];
ASSERT_TRUE(item.IsInts());
ASSERT_TRUE(item.intsValue->size() == 0);
item = RSGraphicConfig::config_["testFloats"];
ASSERT_TRUE(item.IsFloats());
ASSERT_TRUE(item.floatsValue->size() == 0);
item = RSGraphicConfig::config_["testPositiveFloats"];
ASSERT_TRUE(item.IsFloats());
ASSERT_TRUE(item.floatsValue->size() == 0);
ResetConfigMap(nonConstConfigMap);
}
/* *
* @tc.name: DumpConfig
* @tc.desc: test DumpConfig.
* @tc.type: FUNC
*/
HWTEST_F(RSGraphicConfigTest, DumpConfig, TestSize.Level2)
{
std::string xmlStr = "<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<blurEffect>"
"<blurSwitchOpen enable=\"true\"></blurSwitchOpen>"
"</blurEffect>"
"</Configs>";
RSGraphicConfig::config_ = ReadConfig(xmlStr);
RSGraphicConfig::DumpConfig(*RSGraphicConfig::GetConfig().mapValue);
}
/* *
* @tc.name: ReadProperty
* @tc.desc: test ReadProperty name and enable.
* @tc.type: FUNC
*/
HWTEST_F(RSGraphicConfigTest, ReadProperty, TestSize.Level2)
{
std::string xmlStr = "<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<blurEffect>"
"<blurSwitchOpen name=\"testName\" enable=\"true\"></blurSwitchOpen>"
"</blurEffect>"
"</Configs>";
RSGraphicConfig::config_ = ReadConfig(xmlStr);
}
/* *
* @tc.name: BlurEffectConfig
* @tc.desc: set blurEffect.blurSwitchOpen true.
* @tc.type: FUNC
*/
HWTEST_F(RSGraphicConfigTest, BlurEffectConfig, TestSize.Level2)
{
std::string xmlStr = "<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<blurEffect>"
"<blurSwitchOpen enable=\"true\"></blurSwitchOpen>"
"</blurEffect>"
"</Configs>";
RSGraphicConfig::config_ = ReadConfig(xmlStr);
RSMainThread::Instance()->ConfigureRenderService();
ASSERT_TRUE(RSMainThread::Instance()->IsBlurSwitchOpen());
}
/* *
* @tc.name: BlurEffectConfig2
* @tc.desc: set blurEffect.blurSwitchOpen false.
* @tc.type: FUNC
*/
HWTEST_F(RSGraphicConfigTest, BlurEffectConfig2, TestSize.Level2)
{
std::string xmlStr = "<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<blurEffect>"
"<blurSwitchOpen enable=\"false\"></blurSwitchOpen>"
"</blurEffect>"
"</Configs>";
RSGraphicConfig::config_ = ReadConfig(xmlStr);
RSMainThread::Instance()->ConfigureRenderService();
ASSERT_FALSE(RSMainThread::Instance()->IsBlurSwitchOpen());
}
} // namespace
} // namespace Rosen
} // namespace OHOS

View File

@ -3660,4 +3660,18 @@ HWTEST_F(RSMainThreadTest, ResetAnimateNodeFlag, TestSize.Level2)
mainThread->context_ = nullptr;
mainThread->ResetAnimateNodeFlag();
}
/**
* @tc.name: ConfigureRenderService
* @tc.desc: test ConfigureRenderService before and after LoadConfigXml
* @tc.type: FUNC
*/
HWTEST_F(RSMainThreadTest, ConfigureRenderService, TestSize.Level2)
{
auto mainThread = RSMainThread::Instance();
ASSERT_NE(mainThread, nullptr);
mainThread->ConfigureRenderService();
ASSERT_TRUE(RSGraphicConfig::LoadConfigXml());
mainThread->ConfigureRenderService();
}
} // namespace OHOS::Rosen