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 "render_data_store_post_process.h" 17 18 #include <cinttypes> 19 #include <cstdint> 20 21 #include <base/containers/fixed_string.h> 22 #include <base/math/matrix.h> 23 #include <render/datastore/render_data_store_render_pods.h> 24 #include <render/device/intf_shader_manager.h> 25 #include <render/intf_render_context.h> 26 27 #include "datastore/render_data_store_manager.h" 28 #include "datastore/render_data_store_pod.h" 29 #include "loader/json_util.h" 30 #include "util/log.h" 31 32 using namespace BASE_NS; 33 using namespace CORE_NS; 34 35 RENDER_BEGIN_NAMESPACE() 36 namespace { 37 constexpr string_view RENDER_DATA_STORE_POST_PROCESS_TYPE_NAME { RenderDataStorePostProcess::TYPE_NAME }; 38 constexpr string_view RENDER_DATA_STORE_POD_NAME { RenderDataStorePod::TYPE_NAME }; 39 40 constexpr string_view CUSTOM_PROPERTIES = "customProperties"; 41 constexpr string_view GLOBAL_FACTOR = "globalFactor"; 42 constexpr string_view CUSTOM_PROPERTY_DATA = "data"; 43 44 constexpr uint32_t SIZE_OF_FLOAT { sizeof(float) }; 45 constexpr uint32_t SIZE_OF_VEC2 { sizeof(Math::Vec2) }; 46 constexpr uint32_t SIZE_OF_VEC3 { sizeof(Math::Vec3) }; 47 constexpr uint32_t SIZE_OF_VEC4 { sizeof(Math::Vec4) }; 48 constexpr uint32_t SIZE_OF_MAT3X3 { sizeof(Math::Mat3X3) }; 49 constexpr uint32_t SIZE_OF_MAT4X4 { sizeof(Math::Mat4X4) }; 50 51 constexpr uint32_t ALIGNMENT_OF_FLOAT { sizeof(float) }; 52 constexpr uint32_t ALIGNMENT_OF_VEC2 { sizeof(float) * 2U }; 53 constexpr uint32_t ALIGNMENT_OF_VEC3 { sizeof(float) * 4U }; 54 constexpr uint32_t ALIGNMENT_OF_VEC4 { sizeof(float) * 4U }; 55 constexpr uint32_t ALIGNMENT_OF_MAT3X3 { sizeof(float) * 4U * 3U }; 56 constexpr uint32_t ALIGNMENT_OF_MAT4X4 { sizeof(float) * 4U * 4U }; 57 58 constexpr uint32_t MAX_LOCAL_DATA_BYTE_SIZE { PostProcessConstants::USER_LOCAL_FACTOR_BYTE_SIZE }; 59 constexpr uint32_t MAX_GLOBAL_FACTOR_BYTE_SIZE { sizeof(Math::Vec4) }; 60 61 constexpr string_view TAA_SHADER_NAME { "rendershaders://shader/fullscreen_taa.shader" }; 62 constexpr string_view FXAA_SHADER_NAME { "rendershaders://shader/fullscreen_fxaa.shader" }; 63 constexpr string_view DOF_SHADER_NAME { "rendershaders://shader/depth_of_field.shader" }; 64 constexpr string_view MB_SHADER_NAME { "rendershaders://shader/fullscreen_motion_blur.shader" }; 65 GetAlignment(uint32_t value,uint32_t align)66 inline constexpr uint32_t GetAlignment(uint32_t value, uint32_t align) 67 { 68 if (align == 0) { 69 return value; 70 } else { 71 return ((value + align - 1U) / align) * align; 72 } 73 } 74 AppendValues(const uint32_t maxByteSize,const string_view type,const json::value * value,uint32_t & offset,uint8_t * data)75 void AppendValues( 76 const uint32_t maxByteSize, const string_view type, const json::value* value, uint32_t& offset, uint8_t* data) 77 { 78 if (type == "vec4") { 79 if ((offset + ALIGNMENT_OF_VEC4) <= maxByteSize) { 80 Math::Vec4* val = reinterpret_cast<Math::Vec4*>(data + offset); 81 FromJson(*value, *val); 82 offset = GetAlignment(offset + SIZE_OF_VEC4, ALIGNMENT_OF_VEC4); 83 } 84 } else if (type == "uvec4") { 85 if ((offset + ALIGNMENT_OF_VEC4) <= maxByteSize) { 86 Math::UVec4* val = reinterpret_cast<Math::UVec4*>(data + offset); 87 FromJson(*value, *val); 88 offset = GetAlignment(offset + SIZE_OF_VEC4, ALIGNMENT_OF_VEC4); 89 } 90 } else if (type == "ivec4") { 91 if ((offset + ALIGNMENT_OF_VEC4) <= maxByteSize) { 92 Math::UVec4* val = reinterpret_cast<Math::UVec4*>(data + offset); 93 FromJson(*value, *val); 94 offset = GetAlignment(offset + SIZE_OF_VEC4, ALIGNMENT_OF_VEC4); 95 } 96 } else if (type == "vec3") { 97 if ((offset + ALIGNMENT_OF_VEC3) <= maxByteSize) { 98 Math::Vec3* val = reinterpret_cast<Math::Vec3*>(data + offset); 99 FromJson(*value, *val); 100 offset = GetAlignment(offset + SIZE_OF_VEC3, ALIGNMENT_OF_VEC3); 101 } 102 } else if (type == "uvec3") { 103 if ((offset + ALIGNMENT_OF_VEC3) <= maxByteSize) { 104 Math::UVec3* val = reinterpret_cast<Math::UVec3*>(data + offset); 105 FromJson(*value, *val); 106 offset = GetAlignment(offset + SIZE_OF_VEC3, ALIGNMENT_OF_VEC3); 107 } 108 } else if (type == "ivec3") { 109 if ((offset + ALIGNMENT_OF_VEC3) <= maxByteSize) { 110 Math::UVec3* val = reinterpret_cast<Math::UVec3*>(data + offset); 111 FromJson(*value, *val); 112 offset = GetAlignment(offset + SIZE_OF_VEC3, ALIGNMENT_OF_VEC3); 113 } 114 } else if (type == "vec2") { 115 if ((offset + ALIGNMENT_OF_VEC2) <= maxByteSize) { 116 Math::Vec2* val = reinterpret_cast<Math::Vec2*>(data + offset); 117 FromJson(*value, *val); 118 offset = GetAlignment(offset + SIZE_OF_VEC2, ALIGNMENT_OF_VEC2); 119 } 120 } else if (type == "uvec2") { 121 if ((offset + ALIGNMENT_OF_VEC2) <= maxByteSize) { 122 Math::UVec2* val = reinterpret_cast<Math::UVec2*>(data + offset); 123 FromJson(*value, *val); 124 offset = GetAlignment(offset + SIZE_OF_VEC2, ALIGNMENT_OF_VEC2); 125 } 126 } else if (type == "ivec2") { 127 if ((offset + ALIGNMENT_OF_VEC2) <= maxByteSize) { 128 Math::UVec2* val = reinterpret_cast<Math::UVec2*>(data + offset); 129 FromJson(*value, *val); 130 offset = GetAlignment(offset + SIZE_OF_VEC2, ALIGNMENT_OF_VEC2); 131 } 132 } else if (type == "float") { 133 if ((offset + ALIGNMENT_OF_FLOAT) <= maxByteSize) { 134 float* val = reinterpret_cast<float*>(data + offset); 135 FromJson(*value, *val); 136 offset = GetAlignment(offset + SIZE_OF_FLOAT, ALIGNMENT_OF_FLOAT); 137 } 138 } else if (type == "uint") { 139 if ((offset + ALIGNMENT_OF_FLOAT) <= maxByteSize) { 140 uint32_t* val = reinterpret_cast<uint32_t*>(data + offset); 141 FromJson(*value, *val); 142 offset = GetAlignment(offset + SIZE_OF_FLOAT, ALIGNMENT_OF_FLOAT); 143 } 144 } else if (type == "int") { 145 if ((offset + ALIGNMENT_OF_FLOAT) <= maxByteSize) { 146 int32_t* val = reinterpret_cast<int32_t*>(data + offset); 147 FromJson(*value, *val); 148 offset = GetAlignment(offset + SIZE_OF_FLOAT, ALIGNMENT_OF_FLOAT); 149 } 150 } else if (type == "mat3x3") { 151 if ((offset + ALIGNMENT_OF_MAT3X3) <= maxByteSize) { 152 Math::Mat3X3* val = reinterpret_cast<Math::Mat3X3*>(data + offset); 153 FromJson(*value, *val); 154 offset = GetAlignment(offset + SIZE_OF_MAT3X3, ALIGNMENT_OF_MAT3X3); 155 } 156 } else if (type == "mat4x4") { 157 if ((offset + ALIGNMENT_OF_MAT4X4) <= maxByteSize) { 158 Math::Mat4X4* val = reinterpret_cast<Math::Mat4X4*>(data + offset); 159 FromJson(*value, *val); 160 offset = GetAlignment(offset + SIZE_OF_MAT4X4, ALIGNMENT_OF_MAT4X4); 161 } 162 } else { 163 PLUGIN_LOG_W("RENDER_VALIDATION: Invalid property type only int, uint, float, and XvecX variants, and mat3x3 " 164 "and mat4x4 supported"); 165 } 166 // NOTE: does not handle invalid types 167 } 168 } // namespace 169 RenderDataStorePostProcess(const IRenderContext & renderContext,const string_view name)170 RenderDataStorePostProcess::RenderDataStorePostProcess(const IRenderContext& renderContext, const string_view name) 171 : renderContext_(renderContext), name_(name) 172 {} 173 ~RenderDataStorePostProcess()174 RenderDataStorePostProcess::~RenderDataStorePostProcess() {} 175 Create(const string_view name)176 void RenderDataStorePostProcess::Create(const string_view name) 177 { 178 const auto lock = std::lock_guard(mutex_); 179 180 if (!allPostProcesses_.contains(name)) { 181 CreateFromPod(name); 182 } else { 183 PLUGIN_LOG_I("Render data store post process with name (%s) already created.", name.data()); 184 } 185 } 186 Create(const string_view name,const string_view ppName,const RenderHandleReference & shader)187 void RenderDataStorePostProcess::Create( 188 const string_view name, const string_view ppName, const RenderHandleReference& shader) 189 { 190 const auto lock = std::lock_guard(mutex_); 191 192 if (!allPostProcesses_.contains(name)) { 193 CreateFromPod(name); 194 } 195 196 if (auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.end()) { 197 auto& postProcesses = iter->second.postProcesses; 198 const uint32_t ppCount = static_cast<uint32_t>(postProcesses.size()); 199 uint32_t ppIndex = ~0u; 200 for (uint32_t idx = 0; idx < ppCount; ++idx) { 201 if (postProcesses[idx].name == ppName) { 202 ppIndex = idx; 203 break; 204 } 205 } 206 207 if (ppIndex < ppCount) { 208 // does not set variables 209 GetShaderProperties(shader, postProcesses[ppIndex].variables); 210 SetGlobalFactorsImpl(postProcesses[ppIndex].variables, ppIndex, iter->second); 211 } else { 212 PostProcess pp; 213 pp.id = static_cast<uint32_t>(postProcesses.size()); 214 pp.name = ppName; 215 pp.shader = shader; 216 pp.variables = {}; // default variables, overwritten with shader default properties 217 GetShaderProperties(shader, pp.variables); 218 postProcesses.push_back(move(pp)); 219 SetGlobalFactorsImpl(postProcesses[pp.id].variables, pp.id, iter->second); 220 } 221 } else { 222 PLUGIN_LOG_E("Post process creation error (name: %s, ppName: %s)", name.data(), ppName.data()); 223 } 224 } 225 Destroy(const string_view name)226 void RenderDataStorePostProcess::Destroy(const string_view name) 227 { 228 const auto lock = std::lock_guard(mutex_); 229 230 if ((!name.empty()) && allPostProcesses_.contains(name)) { 231 allPostProcesses_.erase(name); 232 if (IRenderDataStorePod* dataStorePod = static_cast<IRenderDataStorePod*>( 233 renderContext_.GetRenderDataStoreManager().GetRenderDataStore(RENDER_DATA_STORE_POD_NAME)); 234 dataStorePod) { 235 dataStorePod->DestroyPod(RENDER_DATA_STORE_POST_PROCESS_TYPE_NAME, name); 236 } 237 } else { 238 PLUGIN_LOG_I("Post process not found: %s", name.data()); 239 } 240 } 241 Destroy(const string_view name,const string_view ppName)242 void RenderDataStorePostProcess::Destroy(const string_view name, const string_view ppName) 243 { 244 const auto lock = std::lock_guard(mutex_); 245 246 if (auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.end()) { 247 for (auto ppIter = iter->second.postProcesses.begin(); ppIter != iter->second.postProcesses.end(); ++ppIter) { 248 if (ppIter->name == ppName) { 249 iter->second.postProcesses.erase(ppIter); 250 break; 251 } 252 } 253 } 254 } 255 Contains(const string_view name) const256 bool RenderDataStorePostProcess::Contains(const string_view name) const 257 { 258 const auto lock = std::lock_guard(mutex_); 259 260 return allPostProcesses_.contains(name); 261 } 262 Contains(const string_view name,const string_view ppName) const263 bool RenderDataStorePostProcess::Contains(const string_view name, const string_view ppName) const 264 { 265 const auto lock = std::lock_guard(mutex_); 266 267 if (const auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.cend()) { 268 for (const auto& ref : iter->second.postProcesses) { 269 if (ref.name == ppName) { 270 return true; 271 } 272 } 273 } 274 return false; 275 } 276 Set(const string_view name,const string_view ppName,const PostProcess::Variables & vars)277 void RenderDataStorePostProcess::Set( 278 const string_view name, const string_view ppName, const PostProcess::Variables& vars) 279 { 280 const auto lock = std::lock_guard(mutex_); 281 282 if (auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.end()) { 283 auto& postProcesses = iter->second.postProcesses; 284 const uint32_t ppCount = static_cast<uint32_t>(postProcesses.size()); 285 for (uint32_t idx = 0; idx < ppCount; ++idx) { 286 if (postProcesses[idx].name == ppName) { 287 SetImpl(vars, idx, iter->second); 288 break; 289 } 290 } 291 } 292 } 293 Set(const string_view name,const array_view<PostProcess::Variables> vars)294 void RenderDataStorePostProcess::Set(const string_view name, const array_view<PostProcess::Variables> vars) 295 { 296 const auto lock = std::lock_guard(mutex_); 297 298 if (auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.end()) { 299 const auto& postProcesses = iter->second.postProcesses; 300 const uint32_t ppCount = 301 Math::min(static_cast<uint32_t>(vars.size()), static_cast<uint32_t>(postProcesses.size())); 302 for (uint32_t idx = 0; idx < ppCount; ++idx) { 303 SetImpl(vars[idx], idx, iter->second); 304 } 305 } 306 } 307 GetGlobalFactors(const string_view name) const308 RenderDataStorePostProcess::GlobalFactors RenderDataStorePostProcess::GetGlobalFactors(const string_view name) const 309 { 310 const auto lock = std::lock_guard(mutex_); 311 312 if (auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.end()) { 313 return iter->second.globalFactors; 314 } else { 315 return {}; 316 } 317 } 318 Get(const string_view name) const319 vector<RenderDataStorePostProcess::PostProcess> RenderDataStorePostProcess::Get(const string_view name) const 320 { 321 const auto lock = std::lock_guard(mutex_); 322 323 if (const auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.cend()) { 324 return iter->second.postProcesses; 325 } 326 return {}; 327 } 328 Get(const string_view name,const string_view ppName) const329 RenderDataStorePostProcess::PostProcess RenderDataStorePostProcess::Get( 330 const string_view name, const string_view ppName) const 331 { 332 const auto lock = std::lock_guard(mutex_); 333 334 if (const auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.cend()) { 335 for (const auto& ref : iter->second.postProcesses) { 336 if (ppName == ref.name) { 337 return ref; 338 } 339 } 340 } 341 return {}; 342 } 343 CreateFromPod(const string_view name)344 void RenderDataStorePostProcess::CreateFromPod(const string_view name) 345 { 346 // create base post process render data store 347 if (IRenderDataStorePod* dataStorePod = static_cast<IRenderDataStorePod*>( 348 renderContext_.GetRenderDataStoreManager().GetRenderDataStore(RENDER_DATA_STORE_POD_NAME)); 349 dataStorePod) { 350 PLUGIN_STATIC_ASSERT( 351 countof(PostProcessConstants::POST_PROCESS_NAMES) == PostProcessConstants::POST_PROCESS_COUNT); 352 auto& postProcessRef = allPostProcesses_[name]; 353 // NOTE: needs to fetch the post process "properties" from shader custom properties 354 if (const auto arrView = dataStorePod->Get(name); arrView.size_bytes() == sizeof(PostProcessConfiguration)) { 355 // populate with built-in data and copy 356 PostProcessConfiguration ppConfig = *((const PostProcessConfiguration*)arrView.data()); 357 FillDefaultPostProcessData(ppConfig, postProcessRef); 358 } else { 359 // create new 360 PostProcessConfiguration ppConfig; 361 dataStorePod->CreatePod(RENDER_DATA_STORE_POST_PROCESS_TYPE_NAME, name, arrayviewU8(ppConfig)); 362 FillDefaultPostProcessData(ppConfig, postProcessRef); 363 } 364 } 365 } 366 SetImpl(const PostProcess::Variables & vars,const uint32_t ppIndex,PostProcessStack & ppStack)367 void RenderDataStorePostProcess::SetImpl( 368 const PostProcess::Variables& vars, const uint32_t ppIndex, PostProcessStack& ppStack) 369 { 370 auto& postProcesses = ppStack.postProcesses; 371 PLUGIN_ASSERT(ppIndex < static_cast<uint32_t>(postProcesses.size())); 372 postProcesses[ppIndex].variables = vars; 373 SetGlobalFactorsImpl(vars, ppIndex, ppStack); 374 } 375 SetGlobalFactorsImpl(const PostProcess::Variables & vars,const uint32_t ppIndex,PostProcessStack & ppStack)376 void RenderDataStorePostProcess::SetGlobalFactorsImpl( 377 const PostProcess::Variables& vars, const uint32_t ppIndex, PostProcessStack& ppStack) 378 { 379 PLUGIN_ASSERT(ppIndex < static_cast<uint32_t>(ppStack.postProcesses.size())); 380 // NOTE: does not copy vars 381 auto& globalFactors = ppStack.globalFactors; 382 if (ppIndex < PostProcessConstants::GLOBAL_FACTOR_COUNT) { 383 globalFactors.factors[ppIndex] = vars.factor; 384 globalFactors.enableFlags = (uint32_t(vars.enabled) << ppIndex); 385 } else if (vars.userFactorIndex < PostProcessConstants::USER_GLOBAL_FACTOR_COUNT) { 386 globalFactors.userFactors[vars.userFactorIndex] = vars.factor; 387 } 388 } 389 FillDefaultPostProcessData(const PostProcessConfiguration & ppConfig,PostProcessStack & ppStack)390 void RenderDataStorePostProcess::FillDefaultPostProcessData( 391 const PostProcessConfiguration& ppConfig, PostProcessStack& ppStack) 392 { 393 const IShaderManager& shaderMgr = renderContext_.GetDevice().GetShaderManager(); 394 auto FillBuiltInData = [&](const uint32_t idx, const uint32_t factorIndex, const uint32_t userFactorIndex, 395 const Math::Vec4& factor, const string_view shaderName) { 396 PostProcess pp; 397 pp.id = idx; 398 pp.name = PostProcessConstants::POST_PROCESS_NAMES[pp.id]; 399 pp.factorIndex = factorIndex; 400 pp.shader = shaderName.empty() ? RenderHandleReference {} : shaderMgr.GetShaderHandle(shaderName); 401 auto& vars = pp.variables; 402 vars.userFactorIndex = userFactorIndex; 403 vars.enabled = false; 404 vars.factor = factor; 405 ClearToValue(vars.customPropertyData, sizeof(vars.customPropertyData), 0x0, sizeof(vars.customPropertyData)); 406 return pp; 407 }; 408 409 constexpr uint32_t defUserIdx { ~0u }; 410 ppStack.postProcesses.push_back(FillBuiltInData(PostProcessConstants::RENDER_TONEMAP, 411 PostProcessConstants::RENDER_TONEMAP, defUserIdx, PostProcessConversionHelper::GetFactorTonemap(ppConfig), {})); 412 ppStack.postProcesses.push_back( 413 FillBuiltInData(PostProcessConstants::RENDER_VIGNETTE, PostProcessConstants::RENDER_VIGNETTE, defUserIdx, 414 PostProcessConversionHelper::GetFactorVignette(ppConfig), {})); 415 ppStack.postProcesses.push_back(FillBuiltInData(PostProcessConstants::RENDER_DITHER, 416 PostProcessConstants::RENDER_DITHER, defUserIdx, PostProcessConversionHelper::GetFactorDither(ppConfig), {})); 417 ppStack.postProcesses.push_back( 418 FillBuiltInData(PostProcessConstants::RENDER_COLOR_CONVERSION, PostProcessConstants::RENDER_COLOR_CONVERSION, 419 defUserIdx, PostProcessConversionHelper::GetFactorColorConversion(ppConfig), {})); 420 ppStack.postProcesses.push_back( 421 FillBuiltInData(PostProcessConstants::RENDER_COLOR_FRINGE_BIT, PostProcessConstants::RENDER_COLOR_FRINGE_BIT, 422 defUserIdx, PostProcessConversionHelper::GetFactorFringe(ppConfig), {})); 423 424 ppStack.postProcesses.push_back(FillBuiltInData( 425 PostProcessConstants::RENDER_EMPTY_5, PostProcessConstants::RENDER_EMPTY_5, defUserIdx, {}, {})); 426 ppStack.postProcesses.push_back(FillBuiltInData( 427 PostProcessConstants::RENDER_EMPTY_6, PostProcessConstants::RENDER_EMPTY_6, defUserIdx, {}, {})); 428 ppStack.postProcesses.push_back(FillBuiltInData( 429 PostProcessConstants::RENDER_EMPTY_7, PostProcessConstants::RENDER_EMPTY_7, defUserIdx, {}, {})); 430 431 ppStack.postProcesses.push_back(FillBuiltInData(PostProcessConstants::RENDER_BLUR, 432 PostProcessConfiguration::INDEX_BLUR, defUserIdx, PostProcessConversionHelper::GetFactorBlur(ppConfig), {})); 433 ppStack.postProcesses.push_back(FillBuiltInData(PostProcessConstants::RENDER_BLOOM, 434 PostProcessConfiguration::INDEX_BLOOM, defUserIdx, PostProcessConversionHelper::GetFactorBloom(ppConfig), {})); 435 ppStack.postProcesses.push_back( 436 FillBuiltInData(PostProcessConstants::RENDER_FXAA, PostProcessConfiguration::INDEX_FXAA, defUserIdx, 437 PostProcessConversionHelper::GetFactorFxaa(ppConfig), FXAA_SHADER_NAME)); 438 ppStack.postProcesses.push_back( 439 FillBuiltInData(PostProcessConstants::RENDER_TAA, PostProcessConfiguration::INDEX_TAA, defUserIdx, 440 PostProcessConversionHelper::GetFactorTaa(ppConfig), TAA_SHADER_NAME)); 441 { 442 auto& pp = ppStack.postProcesses.emplace_back(); 443 pp.id = PostProcessConstants::RENDER_DOF; 444 pp.name = PostProcessConstants::POST_PROCESS_NAMES[pp.id]; 445 pp.factorIndex = PostProcessConfiguration::INDEX_DOF; 446 pp.shader = shaderMgr.GetShaderHandle(DOF_SHADER_NAME); 447 auto& vars = pp.variables; 448 vars.userFactorIndex = defUserIdx; 449 vars.enabled = false; 450 auto factors = PostProcessConversionHelper::GetFactorDof(ppConfig); 451 CloneData(vars.customPropertyData, sizeof(vars.customPropertyData), &factors, sizeof(factors)); 452 factors = PostProcessConversionHelper::GetFactorDof2(ppConfig); 453 CloneData(vars.customPropertyData + sizeof(factors), sizeof(vars.customPropertyData) - sizeof(factors), 454 &factors, sizeof(factors)); 455 } 456 457 ppStack.postProcesses.push_back( 458 FillBuiltInData(PostProcessConstants::RENDER_MOTION_BLUR, PostProcessConstants::RENDER_MOTION_BLUR, defUserIdx, 459 PostProcessConversionHelper::GetFactorMotionBlur(ppConfig), MB_SHADER_NAME)); 460 461 // fill global built-in factors 462 PLUGIN_ASSERT(PostProcessConstants::POST_PROCESS_COUNT == static_cast<uint32_t>(ppStack.postProcesses.size())); 463 for (size_t idx = 0; idx < ppStack.postProcesses.size(); ++idx) { 464 ppStack.globalFactors.factors[idx] = ppStack.postProcesses[idx].variables.factor; 465 } 466 } 467 GetShaderProperties(const RenderHandleReference & shader,IRenderDataStorePostProcess::PostProcess::Variables & vars)468 void RenderDataStorePostProcess::GetShaderProperties( 469 const RenderHandleReference& shader, IRenderDataStorePostProcess::PostProcess::Variables& vars) 470 { 471 if (shader) { 472 const IShaderManager& shaderMgr = renderContext_.GetDevice().GetShaderManager(); 473 if (const json::value* metaJson = shaderMgr.GetMaterialMetadata(shader); metaJson && metaJson->is_array()) { 474 for (const auto& ref : metaJson->array_) { 475 if (const auto globalFactor = ref.find(GLOBAL_FACTOR); globalFactor && globalFactor->is_array()) { 476 // process global factor "array", vec4 477 uint32_t offset = 0; 478 for (const auto& propRef : globalFactor->array_) { 479 if (propRef.is_object()) { 480 string_view type; 481 const json::value* value = nullptr; 482 for (const auto& dataObject : propRef.object_) { 483 if (dataObject.key == "type" && dataObject.value.is_string()) { 484 type = dataObject.value.string_; 485 } else if (dataObject.key == "value") { 486 value = &dataObject.value; 487 } 488 } 489 uint8_t* factorData = reinterpret_cast<uint8_t*>(&vars.factor); 490 AppendValues(MAX_GLOBAL_FACTOR_BYTE_SIZE, type, value, offset, factorData); 491 } 492 } 493 } else if (const auto customProps = ref.find(CUSTOM_PROPERTIES); 494 customProps && customProps->is_array()) { 495 // process custom properties i.e. local factors 496 for (const auto& propRef : customProps->array_) { 497 uint32_t offset = 0; 498 if (const auto customData = propRef.find(CUSTOM_PROPERTY_DATA); 499 customData && customData->is_array()) { 500 if (offset >= MAX_LOCAL_DATA_BYTE_SIZE) { 501 break; 502 } 503 504 for (const auto& dataValue : customData->array_) { 505 if (dataValue.is_object()) { 506 string_view type; 507 const json::value* value = nullptr; 508 for (const auto& dataObject : dataValue.object_) { 509 if (dataObject.key == "type" && dataObject.value.is_string()) { 510 type = dataObject.value.string_; 511 } else if (dataObject.key == "value") { 512 value = &dataObject.value; 513 } 514 } 515 AppendValues( 516 MAX_LOCAL_DATA_BYTE_SIZE, type, value, offset, vars.customPropertyData); 517 } 518 } 519 } 520 } 521 } 522 } 523 } 524 } 525 } 526 527 // for plugin / factory interface Create(IRenderContext & renderContext,char const * name)528 IRenderDataStore* RenderDataStorePostProcess::Create(IRenderContext& renderContext, char const* name) 529 { 530 // engine not used 531 return new RenderDataStorePostProcess(renderContext, name); 532 } 533 Destroy(IRenderDataStore * aInstance)534 void RenderDataStorePostProcess::Destroy(IRenderDataStore* aInstance) 535 { 536 delete static_cast<RenderDataStorePostProcess*>(aInstance); 537 } 538 RENDER_END_NAMESPACE() 539