1 /*
2 * Copyright (c) 2022 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 "render_data_configuration_loader.h"
17
18 #include <core/io/intf_file_manager.h>
19 #include <render/datastore/render_data_store_render_pods.h>
20 #include <render/namespace.h>
21
22 #include "json_util.h"
23 #include "util/log.h"
24
25 using namespace BASE_NS;
26 using namespace CORE_NS;
27
28 RENDER_BEGIN_NAMESPACE()
29 // clang-format off
30 RENDER_JSON_SERIALIZE_ENUM(TonemapConfiguration::TonemapType,
31 {
32 { 0x7FFFFFFF, nullptr },
33 { TonemapConfiguration::TonemapType::TONEMAP_ACES, "aces" },
34 { TonemapConfiguration::TonemapType::TONEMAP_ACES_2020, "aces_2020" },
35 { TonemapConfiguration::TonemapType::TONEMAP_FILMIC, "filmic" },
36 })
37 RENDER_JSON_SERIALIZE_ENUM(ColorConversionConfiguration::ConversionFunctionType,
38 {
39 { 0x7FFFFFFF, nullptr },
40 { ColorConversionConfiguration::ConversionFunctionType::CONVERSION_LINEAR, "linear" },
41 { ColorConversionConfiguration::ConversionFunctionType::CONVERSION_LINEAR_TO_SRGB, "linear_to_srgb" },
42 { ColorConversionConfiguration::ConversionFunctionType::CONVERSION_MULTIPLY_WITH_ALPHA, "multiply_with_alpha" },
43 })
44 RENDER_JSON_SERIALIZE_ENUM(DitherConfiguration::DitherType,
45 {
46 { 0x7FFFFFFF, nullptr },
47 { DitherConfiguration::DitherType::INTERLEAVED_NOISE, "interleaved_noise" },
48 { DitherConfiguration::DitherType::TRIANGLE_NOISE, "triangle_noise" },
49 { DitherConfiguration::DitherType::TRIANGLE_NOISE_RGB, "triangle_noise_rgb" },
50 })
51 RENDER_JSON_SERIALIZE_ENUM(BlurConfiguration::BlurQualityType,
52 {
53 { 0x7FFFFFFF, nullptr },
54 { BlurConfiguration::BlurQualityType::QUALITY_TYPE_LOW, "low" },
55 { BlurConfiguration::BlurQualityType::QUALITY_TYPE_NORMAL, "normal" },
56 { BlurConfiguration::BlurQualityType::QUALITY_TYPE_HIGH, "high" },
57 })
58 RENDER_JSON_SERIALIZE_ENUM(BlurConfiguration::BlurType,
59 {
60 { 0x7FFFFFFF, nullptr },
61 { BlurConfiguration::BlurType::TYPE_NORMAL, "normal" },
62 { BlurConfiguration::BlurType::TYPE_HORIZONTAL, "horizontal" },
63 { BlurConfiguration::BlurType::TYPE_VERTICAL, "vertical" },
64 })
65 RENDER_JSON_SERIALIZE_ENUM(BloomConfiguration::BloomQualityType,
66 {
67 { 0x7FFFFFFF, nullptr },
68 { BloomConfiguration::BloomQualityType::QUALITY_TYPE_LOW, "low" },
69 { BloomConfiguration::BloomQualityType::QUALITY_TYPE_NORMAL, "normal" },
70 { BloomConfiguration::BloomQualityType::QUALITY_TYPE_HIGH, "high" },
71 })
72 RENDER_JSON_SERIALIZE_ENUM(BloomConfiguration::BloomType,
73 {
74 { 0x7FFFFFFF, nullptr },
75 { BloomConfiguration::BloomType::TYPE_NORMAL, "normal" },
76 { BloomConfiguration::BloomType::TYPE_HORIZONTAL, "horizontal" },
77 { BloomConfiguration::BloomType::TYPE_VERTICAL, "vertical" },
78 { BloomConfiguration::BloomType::TYPE_BILATERAL, "bilateral" },
79 })
80 RENDER_JSON_SERIALIZE_ENUM(FxaaConfiguration::Sharpness,
81 {
82 { 0x7FFFFFFF, nullptr },
83 { FxaaConfiguration::Sharpness::SOFT, "soft" },
84 { FxaaConfiguration::Sharpness::MEDIUM, "medium" },
85 { FxaaConfiguration::Sharpness::SHARP, "sharp" },
86 })
87 RENDER_JSON_SERIALIZE_ENUM(FxaaConfiguration::Quality,
88 {
89 { 0x7FFFFFFF, nullptr },
90 { FxaaConfiguration::Quality::LOW, "low" },
91 { FxaaConfiguration::Quality::MEDIUM, "medium" },
92 { FxaaConfiguration::Quality::HIGH, "high" },
93 })
94 RENDER_JSON_SERIALIZE_ENUM(PostProcessConfiguration::PostProcessEnableFlagBits,
95 {
96 { 0x7FFFFFFF, nullptr },
97 { PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_TONEMAP_BIT, "tonemap" },
98 { PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_VIGNETTE_BIT, "vignette" },
99 { PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_DITHER_BIT, "dither" },
100 { PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_COLOR_CONVERSION_BIT, "color_conversion" },
101 { PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_COLOR_FRINGE_BIT, "color_fringe" },
102 { PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_BLUR_BIT, "blur" },
103 { PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_BLOOM_BIT, "bloom" },
104 { PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_FXAA_BIT, "fxaa" },
105 { PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_TAA_BIT, "taa" },
106 { PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_DOF_BIT, "dof" },
107 { PostProcessConfiguration::PostProcessEnableFlagBits::ENABLE_MOTION_BLUR_BIT, "motion_blur" },
108 })
109 // clang-format on
110 namespace {
LoadPostProcess(const json::value & jsonData)111 IRenderDataConfigurationLoader::LoadedPostProcess LoadPostProcess(const json::value& jsonData)
112 {
113 IRenderDataConfigurationLoader::LoadedPostProcess result;
114 auto& ppConfig = result.postProcessConfiguration;
115 auto& err = result.loadResult.error;
116
117 SafeGetJsonValue(jsonData, "name", err, result.name);
118 float version = 0.0f;
119 SafeGetJsonValue(jsonData, "version", err, version);
120 if (version < 1.0f) {
121 PLUGIN_LOG_W("version number should be 1.0 or higher for post process configuration json (version=%f name=%s)",
122 version, result.name.c_str());
123 }
124 if (err.empty()) {
125 if (const auto iter = jsonData.find("postProcessConfiguration"); iter) {
126 SafeGetJsonBitfield<PostProcessConfiguration::PostProcessEnableFlagBits>(
127 *iter, "enableFlags", err, ppConfig.enableFlags);
128
129 if (const auto cIter = iter->find("bloomConfiguration"); cIter) {
130 SafeGetJsonEnum(*cIter, "bloomType", err, ppConfig.bloomConfiguration.bloomType);
131 SafeGetJsonEnum(*cIter, "bloomQualityType", err, ppConfig.bloomConfiguration.bloomQualityType);
132 SafeGetJsonValue(*cIter, "thresholdHard", err, ppConfig.bloomConfiguration.thresholdHard);
133 SafeGetJsonValue(*cIter, "thresholdSoft", err, ppConfig.bloomConfiguration.thresholdSoft);
134 SafeGetJsonValue(*cIter, "amountCoefficient", err, ppConfig.bloomConfiguration.amountCoefficient);
135 SafeGetJsonValue(*cIter, "dirtMaskCoefficient", err, ppConfig.bloomConfiguration.dirtMaskCoefficient);
136 SafeGetJsonValue(*cIter, "scatter", err, ppConfig.bloomConfiguration.scatter);
137 SafeGetJsonValue(*cIter, "scaleFactor", err, ppConfig.bloomConfiguration.scaleFactor);
138 SafeGetJsonValue(*cIter, "useCompute", err, ppConfig.bloomConfiguration.useCompute);
139 // NOTE: dirt mask name should be added
140 }
141 if (const auto cIter = iter->find("vignetteConfiguration"); cIter) {
142 SafeGetJsonValue(*cIter, "coefficient", err, ppConfig.vignetteConfiguration.coefficient);
143 SafeGetJsonValue(*cIter, "power", err, ppConfig.vignetteConfiguration.power);
144 }
145 if (const auto cIter = iter->find("colorFringeConfiguration"); cIter) {
146 SafeGetJsonValue(
147 *cIter, "distanceCoefficient", err, ppConfig.colorFringeConfiguration.distanceCoefficient);
148 SafeGetJsonValue(*cIter, "coefficient", err, ppConfig.colorFringeConfiguration.coefficient);
149 }
150 if (const auto cIter = iter->find("tonemapConfiguration"); cIter) {
151 SafeGetJsonEnum(*cIter, "tonemapType", err, ppConfig.tonemapConfiguration.tonemapType);
152 SafeGetJsonValue(*cIter, "exposure", err, ppConfig.tonemapConfiguration.exposure);
153 }
154 if (const auto cIter = iter->find("ditherConfiguration"); cIter) {
155 SafeGetJsonEnum(*cIter, "ditherType", err, ppConfig.ditherConfiguration.ditherType);
156 }
157 if (const auto cIter = iter->find("blurConfiguration"); cIter) {
158 SafeGetJsonEnum(*cIter, "blurType", err, ppConfig.blurConfiguration.blurType);
159 SafeGetJsonEnum(*cIter, "blurQualityType", err, ppConfig.blurConfiguration.blurQualityType);
160 SafeGetJsonValue(*cIter, "filterSize", err, ppConfig.blurConfiguration.filterSize);
161 SafeGetJsonValue(*cIter, "maxMipLevel", err, ppConfig.blurConfiguration.maxMipLevel);
162 }
163 if (const auto cIter = iter->find("colorConversionConfiguration"); cIter) {
164 SafeGetJsonBitfield<ColorConversionConfiguration::ConversionFunctionType>(*cIter,
165 "conversionFunctionType", err, ppConfig.colorConversionConfiguration.conversionFunctionType);
166 }
167 if (const auto cIter = iter->find("FxaaConfiguration"); cIter) {
168 SafeGetJsonEnum(*cIter, "sharpness", err, ppConfig.fxaaConfiguration.sharpness);
169 SafeGetJsonEnum(*cIter, "quality", err, ppConfig.fxaaConfiguration.quality);
170 }
171 } else {
172 err += "postProcessConfiguration not found\n";
173 }
174 }
175 result.loadResult.success = err.empty();
176
177 return result;
178 }
LoadFromNullTerminated(const string_view jsonString)179 IRenderDataConfigurationLoader::LoadedPostProcess LoadFromNullTerminated(const string_view jsonString)
180 {
181 IRenderDataConfigurationLoader::LoadedPostProcess result;
182 const auto json = json::parse(jsonString.data());
183 if (json) {
184 result = RENDER_NS::LoadPostProcess(json);
185 } else {
186 result.loadResult.success = false;
187 result.loadResult.error = "Invalid json file.";
188 }
189
190 return result;
191 }
192 } // namespace
193
LoadPostProcess(const string_view jsonString)194 IRenderDataConfigurationLoader::LoadedPostProcess RenderDataConfigurationLoader::LoadPostProcess(
195 const string_view jsonString)
196 {
197 // make sure the input is zero terminated before parsing.
198 const auto asString = string(jsonString);
199 return LoadFromNullTerminated(asString);
200 }
201
LoadPostProcess(IFileManager & fileManager,const string_view uri)202 IRenderDataConfigurationLoader::LoadedPostProcess RenderDataConfigurationLoader::LoadPostProcess(
203 IFileManager& fileManager, const string_view uri)
204 {
205 IRenderDataConfigurationLoader::LoadedPostProcess result;
206
207 IFile::Ptr file = fileManager.OpenFile(uri);
208 if (!file) {
209 PLUGIN_LOG_E("Error loading '%s'", string(uri).c_str());
210 result.loadResult = IRenderDataConfigurationLoader::LoadResult("Failed to open file.");
211 return result;
212 }
213
214 const uint64_t byteLength = file->GetLength();
215
216 string raw;
217 raw.resize(static_cast<size_t>(byteLength));
218
219 if (file->Read(raw.data(), byteLength) != byteLength) {
220 PLUGIN_LOG_E("Error loading '%s'", string(uri).c_str());
221 result.loadResult = IRenderDataConfigurationLoader::LoadResult("Failed to read file.");
222 return result;
223 }
224 result = LoadFromNullTerminated(raw);
225 return result;
226 }
227
LoadPostProcess(const string_view jsonString)228 IRenderDataConfigurationLoader::LoadedPostProcess RenderDataConfigurationLoaderImpl::LoadPostProcess(
229 const string_view jsonString)
230 {
231 return RenderDataConfigurationLoader::LoadPostProcess(jsonString);
232 }
233
LoadPostProcess(IFileManager & fileManager,const string_view uri)234 IRenderDataConfigurationLoader::LoadedPostProcess RenderDataConfigurationLoaderImpl::LoadPostProcess(
235 IFileManager& fileManager, const string_view uri)
236 {
237 return RenderDataConfigurationLoader::LoadPostProcess(fileManager, uri);
238 }
239
GetInterface(const BASE_NS::Uid & uid) const240 const IInterface* RenderDataConfigurationLoaderImpl::GetInterface(const BASE_NS::Uid& uid) const
241 {
242 if ((uid == IRenderDataConfigurationLoader::UID) || (uid == IInterface::UID)) {
243 return this;
244 }
245 return nullptr;
246 }
247
GetInterface(const BASE_NS::Uid & uid)248 IInterface* RenderDataConfigurationLoaderImpl::GetInterface(const BASE_NS::Uid& uid)
249 {
250 if ((uid == IRenderDataConfigurationLoader::UID) || (uid == IInterface::UID)) {
251 return this;
252 }
253 return nullptr;
254 }
255
Ref()256 void RenderDataConfigurationLoaderImpl::Ref() {}
257
Unref()258 void RenderDataConfigurationLoaderImpl::Unref() {}
259 RENDER_END_NAMESPACE()
260