18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#include "graphics_context.h" 178bf80f4bSopenharmony_ci 188bf80f4bSopenharmony_ci#include <algorithm> 198bf80f4bSopenharmony_ci 208bf80f4bSopenharmony_ci#include <base/containers/string_view.h> 218bf80f4bSopenharmony_ci#include <base/containers/unordered_map.h> 228bf80f4bSopenharmony_ci#include <base/util/uid.h> 238bf80f4bSopenharmony_ci#include <core/ecs/intf_ecs.h> 248bf80f4bSopenharmony_ci#include <core/ecs/intf_entity_manager.h> 258bf80f4bSopenharmony_ci#include <core/intf_engine.h> 268bf80f4bSopenharmony_ci#include <core/io/intf_file_manager.h> 278bf80f4bSopenharmony_ci#include <core/log.h> 288bf80f4bSopenharmony_ci#include <core/plugin/intf_plugin.h> 298bf80f4bSopenharmony_ci#include <core/plugin/intf_plugin_register.h> 308bf80f4bSopenharmony_ci#include <core/property/intf_property_handle.h> 318bf80f4bSopenharmony_ci#include <render/datastore/intf_render_data_store_manager.h> 328bf80f4bSopenharmony_ci#include <render/datastore/intf_render_data_store_pod.h> 338bf80f4bSopenharmony_ci#include <render/device/intf_device.h> 348bf80f4bSopenharmony_ci#include <render/device/intf_gpu_resource_manager.h> 358bf80f4bSopenharmony_ci#include <render/device/intf_shader_manager.h> 368bf80f4bSopenharmony_ci#include <render/implementation_uids.h> 378bf80f4bSopenharmony_ci#include <render/intf_plugin.h> 388bf80f4bSopenharmony_ci#include <render/intf_render_context.h> 398bf80f4bSopenharmony_ci#include <render/loader/intf_render_data_configuration_loader.h> 408bf80f4bSopenharmony_ci#include <render/nodecontext/intf_render_node_graph_manager.h> 418bf80f4bSopenharmony_ci 428bf80f4bSopenharmony_ci#if (RENDER_HAS_VULKAN_BACKEND) 438bf80f4bSopenharmony_ci#include <render/vulkan/intf_device_vk.h> 448bf80f4bSopenharmony_ci#endif 458bf80f4bSopenharmony_ci 468bf80f4bSopenharmony_ci#include <3d/ecs/components/material_component.h> 478bf80f4bSopenharmony_ci#include <3d/ecs/components/uri_component.h> 488bf80f4bSopenharmony_ci#include <3d/ecs/systems/intf_render_system.h> 498bf80f4bSopenharmony_ci#include <3d/implementation_uids.h> 508bf80f4bSopenharmony_ci#include <3d/intf_plugin.h> 518bf80f4bSopenharmony_ci#include <3d/loaders/intf_scene_loader.h> 528bf80f4bSopenharmony_ci#include <3d/render/default_material_constants.h> 538bf80f4bSopenharmony_ci#include <3d/render/intf_render_node_scene_util.h> 548bf80f4bSopenharmony_ci#include <3d/util/intf_mesh_util.h> 558bf80f4bSopenharmony_ci#include <3d/util/intf_scene_util.h> 568bf80f4bSopenharmony_ci 578bf80f4bSopenharmony_ci#include "gltf/gltf2.h" 588bf80f4bSopenharmony_ci#include "render/render_node_scene_util.h" 598bf80f4bSopenharmony_ci#include "util/mesh_builder.h" 608bf80f4bSopenharmony_ci#include "util/mesh_util.h" 618bf80f4bSopenharmony_ci#include "util/picking.h" 628bf80f4bSopenharmony_ci#include "util/render_util.h" 638bf80f4bSopenharmony_ci#include "util/scene_util.h" 648bf80f4bSopenharmony_ci#include "util/uri_lookup.h" 658bf80f4bSopenharmony_ci 668bf80f4bSopenharmony_ciextern "C" void InitRegistry(CORE_NS::IPluginRegister& pluginRegistry); 678bf80f4bSopenharmony_ci 688bf80f4bSopenharmony_ciCORE3D_BEGIN_NAMESPACE() 698bf80f4bSopenharmony_ciusing namespace BASE_NS; 708bf80f4bSopenharmony_ciusing namespace CORE_NS; 718bf80f4bSopenharmony_ciusing namespace RENDER_NS; 728bf80f4bSopenharmony_ci 738bf80f4bSopenharmony_cinamespace { 748bf80f4bSopenharmony_cistruct RegisterPathStrings { 758bf80f4bSopenharmony_ci string_view protocol; 768bf80f4bSopenharmony_ci string_view uri; 778bf80f4bSopenharmony_ci}; 788bf80f4bSopenharmony_cistatic constexpr RegisterPathStrings RENDER_DATA_PATHS[] = { 798bf80f4bSopenharmony_ci { "3dshaders", "rofs3D://shaders/" }, 808bf80f4bSopenharmony_ci { "3dshaderstates", "rofs3D://shaderstates/" }, 818bf80f4bSopenharmony_ci { "3dvertexinputdeclarations", "rofs3D://vertexinputdeclarations/" }, 828bf80f4bSopenharmony_ci { "3dpipelinelayouts", "rofs3D://pipelinelayouts/" }, 838bf80f4bSopenharmony_ci { "3drenderdataconfigurations", "rofs3D://renderdataconfigurations/" }, 848bf80f4bSopenharmony_ci { "3drendernodegraphs", "rofs3D://rendernodegraphs/" }, 858bf80f4bSopenharmony_ci}; 868bf80f4bSopenharmony_ci 878bf80f4bSopenharmony_cistatic constexpr IShaderManager::ShaderFilePathDesc SHADER_FILE_PATHS { 888bf80f4bSopenharmony_ci "3dshaders://", 898bf80f4bSopenharmony_ci "3dshaderstates://", 908bf80f4bSopenharmony_ci "3dpipelinelayouts://", 918bf80f4bSopenharmony_ci "3dvertexinputdeclarations://", 928bf80f4bSopenharmony_ci}; 938bf80f4bSopenharmony_ci 948bf80f4bSopenharmony_cistatic constexpr string_view POST_PROCESS_PATH { "3drenderdataconfigurations://postprocess/" }; 958bf80f4bSopenharmony_cistatic constexpr string_view POST_PROCESS_DATA_STORE_NAME { "RenderDataStorePod" }; 968bf80f4bSopenharmony_cistatic constexpr string_view POST_PROCESS_NAME { "PostProcess" }; 978bf80f4bSopenharmony_ci 988bf80f4bSopenharmony_civoid CreateDefaultImages(IDevice& device, vector<RenderHandleReference>& defaultGpuResources) 998bf80f4bSopenharmony_ci{ 1008bf80f4bSopenharmony_ci IGpuResourceManager& gpuResourceMgr = device.GetGpuResourceManager(); 1018bf80f4bSopenharmony_ci 1028bf80f4bSopenharmony_ci // default material gpu images 1038bf80f4bSopenharmony_ci GpuImageDesc desc { ImageType::CORE_IMAGE_TYPE_2D, ImageViewType::CORE_IMAGE_VIEW_TYPE_2D, 1048bf80f4bSopenharmony_ci Format::BASE_FORMAT_R8G8B8A8_SRGB, ImageTiling::CORE_IMAGE_TILING_OPTIMAL, 1058bf80f4bSopenharmony_ci ImageUsageFlagBits::CORE_IMAGE_USAGE_SAMPLED_BIT | ImageUsageFlagBits::CORE_IMAGE_USAGE_TRANSFER_DST_BIT, 1068bf80f4bSopenharmony_ci MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, 0, 2, 2, 1, 1, 1, 1078bf80f4bSopenharmony_ci SampleCountFlagBits::CORE_SAMPLE_COUNT_1_BIT, {} }; 1088bf80f4bSopenharmony_ci constexpr uint32_t sizeOfUint32 = sizeof(uint32_t); 1098bf80f4bSopenharmony_ci 1108bf80f4bSopenharmony_ci desc.format = Format::BASE_FORMAT_R8G8B8A8_UNORM; 1118bf80f4bSopenharmony_ci { 1128bf80f4bSopenharmony_ci constexpr const uint32_t normalData[4u] = { 0xFFFF7f7f, 0xFFFF7f7f, 0xFFFF7f7f, 0xFFFF7f7f }; 1138bf80f4bSopenharmony_ci const auto normalDataView = 1148bf80f4bSopenharmony_ci array_view(reinterpret_cast<const uint8_t*>(normalData), sizeOfUint32 * countof(normalData)); 1158bf80f4bSopenharmony_ci defaultGpuResources.push_back(gpuResourceMgr.Create( 1168bf80f4bSopenharmony_ci DefaultMaterialGpuResourceConstants::CORE_DEFAULT_MATERIAL_NORMAL, desc, normalDataView)); 1178bf80f4bSopenharmony_ci } 1188bf80f4bSopenharmony_ci 1198bf80f4bSopenharmony_ci desc.format = Format::BASE_FORMAT_R8_UNORM; 1208bf80f4bSopenharmony_ci { 1218bf80f4bSopenharmony_ci constexpr const uint8_t byteData[4u] = { 0xff, 0xff, 0xff, 0xff }; 1228bf80f4bSopenharmony_ci const auto byteDataView = 1238bf80f4bSopenharmony_ci array_view(reinterpret_cast<const uint8_t*>(byteData), sizeof(uint8_t) * countof(byteData)); 1248bf80f4bSopenharmony_ci defaultGpuResources.push_back( 1258bf80f4bSopenharmony_ci gpuResourceMgr.Create(DefaultMaterialGpuResourceConstants::CORE_DEFAULT_MATERIAL_AO, desc, byteDataView)); 1268bf80f4bSopenharmony_ci } 1278bf80f4bSopenharmony_ci 1288bf80f4bSopenharmony_ci // env cubemaps 1298bf80f4bSopenharmony_ci desc.imageViewType = ImageViewType::CORE_IMAGE_VIEW_TYPE_CUBE; 1308bf80f4bSopenharmony_ci desc.format = Format::BASE_FORMAT_R8G8B8A8_SRGB; 1318bf80f4bSopenharmony_ci desc.createFlags = ImageCreateFlagBits::CORE_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; 1328bf80f4bSopenharmony_ci desc.layerCount = 6u; 1338bf80f4bSopenharmony_ci { 1348bf80f4bSopenharmony_ci // Env color is currently in rgbd format (alpha channel is used as a divider for the rgb values). 1358bf80f4bSopenharmony_ci const vector<uint32_t> cubeData(4u * 6u, 0xFFFFffff); 1368bf80f4bSopenharmony_ci const array_view<const uint8_t> cubeDataView( 1378bf80f4bSopenharmony_ci reinterpret_cast<const uint8_t*>(cubeData.data()), cubeData.size() * sizeOfUint32); 1388bf80f4bSopenharmony_ci defaultGpuResources.push_back(gpuResourceMgr.Create( 1398bf80f4bSopenharmony_ci DefaultMaterialGpuResourceConstants::CORE_DEFAULT_RADIANCE_CUBEMAP, desc, cubeDataView)); 1408bf80f4bSopenharmony_ci 1418bf80f4bSopenharmony_ci // Skybox is currently in rgbd format (alpha channel is used as a divider for the rgb values). 1428bf80f4bSopenharmony_ci defaultGpuResources.push_back(gpuResourceMgr.Create( 1438bf80f4bSopenharmony_ci DefaultMaterialGpuResourceConstants::CORE_DEFAULT_SKYBOX_CUBEMAP, desc, cubeDataView)); 1448bf80f4bSopenharmony_ci } 1458bf80f4bSopenharmony_ci} 1468bf80f4bSopenharmony_ci 1478bf80f4bSopenharmony_civoid CreateDefaultSamplers(IDevice& device, vector<RenderHandleReference>& defaultGpuResources) 1488bf80f4bSopenharmony_ci{ 1498bf80f4bSopenharmony_ci IGpuResourceManager& gpuResourceMgr = device.GetGpuResourceManager(); 1508bf80f4bSopenharmony_ci { 1518bf80f4bSopenharmony_ci GpuSamplerDesc sampler { 1528bf80f4bSopenharmony_ci Filter::CORE_FILTER_LINEAR, // magFilter 1538bf80f4bSopenharmony_ci Filter::CORE_FILTER_LINEAR, // minFilter 1548bf80f4bSopenharmony_ci Filter::CORE_FILTER_LINEAR, // mipMapMode 1558bf80f4bSopenharmony_ci SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU 1568bf80f4bSopenharmony_ci SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV 1578bf80f4bSopenharmony_ci SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW 1588bf80f4bSopenharmony_ci }; 1598bf80f4bSopenharmony_ci constexpr float CUBE_MAP_LOD_COEFF { 8.0f }; 1608bf80f4bSopenharmony_ci sampler.minLod = 0.0f; 1618bf80f4bSopenharmony_ci sampler.maxLod = CUBE_MAP_LOD_COEFF; 1628bf80f4bSopenharmony_ci defaultGpuResources.push_back( 1638bf80f4bSopenharmony_ci gpuResourceMgr.Create(DefaultMaterialGpuResourceConstants::CORE_DEFAULT_RADIANCE_CUBEMAP_SAMPLER, sampler)); 1648bf80f4bSopenharmony_ci } 1658bf80f4bSopenharmony_ci { 1668bf80f4bSopenharmony_ci GpuSamplerDesc sampler { 1678bf80f4bSopenharmony_ci Filter::CORE_FILTER_LINEAR, // magFilter 1688bf80f4bSopenharmony_ci Filter::CORE_FILTER_LINEAR, // minFilter 1698bf80f4bSopenharmony_ci Filter::CORE_FILTER_LINEAR, // mipMapMode 1708bf80f4bSopenharmony_ci SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU 1718bf80f4bSopenharmony_ci SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV 1728bf80f4bSopenharmony_ci SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW 1738bf80f4bSopenharmony_ci }; 1748bf80f4bSopenharmony_ci defaultGpuResources.push_back( 1758bf80f4bSopenharmony_ci gpuResourceMgr.Create(DefaultMaterialGpuResourceConstants::CORE_DEFAULT_VSM_SHADOW_SAMPLER, sampler)); 1768bf80f4bSopenharmony_ci 1778bf80f4bSopenharmony_ci sampler.compareOp = CompareOp::CORE_COMPARE_OP_GREATER; 1788bf80f4bSopenharmony_ci sampler.enableCompareOp = true; 1798bf80f4bSopenharmony_ci defaultGpuResources.push_back( 1808bf80f4bSopenharmony_ci gpuResourceMgr.Create(DefaultMaterialGpuResourceConstants::CORE_DEFAULT_PCF_SHADOW_SAMPLER, sampler)); 1818bf80f4bSopenharmony_ci } 1828bf80f4bSopenharmony_ci} 1838bf80f4bSopenharmony_ci 1848bf80f4bSopenharmony_civoid CreateDefaultResources(IDevice& device, vector<RenderHandleReference>& defaultGpuResources) 1858bf80f4bSopenharmony_ci{ 1868bf80f4bSopenharmony_ci CreateDefaultImages(device, defaultGpuResources); 1878bf80f4bSopenharmony_ci CreateDefaultSamplers(device, defaultGpuResources); 1888bf80f4bSopenharmony_ci} 1898bf80f4bSopenharmony_ci} // namespace 1908bf80f4bSopenharmony_ci 1918bf80f4bSopenharmony_ci// Core Rofs Data. 1928bf80f4bSopenharmony_ciextern "C" { 1938bf80f4bSopenharmony_ciextern const void* const BINARY_DATA_FOR_3D[]; 1948bf80f4bSopenharmony_ciextern const uint64_t SIZE_OF_DATA_FOR_3D; 1958bf80f4bSopenharmony_ci} 1968bf80f4bSopenharmony_ci 1978bf80f4bSopenharmony_ciarray_view<const RenderDataStoreTypeInfo> GetRenderDataStores3D(); 1988bf80f4bSopenharmony_ciarray_view<const RenderNodeTypeInfo> GetRenderNodes3D(); 1998bf80f4bSopenharmony_ciarray_view<const ComponentManagerTypeInfo> GetComponentManagers3D(); 2008bf80f4bSopenharmony_ciarray_view<const SystemTypeInfo> GetSystems3D(); 2018bf80f4bSopenharmony_ci 2028bf80f4bSopenharmony_cistruct Agp3DPluginState { 2038bf80f4bSopenharmony_ci IRenderContext& renderContext; 2048bf80f4bSopenharmony_ci unique_ptr<GraphicsContext> context; 2058bf80f4bSopenharmony_ci 2068bf80f4bSopenharmony_ci vector<RenderHandleReference> defaultGpuResources; 2078bf80f4bSopenharmony_ci vector<string> defaultPostProcesses; 2088bf80f4bSopenharmony_ci 2098bf80f4bSopenharmony_ci Picking picker_; 2108bf80f4bSopenharmony_ci RenderNodeSceneUtilImpl renderNodeSceneUtil; 2118bf80f4bSopenharmony_ci InterfaceTypeInfo interfaces[4] = { 2128bf80f4bSopenharmony_ci InterfaceTypeInfo { 2138bf80f4bSopenharmony_ci this, 2148bf80f4bSopenharmony_ci UID_MESH_BUILDER, 2158bf80f4bSopenharmony_ci CORE_NS::GetName<IMeshBuilder>().data(), 2168bf80f4bSopenharmony_ci [](IClassFactory&, PluginToken token) -> IInterface* { 2178bf80f4bSopenharmony_ci if (token) { 2188bf80f4bSopenharmony_ci Agp3DPluginState* state = static_cast<Agp3DPluginState*>(token); 2198bf80f4bSopenharmony_ci return new MeshBuilder(state->renderContext); 2208bf80f4bSopenharmony_ci } 2218bf80f4bSopenharmony_ci return nullptr; 2228bf80f4bSopenharmony_ci }, 2238bf80f4bSopenharmony_ci nullptr, 2248bf80f4bSopenharmony_ci }, 2258bf80f4bSopenharmony_ci InterfaceTypeInfo { 2268bf80f4bSopenharmony_ci this, 2278bf80f4bSopenharmony_ci UID_PICKING, 2288bf80f4bSopenharmony_ci CORE_NS::GetName<IPicking>().data(), 2298bf80f4bSopenharmony_ci nullptr, 2308bf80f4bSopenharmony_ci [](IClassRegister& registry, PluginToken token) -> IInterface* { 2318bf80f4bSopenharmony_ci if (token) { 2328bf80f4bSopenharmony_ci Agp3DPluginState* state = static_cast<Agp3DPluginState*>(token); 2338bf80f4bSopenharmony_ci return &state->picker_; 2348bf80f4bSopenharmony_ci } 2358bf80f4bSopenharmony_ci return nullptr; 2368bf80f4bSopenharmony_ci }, 2378bf80f4bSopenharmony_ci }, 2388bf80f4bSopenharmony_ci InterfaceTypeInfo { 2398bf80f4bSopenharmony_ci this, 2408bf80f4bSopenharmony_ci UID_RENDER_NODE_SCENE_UTIL, 2418bf80f4bSopenharmony_ci CORE_NS::GetName<IRenderNodeSceneUtil>().data(), 2428bf80f4bSopenharmony_ci nullptr, 2438bf80f4bSopenharmony_ci [](IClassRegister& registry, PluginToken token) -> IInterface* { 2448bf80f4bSopenharmony_ci if (token) { 2458bf80f4bSopenharmony_ci Agp3DPluginState* state = static_cast<Agp3DPluginState*>(token); 2468bf80f4bSopenharmony_ci return &state->renderNodeSceneUtil; 2478bf80f4bSopenharmony_ci } 2488bf80f4bSopenharmony_ci return nullptr; 2498bf80f4bSopenharmony_ci }, 2508bf80f4bSopenharmony_ci }, 2518bf80f4bSopenharmony_ci InterfaceTypeInfo { 2528bf80f4bSopenharmony_ci this, 2538bf80f4bSopenharmony_ci UID_GRAPHICS_CONTEXT, 2548bf80f4bSopenharmony_ci CORE_NS::GetName<IGraphicsContext>().data(), 2558bf80f4bSopenharmony_ci [](IClassFactory& registry, PluginToken token) -> IInterface* { 2568bf80f4bSopenharmony_ci if (token) { 2578bf80f4bSopenharmony_ci Agp3DPluginState* state = static_cast<Agp3DPluginState*>(token); 2588bf80f4bSopenharmony_ci if (!state->context) { 2598bf80f4bSopenharmony_ci state->context = make_unique<GraphicsContext>(*state, state->renderContext); 2608bf80f4bSopenharmony_ci } 2618bf80f4bSopenharmony_ci return state->context->GetInterface(IInterface::UID); 2628bf80f4bSopenharmony_ci } 2638bf80f4bSopenharmony_ci return nullptr; 2648bf80f4bSopenharmony_ci }, 2658bf80f4bSopenharmony_ci [](IClassRegister& registry, PluginToken token) -> IInterface* { 2668bf80f4bSopenharmony_ci if (token) { 2678bf80f4bSopenharmony_ci Agp3DPluginState* state = static_cast<Agp3DPluginState*>(token); 2688bf80f4bSopenharmony_ci return state->context->GetInterface(IInterface::UID); 2698bf80f4bSopenharmony_ci } 2708bf80f4bSopenharmony_ci return nullptr; 2718bf80f4bSopenharmony_ci }, 2728bf80f4bSopenharmony_ci }, 2738bf80f4bSopenharmony_ci }; 2748bf80f4bSopenharmony_ci 2758bf80f4bSopenharmony_ci void Destroy() 2768bf80f4bSopenharmony_ci { 2778bf80f4bSopenharmony_ci context.reset(); 2788bf80f4bSopenharmony_ci } 2798bf80f4bSopenharmony_ci}; 2808bf80f4bSopenharmony_ci 2818bf80f4bSopenharmony_ciGraphicsContext::GraphicsContext(struct Agp3DPluginState& factory, IRenderContext& context) 2828bf80f4bSopenharmony_ci : factory_(factory), context_(context) 2838bf80f4bSopenharmony_ci{} 2848bf80f4bSopenharmony_ci 2858bf80f4bSopenharmony_ciGraphicsContext ::~GraphicsContext() 2868bf80f4bSopenharmony_ci{ 2878bf80f4bSopenharmony_ci GetPluginRegister().RemoveListener(*this); 2888bf80f4bSopenharmony_ci 2898bf80f4bSopenharmony_ci for (auto& info : plugins_) { 2908bf80f4bSopenharmony_ci if (info.second && info.second->destroyPlugin) { 2918bf80f4bSopenharmony_ci info.second->destroyPlugin(info.first); 2928bf80f4bSopenharmony_ci } 2938bf80f4bSopenharmony_ci } 2948bf80f4bSopenharmony_ci if (sceneUtil_ && gltf2_) { 2958bf80f4bSopenharmony_ci sceneUtil_->UnregisterSceneLoader(IInterface::Ptr { gltf2_->GetInterface(ISceneLoader::UID) }); 2968bf80f4bSopenharmony_ci } 2978bf80f4bSopenharmony_ci} 2988bf80f4bSopenharmony_ci 2998bf80f4bSopenharmony_civoid GraphicsContext::Init() 3008bf80f4bSopenharmony_ci{ 3018bf80f4bSopenharmony_ci if (initialized_) { 3028bf80f4bSopenharmony_ci return; 3038bf80f4bSopenharmony_ci } 3048bf80f4bSopenharmony_ci auto& engine = context_.GetEngine(); 3058bf80f4bSopenharmony_ci 3068bf80f4bSopenharmony_ci meshUtil_ = make_unique<MeshUtil>(engine); 3078bf80f4bSopenharmony_ci gltf2_ = make_unique<Gltf2>(*this); 3088bf80f4bSopenharmony_ci sceneUtil_ = make_unique<SceneUtil>(*this); 3098bf80f4bSopenharmony_ci renderUtil_ = make_unique<RenderUtil>(*this); 3108bf80f4bSopenharmony_ci sceneUtil_->RegisterSceneLoader(IInterface::Ptr { gltf2_->GetInterface(ISceneLoader::UID) }); 3118bf80f4bSopenharmony_ci initialized_ = true; 3128bf80f4bSopenharmony_ci 3138bf80f4bSopenharmony_ci GetPluginRegister().AddListener(*this); 3148bf80f4bSopenharmony_ci 3158bf80f4bSopenharmony_ci for (auto info : CORE_NS::GetPluginRegister().GetTypeInfos(I3DPlugin::UID)) { 3168bf80f4bSopenharmony_ci if (auto plugin = static_cast<const I3DPlugin*>(info); plugin && plugin->createPlugin) { 3178bf80f4bSopenharmony_ci auto token = plugin->createPlugin(*this); 3188bf80f4bSopenharmony_ci plugins_.push_back({ token, plugin }); 3198bf80f4bSopenharmony_ci } 3208bf80f4bSopenharmony_ci } 3218bf80f4bSopenharmony_ci} 3228bf80f4bSopenharmony_ci 3238bf80f4bSopenharmony_ciIRenderContext& GraphicsContext::GetRenderContext() const 3248bf80f4bSopenharmony_ci{ 3258bf80f4bSopenharmony_ci return context_; 3268bf80f4bSopenharmony_ci} 3278bf80f4bSopenharmony_ci 3288bf80f4bSopenharmony_ciarray_view<const RenderHandleReference> GraphicsContext::GetRenderNodeGraphs(const IEcs& ecs) const 3298bf80f4bSopenharmony_ci{ 3308bf80f4bSopenharmony_ci // NOTE: gets the render node graphs from built-in RenderSystem 3318bf80f4bSopenharmony_ci if (IRenderSystem* rs = GetSystem<IRenderSystem>(ecs); rs) { 3328bf80f4bSopenharmony_ci return rs->GetRenderNodeGraphs(); 3338bf80f4bSopenharmony_ci } else { 3348bf80f4bSopenharmony_ci return {}; 3358bf80f4bSopenharmony_ci } 3368bf80f4bSopenharmony_ci} 3378bf80f4bSopenharmony_ci 3388bf80f4bSopenharmony_ciISceneUtil& GraphicsContext::GetSceneUtil() const 3398bf80f4bSopenharmony_ci{ 3408bf80f4bSopenharmony_ci return *sceneUtil_; 3418bf80f4bSopenharmony_ci} 3428bf80f4bSopenharmony_ci 3438bf80f4bSopenharmony_ciIMeshUtil& GraphicsContext::GetMeshUtil() const 3448bf80f4bSopenharmony_ci{ 3458bf80f4bSopenharmony_ci return *meshUtil_; 3468bf80f4bSopenharmony_ci} 3478bf80f4bSopenharmony_ci 3488bf80f4bSopenharmony_ciIGltf2& GraphicsContext::GetGltf() const 3498bf80f4bSopenharmony_ci{ 3508bf80f4bSopenharmony_ci return *gltf2_; 3518bf80f4bSopenharmony_ci} 3528bf80f4bSopenharmony_ci 3538bf80f4bSopenharmony_ciIRenderUtil& GraphicsContext::GetRenderUtil() const 3548bf80f4bSopenharmony_ci{ 3558bf80f4bSopenharmony_ci return *renderUtil_; 3568bf80f4bSopenharmony_ci} 3578bf80f4bSopenharmony_ci 3588bf80f4bSopenharmony_ciconst IInterface* GraphicsContext::GetInterface(const Uid& uid) const 3598bf80f4bSopenharmony_ci{ 3608bf80f4bSopenharmony_ci if (uid == IGraphicsContext::UID) { 3618bf80f4bSopenharmony_ci return static_cast<const IGraphicsContext*>(this); 3628bf80f4bSopenharmony_ci } else if (uid == IInterface::UID) { 3638bf80f4bSopenharmony_ci return static_cast<const IInterface*>(static_cast<const IGraphicsContext*>(this)); 3648bf80f4bSopenharmony_ci } else if (uid == IClassRegister::UID) { 3658bf80f4bSopenharmony_ci return static_cast<const IClassRegister*>(this); 3668bf80f4bSopenharmony_ci } else if (uid == IClassFactory::UID) { 3678bf80f4bSopenharmony_ci return static_cast<const IClassFactory*>(this); 3688bf80f4bSopenharmony_ci } 3698bf80f4bSopenharmony_ci return nullptr; 3708bf80f4bSopenharmony_ci} 3718bf80f4bSopenharmony_ci 3728bf80f4bSopenharmony_ciIInterface* GraphicsContext::GetInterface(const Uid& uid) 3738bf80f4bSopenharmony_ci{ 3748bf80f4bSopenharmony_ci if (uid == IGraphicsContext::UID) { 3758bf80f4bSopenharmony_ci return static_cast<IGraphicsContext*>(this); 3768bf80f4bSopenharmony_ci } else if (uid == IInterface::UID) { 3778bf80f4bSopenharmony_ci return static_cast<IInterface*>(static_cast<IGraphicsContext*>(this)); 3788bf80f4bSopenharmony_ci } else if (uid == IClassRegister::UID) { 3798bf80f4bSopenharmony_ci return static_cast<IClassRegister*>(this); 3808bf80f4bSopenharmony_ci } else if (uid == IClassFactory::UID) { 3818bf80f4bSopenharmony_ci return static_cast<IClassFactory*>(this); 3828bf80f4bSopenharmony_ci } 3838bf80f4bSopenharmony_ci return nullptr; 3848bf80f4bSopenharmony_ci} 3858bf80f4bSopenharmony_ci 3868bf80f4bSopenharmony_civoid GraphicsContext::Ref() 3878bf80f4bSopenharmony_ci{ 3888bf80f4bSopenharmony_ci refcnt_++; 3898bf80f4bSopenharmony_ci} 3908bf80f4bSopenharmony_ci 3918bf80f4bSopenharmony_civoid GraphicsContext::Unref() 3928bf80f4bSopenharmony_ci{ 3938bf80f4bSopenharmony_ci if (--refcnt_ == 0) { 3948bf80f4bSopenharmony_ci factory_.Destroy(); 3958bf80f4bSopenharmony_ci } 3968bf80f4bSopenharmony_ci} 3978bf80f4bSopenharmony_ci 3988bf80f4bSopenharmony_civoid GraphicsContext::RegisterInterfaceType(const InterfaceTypeInfo& interfaceInfo) 3998bf80f4bSopenharmony_ci{ 4008bf80f4bSopenharmony_ci // keep interfaceTypeInfos_ sorted according to UIDs 4018bf80f4bSopenharmony_ci const auto pos = std::upper_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), interfaceInfo.uid, 4028bf80f4bSopenharmony_ci [](Uid value, const InterfaceTypeInfo* element) { return value < element->uid; }); 4038bf80f4bSopenharmony_ci interfaceTypeInfos_.insert(pos, &interfaceInfo); 4048bf80f4bSopenharmony_ci} 4058bf80f4bSopenharmony_ci 4068bf80f4bSopenharmony_civoid GraphicsContext::UnregisterInterfaceType(const InterfaceTypeInfo& interfaceInfo) 4078bf80f4bSopenharmony_ci{ 4088bf80f4bSopenharmony_ci if (!interfaceTypeInfos_.empty()) { 4098bf80f4bSopenharmony_ci const auto pos = std::lower_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), interfaceInfo.uid, 4108bf80f4bSopenharmony_ci [](const InterfaceTypeInfo* element, Uid value) { return element->uid < value; }); 4118bf80f4bSopenharmony_ci if ((pos != interfaceTypeInfos_.cend()) && (*pos)->uid == interfaceInfo.uid) { 4128bf80f4bSopenharmony_ci interfaceTypeInfos_.erase(pos); 4138bf80f4bSopenharmony_ci } 4148bf80f4bSopenharmony_ci } 4158bf80f4bSopenharmony_ci} 4168bf80f4bSopenharmony_ci 4178bf80f4bSopenharmony_ciarray_view<const InterfaceTypeInfo* const> GraphicsContext::GetInterfaceMetadata() const 4188bf80f4bSopenharmony_ci{ 4198bf80f4bSopenharmony_ci return interfaceTypeInfos_; 4208bf80f4bSopenharmony_ci} 4218bf80f4bSopenharmony_ci 4228bf80f4bSopenharmony_ciconst InterfaceTypeInfo& GraphicsContext::GetInterfaceMetadata(const Uid& uid) const 4238bf80f4bSopenharmony_ci{ 4248bf80f4bSopenharmony_ci static InterfaceTypeInfo invalidType {}; 4258bf80f4bSopenharmony_ci 4268bf80f4bSopenharmony_ci if (!interfaceTypeInfos_.empty()) { 4278bf80f4bSopenharmony_ci const auto pos = std::lower_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), uid, 4288bf80f4bSopenharmony_ci [](const InterfaceTypeInfo* element, Uid value) { return element->uid < value; }); 4298bf80f4bSopenharmony_ci if ((pos != interfaceTypeInfos_.cend()) && (*pos)->uid == uid) { 4308bf80f4bSopenharmony_ci return *(*pos); 4318bf80f4bSopenharmony_ci } 4328bf80f4bSopenharmony_ci } 4338bf80f4bSopenharmony_ci return invalidType; 4348bf80f4bSopenharmony_ci} 4358bf80f4bSopenharmony_ci 4368bf80f4bSopenharmony_ciIInterface* GraphicsContext::GetInstance(const BASE_NS::Uid& uid) const 4378bf80f4bSopenharmony_ci{ 4388bf80f4bSopenharmony_ci const auto& data = GetInterfaceMetadata(uid); 4398bf80f4bSopenharmony_ci if (data.getInterface) { 4408bf80f4bSopenharmony_ci return data.getInterface(const_cast<GraphicsContext&>(*this), data.token); 4418bf80f4bSopenharmony_ci } 4428bf80f4bSopenharmony_ci return nullptr; 4438bf80f4bSopenharmony_ci} 4448bf80f4bSopenharmony_ci 4458bf80f4bSopenharmony_ciIInterface::Ptr GraphicsContext::CreateInstance(const BASE_NS::Uid& uid) 4468bf80f4bSopenharmony_ci{ 4478bf80f4bSopenharmony_ci const auto& data = GetInterfaceMetadata(uid); 4488bf80f4bSopenharmony_ci if (data.createInterface) { 4498bf80f4bSopenharmony_ci return IInterface::Ptr { data.createInterface(*this, data.token) }; 4508bf80f4bSopenharmony_ci } 4518bf80f4bSopenharmony_ci return IInterface::Ptr {}; 4528bf80f4bSopenharmony_ci} 4538bf80f4bSopenharmony_ci 4548bf80f4bSopenharmony_civoid GraphicsContext::OnTypeInfoEvent(EventType type, array_view<const ITypeInfo* const> typeInfos) 4558bf80f4bSopenharmony_ci{ 4568bf80f4bSopenharmony_ci if (type == EventType::ADDED) { 4578bf80f4bSopenharmony_ci for (const auto* info : typeInfos) { 4588bf80f4bSopenharmony_ci if (info && info->typeUid == I3DPlugin::UID && static_cast<const I3DPlugin*>(info)->createPlugin) { 4598bf80f4bSopenharmony_ci auto plugin = static_cast<const I3DPlugin*>(info); 4608bf80f4bSopenharmony_ci if (std::none_of(plugins_.begin(), plugins_.end(), 4618bf80f4bSopenharmony_ci [plugin](const pair<PluginToken, const I3DPlugin*>& pluginData) { 4628bf80f4bSopenharmony_ci return pluginData.second == plugin; 4638bf80f4bSopenharmony_ci })) { 4648bf80f4bSopenharmony_ci auto token = plugin->createPlugin(*this); 4658bf80f4bSopenharmony_ci plugins_.push_back({ token, plugin }); 4668bf80f4bSopenharmony_ci } 4678bf80f4bSopenharmony_ci } 4688bf80f4bSopenharmony_ci } 4698bf80f4bSopenharmony_ci } else if (type == EventType::REMOVED) { 4708bf80f4bSopenharmony_ci for (const auto* info : typeInfos) { 4718bf80f4bSopenharmony_ci if (info && info->typeUid == I3DPlugin::UID) { 4728bf80f4bSopenharmony_ci auto plugin = static_cast<const I3DPlugin*>(info); 4738bf80f4bSopenharmony_ci if (auto pos = std::find_if(plugins_.begin(), plugins_.end(), 4748bf80f4bSopenharmony_ci [plugin](const pair<PluginToken, const I3DPlugin*>& pluginData) { 4758bf80f4bSopenharmony_ci return pluginData.second == plugin; 4768bf80f4bSopenharmony_ci }); 4778bf80f4bSopenharmony_ci pos != plugins_.end()) { 4788bf80f4bSopenharmony_ci if (plugin->destroyPlugin) { 4798bf80f4bSopenharmony_ci plugin->destroyPlugin(pos->first); 4808bf80f4bSopenharmony_ci } 4818bf80f4bSopenharmony_ci plugins_.erase(pos); 4828bf80f4bSopenharmony_ci } 4838bf80f4bSopenharmony_ci } 4848bf80f4bSopenharmony_ci } 4858bf80f4bSopenharmony_ci } 4868bf80f4bSopenharmony_ci} 4878bf80f4bSopenharmony_ci 4888bf80f4bSopenharmony_civoid RegisterTypes(IPluginRegister& pluginRegistry); 4898bf80f4bSopenharmony_civoid UnregisterTypes(IPluginRegister& pluginRegistry); 4908bf80f4bSopenharmony_ci 4918bf80f4bSopenharmony_cinamespace { 4928bf80f4bSopenharmony_ciPluginToken CreatePlugin3D(IRenderContext& context) 4938bf80f4bSopenharmony_ci{ 4948bf80f4bSopenharmony_ci Agp3DPluginState* token = new Agp3DPluginState { context, {}, {}, {}, {}, {} }; 4958bf80f4bSopenharmony_ci auto& registry = *context.GetInterface<IClassRegister>(); 4968bf80f4bSopenharmony_ci for (const auto& info : token->interfaces) { 4978bf80f4bSopenharmony_ci registry.RegisterInterfaceType(info); 4988bf80f4bSopenharmony_ci } 4998bf80f4bSopenharmony_ci 5008bf80f4bSopenharmony_ci IFileManager& fileManager = context.GetEngine().GetFileManager(); 5018bf80f4bSopenharmony_ci#if (CORE3D_EMBEDDED_ASSETS_ENABLED == 1) 5028bf80f4bSopenharmony_ci // Create engine:// protocol that points to embedded asset files. 5038bf80f4bSopenharmony_ci fileManager.RegisterFilesystem("rofs3D", fileManager.CreateROFilesystem(BINARY_DATA_FOR_3D, SIZE_OF_DATA_FOR_3D)); 5048bf80f4bSopenharmony_ci#endif 5058bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < countof(RENDER_DATA_PATHS); ++idx) { 5068bf80f4bSopenharmony_ci fileManager.RegisterPath(RENDER_DATA_PATHS[idx].protocol, RENDER_DATA_PATHS[idx].uri, false); 5078bf80f4bSopenharmony_ci } 5088bf80f4bSopenharmony_ci context.GetDevice().GetShaderManager().LoadShaderFiles(SHADER_FILE_PATHS); 5098bf80f4bSopenharmony_ci 5108bf80f4bSopenharmony_ci CreateDefaultResources(context.GetDevice(), token->defaultGpuResources); 5118bf80f4bSopenharmony_ci { 5128bf80f4bSopenharmony_ci auto* renderDataConfigurationLoader = CORE_NS::GetInstance<IRenderDataConfigurationLoader>( 5138bf80f4bSopenharmony_ci *context.GetInterface<IClassRegister>(), UID_RENDER_DATA_CONFIGURATION_LOADER); 5148bf80f4bSopenharmony_ci auto* dataStore = context.GetRenderDataStoreManager().GetRenderDataStore(POST_PROCESS_DATA_STORE_NAME); 5158bf80f4bSopenharmony_ci if (renderDataConfigurationLoader && dataStore) { 5168bf80f4bSopenharmony_ci auto& fileMgr = context.GetEngine().GetFileManager(); 5178bf80f4bSopenharmony_ci constexpr string_view ppPath = POST_PROCESS_PATH; 5188bf80f4bSopenharmony_ci if (auto dir = fileMgr.OpenDirectory(ppPath); dir) { 5198bf80f4bSopenharmony_ci for (const auto& entry : dir->GetEntries()) { 5208bf80f4bSopenharmony_ci if (entry.type == IDirectory::Entry::Type::FILE) { 5218bf80f4bSopenharmony_ci const auto loadedPP = 5228bf80f4bSopenharmony_ci renderDataConfigurationLoader->LoadPostProcess(fileMgr, ppPath + entry.name); 5238bf80f4bSopenharmony_ci if (loadedPP.loadResult.success) { 5248bf80f4bSopenharmony_ci token->defaultPostProcesses.push_back(loadedPP.name); 5258bf80f4bSopenharmony_ci auto pod = static_cast<IRenderDataStorePod*>(dataStore); 5268bf80f4bSopenharmony_ci pod->CreatePod( 5278bf80f4bSopenharmony_ci POST_PROCESS_NAME, loadedPP.name, arrayviewU8(loadedPP.postProcessConfiguration)); 5288bf80f4bSopenharmony_ci } 5298bf80f4bSopenharmony_ci } 5308bf80f4bSopenharmony_ci } 5318bf80f4bSopenharmony_ci } 5328bf80f4bSopenharmony_ci } 5338bf80f4bSopenharmony_ci } 5348bf80f4bSopenharmony_ci 5358bf80f4bSopenharmony_ci return token; 5368bf80f4bSopenharmony_ci} 5378bf80f4bSopenharmony_ci 5388bf80f4bSopenharmony_civoid DestroyPlugin3D(PluginToken token) 5398bf80f4bSopenharmony_ci{ 5408bf80f4bSopenharmony_ci Agp3DPluginState* state = static_cast<Agp3DPluginState*>(token); 5418bf80f4bSopenharmony_ci IFileManager& fileManager = state->renderContext.GetEngine().GetFileManager(); 5428bf80f4bSopenharmony_ci 5438bf80f4bSopenharmony_ci state->defaultGpuResources.clear(); 5448bf80f4bSopenharmony_ci { 5458bf80f4bSopenharmony_ci auto* renderDataConfigurationLoader = CORE_NS::GetInstance<IRenderDataConfigurationLoader>( 5468bf80f4bSopenharmony_ci *state->renderContext.GetInterface<IClassRegister>(), UID_RENDER_DATA_CONFIGURATION_LOADER); 5478bf80f4bSopenharmony_ci auto* dataStore = 5488bf80f4bSopenharmony_ci state->renderContext.GetRenderDataStoreManager().GetRenderDataStore(POST_PROCESS_DATA_STORE_NAME); 5498bf80f4bSopenharmony_ci if (renderDataConfigurationLoader && dataStore) { 5508bf80f4bSopenharmony_ci auto pod = static_cast<IRenderDataStorePod*>(dataStore); 5518bf80f4bSopenharmony_ci for (const auto& ref : state->defaultPostProcesses) { 5528bf80f4bSopenharmony_ci pod->DestroyPod(POST_PROCESS_NAME, ref); 5538bf80f4bSopenharmony_ci } 5548bf80f4bSopenharmony_ci } 5558bf80f4bSopenharmony_ci state->defaultPostProcesses.clear(); 5568bf80f4bSopenharmony_ci } 5578bf80f4bSopenharmony_ci state->renderContext.GetDevice().GetShaderManager().UnloadShaderFiles(SHADER_FILE_PATHS); 5588bf80f4bSopenharmony_ci#if (CORE3D_EMBEDDED_ASSETS_ENABLED == 1) 5598bf80f4bSopenharmony_ci fileManager.UnregisterFilesystem("rofs3D"); 5608bf80f4bSopenharmony_ci#endif 5618bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < countof(RENDER_DATA_PATHS); ++idx) { 5628bf80f4bSopenharmony_ci fileManager.UnregisterPath(RENDER_DATA_PATHS[idx].protocol, RENDER_DATA_PATHS[idx].uri); 5638bf80f4bSopenharmony_ci } 5648bf80f4bSopenharmony_ci 5658bf80f4bSopenharmony_ci auto& registry = *state->renderContext.GetInterface<IClassRegister>(); 5668bf80f4bSopenharmony_ci for (const auto& info : state->interfaces) { 5678bf80f4bSopenharmony_ci registry.UnregisterInterfaceType(info); 5688bf80f4bSopenharmony_ci } 5698bf80f4bSopenharmony_ci 5708bf80f4bSopenharmony_ci delete state; 5718bf80f4bSopenharmony_ci} 5728bf80f4bSopenharmony_ci 5738bf80f4bSopenharmony_ciPluginToken CreateEcsPlugin3D(IEcs& ecs) 5748bf80f4bSopenharmony_ci{ 5758bf80f4bSopenharmony_ci return {}; 5768bf80f4bSopenharmony_ci} 5778bf80f4bSopenharmony_ci 5788bf80f4bSopenharmony_civoid DestroyEcsPlugin3D(PluginToken token) {} 5798bf80f4bSopenharmony_ci 5808bf80f4bSopenharmony_ciconstexpr IRenderPlugin RENDER_PLUGIN(CreatePlugin3D, DestroyPlugin3D); 5818bf80f4bSopenharmony_ciconstexpr IEcsPlugin ECS_PLUGIN(CreateEcsPlugin3D, DestroyEcsPlugin3D); 5828bf80f4bSopenharmony_ci} // namespace 5838bf80f4bSopenharmony_ci 5848bf80f4bSopenharmony_ciPluginToken RegisterInterfaces3D(IPluginRegister& pluginRegistry) 5858bf80f4bSopenharmony_ci{ 5868bf80f4bSopenharmony_ci InitRegistry(pluginRegistry); 5878bf80f4bSopenharmony_ci pluginRegistry.RegisterTypeInfo(RENDER_PLUGIN); 5888bf80f4bSopenharmony_ci pluginRegistry.RegisterTypeInfo(ECS_PLUGIN); 5898bf80f4bSopenharmony_ci 5908bf80f4bSopenharmony_ci RegisterTypes(GetPluginRegister()); 5918bf80f4bSopenharmony_ci 5928bf80f4bSopenharmony_ci return &pluginRegistry; 5938bf80f4bSopenharmony_ci} 5948bf80f4bSopenharmony_ci 5958bf80f4bSopenharmony_civoid UnregisterInterfaces3D(PluginToken token) 5968bf80f4bSopenharmony_ci{ 5978bf80f4bSopenharmony_ci IPluginRegister* pluginRegistry = static_cast<IPluginRegister*>(token); 5988bf80f4bSopenharmony_ci 5998bf80f4bSopenharmony_ci UnregisterTypes(GetPluginRegister()); 6008bf80f4bSopenharmony_ci 6018bf80f4bSopenharmony_ci pluginRegistry->UnregisterTypeInfo(ECS_PLUGIN); 6028bf80f4bSopenharmony_ci pluginRegistry->UnregisterTypeInfo(RENDER_PLUGIN); 6038bf80f4bSopenharmony_ci} 6048bf80f4bSopenharmony_ciCORE3D_END_NAMESPACE() 605