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 "render_context.h"
178bf80f4bSopenharmony_ci
188bf80f4bSopenharmony_ci#include <base/containers/fixed_string.h>
198bf80f4bSopenharmony_ci#include <base/containers/vector.h>
208bf80f4bSopenharmony_ci#include <core/intf_engine.h>
218bf80f4bSopenharmony_ci#include <core/io/intf_file_manager.h>
228bf80f4bSopenharmony_ci#include <core/plugin/intf_class_register.h>
238bf80f4bSopenharmony_ci
248bf80f4bSopenharmony_ci#if (RENDER_PERF_ENABLED == 1)
258bf80f4bSopenharmony_ci#include <core/perf/intf_performance_data_manager.h>
268bf80f4bSopenharmony_ci#endif
278bf80f4bSopenharmony_ci
288bf80f4bSopenharmony_ci#include "datastore/render_data_store_default_acceleration_structure_staging.h"
298bf80f4bSopenharmony_ci#include "datastore/render_data_store_default_gpu_resource_data_copy.h"
308bf80f4bSopenharmony_ci#include "datastore/render_data_store_default_staging.h"
318bf80f4bSopenharmony_ci#include "datastore/render_data_store_manager.h"
328bf80f4bSopenharmony_ci#include "datastore/render_data_store_pod.h"
338bf80f4bSopenharmony_ci#include "datastore/render_data_store_post_process.h"
348bf80f4bSopenharmony_ci#include "datastore/render_data_store_shader_passes.h"
358bf80f4bSopenharmony_ci#include "default_engine_constants.h"
368bf80f4bSopenharmony_ci#include "device/device.h"
378bf80f4bSopenharmony_ci#include "device/shader_manager.h"
388bf80f4bSopenharmony_ci#include "loader/render_data_loader.h"
398bf80f4bSopenharmony_ci#include "node/core_render_node_factory.h"
408bf80f4bSopenharmony_ci#include "nodecontext/render_node_graph_manager.h"
418bf80f4bSopenharmony_ci#include "nodecontext/render_node_graph_node_store.h"
428bf80f4bSopenharmony_ci#include "nodecontext/render_node_manager.h"
438bf80f4bSopenharmony_ci#include "nodecontext/render_node_post_process_util.h"
448bf80f4bSopenharmony_ci#include "renderer.h"
458bf80f4bSopenharmony_ci#include "util/render_util.h"
468bf80f4bSopenharmony_ci
478bf80f4bSopenharmony_ci#if RENDER_HAS_VULKAN_BACKEND
488bf80f4bSopenharmony_ci#include "vulkan/device_vk.h"
498bf80f4bSopenharmony_ci#endif
508bf80f4bSopenharmony_ci
518bf80f4bSopenharmony_ci#if (RENDER_HAS_GL_BACKEND) || (RENDER_HAS_GLES_BACKEND)
528bf80f4bSopenharmony_ci#include "gles/device_gles.h"
538bf80f4bSopenharmony_ci#include "gles/swapchain_gles.h"
548bf80f4bSopenharmony_ci#endif
558bf80f4bSopenharmony_ci
568bf80f4bSopenharmony_ci#include <algorithm>
578bf80f4bSopenharmony_ci
588bf80f4bSopenharmony_ciusing namespace BASE_NS;
598bf80f4bSopenharmony_ciusing namespace CORE_NS;
608bf80f4bSopenharmony_ci
618bf80f4bSopenharmony_ciRENDER_BEGIN_NAMESPACE()
628bf80f4bSopenharmony_cinamespace {
638bf80f4bSopenharmony_cistruct RegisterPathStrings {
648bf80f4bSopenharmony_ci    string_view protocol;
658bf80f4bSopenharmony_ci    string_view uri;
668bf80f4bSopenharmony_ci};
678bf80f4bSopenharmony_cistatic constexpr RegisterPathStrings RENDER_DATA_PATHS[] = {
688bf80f4bSopenharmony_ci    { "rendershaders", "rofsRndr://shaders/" },
698bf80f4bSopenharmony_ci    { "rendershaderstates", "rofsRndr://shaderstates/" },
708bf80f4bSopenharmony_ci    { "rendervertexinputdeclarations", "rofsRndr://vertexinputdeclarations/" },
718bf80f4bSopenharmony_ci    { "renderpipelinelayouts", "rofsRndr://pipelinelayouts/" },
728bf80f4bSopenharmony_ci    { "renderrenderdataconfigurations", "rofsRndr://renderdataconfigurations/" },
738bf80f4bSopenharmony_ci    { "renderrendernodegraphs", "rofsRndr://rendernodegraphs/" },
748bf80f4bSopenharmony_ci};
758bf80f4bSopenharmony_ci
768bf80f4bSopenharmony_ci#if (RENDER_EMBEDDED_ASSETS_ENABLED == 1)
778bf80f4bSopenharmony_ci// Core Rofs Data.
788bf80f4bSopenharmony_ciextern "C" const uint64_t SIZEOFDATAFORRENDER;
798bf80f4bSopenharmony_ciextern "C" const void* const BINARYDATAFORRENDER[];
808bf80f4bSopenharmony_ci#endif
818bf80f4bSopenharmony_ci
828bf80f4bSopenharmony_ci// This is defined in the CMake generated version.cpp
838bf80f4bSopenharmony_civoid LogRenderBuildInfo()
848bf80f4bSopenharmony_ci{
858bf80f4bSopenharmony_ci#define RENDER_TO_STRING_INTERNAL(x) #x
868bf80f4bSopenharmony_ci#define RENDER_TO_STRING(x) RENDER_TO_STRING_INTERNAL(x)
878bf80f4bSopenharmony_ci
888bf80f4bSopenharmony_ci    PLUGIN_LOG_I("RENDER_VALIDATION_ENABLED=" RENDER_TO_STRING(RENDER_VALIDATION_ENABLED));
898bf80f4bSopenharmony_ci    PLUGIN_LOG_I("RENDER_DEV_ENABLED=" RENDER_TO_STRING(RENDER_DEV_ENABLED));
908bf80f4bSopenharmony_ci}
918bf80f4bSopenharmony_ci
928bf80f4bSopenharmony_citemplate<class RenderDataStoreType>
938bf80f4bSopenharmony_ciRenderDataStoreTypeInfo FillRenderDataStoreTypeInfo()
948bf80f4bSopenharmony_ci{
958bf80f4bSopenharmony_ci    return {
968bf80f4bSopenharmony_ci        { RenderDataStoreTypeInfo::UID },
978bf80f4bSopenharmony_ci        RenderDataStoreType::UID,
988bf80f4bSopenharmony_ci        RenderDataStoreType::TYPE_NAME,
998bf80f4bSopenharmony_ci        RenderDataStoreType::Create,
1008bf80f4bSopenharmony_ci        RenderDataStoreType::Destroy,
1018bf80f4bSopenharmony_ci    };
1028bf80f4bSopenharmony_ci}
1038bf80f4bSopenharmony_ci
1048bf80f4bSopenharmony_civoid RegisterCoreRenderDataStores(RenderDataStoreManager& renderDataStoreManager)
1058bf80f4bSopenharmony_ci{
1068bf80f4bSopenharmony_ci    renderDataStoreManager.AddRenderDataStoreFactory(FillRenderDataStoreTypeInfo<RenderDataStorePod>());
1078bf80f4bSopenharmony_ci    renderDataStoreManager.AddRenderDataStoreFactory(
1088bf80f4bSopenharmony_ci        FillRenderDataStoreTypeInfo<RenderDataStoreDefaultAccelerationStructureStaging>());
1098bf80f4bSopenharmony_ci    renderDataStoreManager.AddRenderDataStoreFactory(FillRenderDataStoreTypeInfo<RenderDataStoreDefaultStaging>());
1108bf80f4bSopenharmony_ci    renderDataStoreManager.AddRenderDataStoreFactory(
1118bf80f4bSopenharmony_ci        FillRenderDataStoreTypeInfo<RenderDataStoreDefaultGpuResourceDataCopy>());
1128bf80f4bSopenharmony_ci    renderDataStoreManager.AddRenderDataStoreFactory(FillRenderDataStoreTypeInfo<RenderDataStoreShaderPasses>());
1138bf80f4bSopenharmony_ci    renderDataStoreManager.AddRenderDataStoreFactory(FillRenderDataStoreTypeInfo<RenderDataStorePostProcess>());
1148bf80f4bSopenharmony_ci}
1158bf80f4bSopenharmony_ci
1168bf80f4bSopenharmony_citemplate<typename DataStoreType>
1178bf80f4bSopenharmony_ciIRenderDataStore* CreateDataStore(IRenderDataStoreManager& renderDataStoreManager, const string_view name)
1188bf80f4bSopenharmony_ci{
1198bf80f4bSopenharmony_ci    IRenderDataStore* renderDataStore = renderDataStoreManager.Create(DataStoreType::UID, name.data());
1208bf80f4bSopenharmony_ci    PLUGIN_ASSERT(renderDataStore);
1218bf80f4bSopenharmony_ci    return renderDataStore;
1228bf80f4bSopenharmony_ci}
1238bf80f4bSopenharmony_ci
1248bf80f4bSopenharmony_civoid CreateDefaultRenderDataStores(IRenderDataStoreManager& renderDataStoreManager, RenderDataLoader& renderDataLoader)
1258bf80f4bSopenharmony_ci{
1268bf80f4bSopenharmony_ci    // add pod store
1278bf80f4bSopenharmony_ci    {
1288bf80f4bSopenharmony_ci        auto renderDataStorePod =
1298bf80f4bSopenharmony_ci            CreateDataStore<RenderDataStorePod>(renderDataStoreManager, RenderDataStorePod::TYPE_NAME);
1308bf80f4bSopenharmony_ci        if (renderDataStorePod) {
1318bf80f4bSopenharmony_ci            IRenderDataStorePod* renderDataStorePodTyped = static_cast<IRenderDataStorePod*>(renderDataStorePod);
1328bf80f4bSopenharmony_ci
1338bf80f4bSopenharmony_ci            NodeGraphBackBufferConfiguration backBufferConfig {};
1348bf80f4bSopenharmony_ci            const auto len =
1358bf80f4bSopenharmony_ci                DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER.copy(backBufferConfig.backBufferName,
1368bf80f4bSopenharmony_ci                    NodeGraphBackBufferConfiguration::CORE_MAX_BACK_BUFFER_NAME_LENGTH - 1);
1378bf80f4bSopenharmony_ci            backBufferConfig.backBufferName[len] = '\0';
1388bf80f4bSopenharmony_ci            renderDataStorePodTyped->CreatePod(
1398bf80f4bSopenharmony_ci                "NodeGraphConfiguration", "NodeGraphBackBufferConfiguration", arrayviewU8(backBufferConfig));
1408bf80f4bSopenharmony_ci
1418bf80f4bSopenharmony_ci            // load and store configurations
1428bf80f4bSopenharmony_ci            renderDataLoader.Load("render", *renderDataStorePodTyped);
1438bf80f4bSopenharmony_ci        }
1448bf80f4bSopenharmony_ci    }
1458bf80f4bSopenharmony_ci
1468bf80f4bSopenharmony_ci    CreateDataStore<RenderDataStoreDefaultAccelerationStructureStaging>(
1478bf80f4bSopenharmony_ci        renderDataStoreManager, RenderDataStoreDefaultAccelerationStructureStaging::TYPE_NAME);
1488bf80f4bSopenharmony_ci    CreateDataStore<RenderDataStoreDefaultStaging>(renderDataStoreManager, RenderDataStoreDefaultStaging::TYPE_NAME);
1498bf80f4bSopenharmony_ci    CreateDataStore<RenderDataStoreDefaultGpuResourceDataCopy>(
1508bf80f4bSopenharmony_ci        renderDataStoreManager, RenderDataStoreDefaultGpuResourceDataCopy::TYPE_NAME);
1518bf80f4bSopenharmony_ci    CreateDataStore<RenderDataStoreShaderPasses>(renderDataStoreManager, RenderDataStoreShaderPasses::TYPE_NAME);
1528bf80f4bSopenharmony_ci    CreateDataStore<RenderDataStorePostProcess>(renderDataStoreManager, RenderDataStorePostProcess::TYPE_NAME);
1538bf80f4bSopenharmony_ci}
1548bf80f4bSopenharmony_ci
1558bf80f4bSopenharmony_civoid CreateDefaultBuffers(IGpuResourceManager& gpuResourceMgr, vector<RenderHandleReference>& defaultGpuResources)
1568bf80f4bSopenharmony_ci{
1578bf80f4bSopenharmony_ci    defaultGpuResources.push_back(gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_GPU_BUFFER,
1588bf80f4bSopenharmony_ci        GpuBufferDesc { CORE_BUFFER_USAGE_TRANSFER_SRC_BIT | CORE_BUFFER_USAGE_TRANSFER_DST_BIT |
1598bf80f4bSopenharmony_ci                            CORE_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | CORE_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
1608bf80f4bSopenharmony_ci                            CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT | CORE_BUFFER_USAGE_STORAGE_BUFFER_BIT |
1618bf80f4bSopenharmony_ci                            CORE_BUFFER_USAGE_INDEX_BUFFER_BIT | CORE_BUFFER_USAGE_VERTEX_BUFFER_BIT |
1628bf80f4bSopenharmony_ci                            CORE_BUFFER_USAGE_INDIRECT_BUFFER_BIT | CORE_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT |
1638bf80f4bSopenharmony_ci                            CORE_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT,
1648bf80f4bSopenharmony_ci            (CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT), 0u, 1024u }));
1658bf80f4bSopenharmony_ci}
1668bf80f4bSopenharmony_ci
1678bf80f4bSopenharmony_civoid CreateDefaultTextures(IGpuResourceManager& gpuResourceMgr, vector<RenderHandleReference>& defaultGpuResources)
1688bf80f4bSopenharmony_ci{
1698bf80f4bSopenharmony_ci    GpuImageDesc desc { ImageType::CORE_IMAGE_TYPE_2D, ImageViewType::CORE_IMAGE_VIEW_TYPE_2D,
1708bf80f4bSopenharmony_ci        Format::BASE_FORMAT_R8G8B8A8_UNORM, ImageTiling::CORE_IMAGE_TILING_OPTIMAL,
1718bf80f4bSopenharmony_ci        ImageUsageFlagBits::CORE_IMAGE_USAGE_SAMPLED_BIT | ImageUsageFlagBits::CORE_IMAGE_USAGE_TRANSFER_DST_BIT,
1728bf80f4bSopenharmony_ci        MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
1738bf80f4bSopenharmony_ci        0, // ImageCreateFlags
1748bf80f4bSopenharmony_ci        0, // EngineImageCreationFlags
1758bf80f4bSopenharmony_ci        2, 2, 1, 1, 1, SampleCountFlagBits::CORE_SAMPLE_COUNT_1_BIT, {} };
1768bf80f4bSopenharmony_ci
1778bf80f4bSopenharmony_ci    constexpr uint32_t sizeOfUint32 = sizeof(uint32_t);
1788bf80f4bSopenharmony_ci    constexpr const uint32_t rgbData[4u] = { 0x0, 0x0, 0x0, 0x0 };
1798bf80f4bSopenharmony_ci    const auto rgbDataView = array_view(reinterpret_cast<const uint8_t*>(rgbData), sizeOfUint32 * countof(rgbData));
1808bf80f4bSopenharmony_ci    defaultGpuResources.push_back(
1818bf80f4bSopenharmony_ci        gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_GPU_IMAGE, desc, rgbDataView));
1828bf80f4bSopenharmony_ci    constexpr const uint32_t rgbDataWhite[4u] = { 0xFFFFffff, 0xFFFFffff, 0xFFFFffff, 0xFFFFffff };
1838bf80f4bSopenharmony_ci    const auto rgbDataViewWhite =
1848bf80f4bSopenharmony_ci        array_view(reinterpret_cast<const uint8_t*>(rgbDataWhite), sizeOfUint32 * countof(rgbDataWhite));
1858bf80f4bSopenharmony_ci    defaultGpuResources.push_back(
1868bf80f4bSopenharmony_ci        gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_GPU_IMAGE_WHITE, desc, rgbDataViewWhite));
1878bf80f4bSopenharmony_ci}
1888bf80f4bSopenharmony_ci
1898bf80f4bSopenharmony_civoid CreateDefaultTargets(IGpuResourceManager& gpuResourceMgr, vector<RenderHandleReference>& defaultGpuResources)
1908bf80f4bSopenharmony_ci{
1918bf80f4bSopenharmony_ci    {
1928bf80f4bSopenharmony_ci        // hard-coded default backbuffer
1938bf80f4bSopenharmony_ci        // all presentations and swapchain semaphore syncs are done automatically for this client handle
1948bf80f4bSopenharmony_ci        GpuImageDesc desc {
1958bf80f4bSopenharmony_ci            ImageType::CORE_IMAGE_TYPE_2D,
1968bf80f4bSopenharmony_ci            ImageViewType::CORE_IMAGE_VIEW_TYPE_2D,
1978bf80f4bSopenharmony_ci            Format::BASE_FORMAT_R8G8B8A8_UNORM,
1988bf80f4bSopenharmony_ci            ImageTiling::CORE_IMAGE_TILING_OPTIMAL,
1998bf80f4bSopenharmony_ci            ImageUsageFlagBits::CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
2008bf80f4bSopenharmony_ci            MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2018bf80f4bSopenharmony_ci            0, // ImageCreateFlags
2028bf80f4bSopenharmony_ci            EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_RESET_STATE_ON_FRAME_BORDERS |
2038bf80f4bSopenharmony_ci                EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, // EngineImageCreationFlags
2048bf80f4bSopenharmony_ci            2,
2058bf80f4bSopenharmony_ci            2,
2068bf80f4bSopenharmony_ci            1,
2078bf80f4bSopenharmony_ci            1,
2088bf80f4bSopenharmony_ci            1,
2098bf80f4bSopenharmony_ci            SampleCountFlagBits::CORE_SAMPLE_COUNT_1_BIT,
2108bf80f4bSopenharmony_ci            {},
2118bf80f4bSopenharmony_ci        };
2128bf80f4bSopenharmony_ci        GpuResourceManager& gpuResourceMgrImpl = (GpuResourceManager&)gpuResourceMgr;
2138bf80f4bSopenharmony_ci        // create as a swapchain image to get correct handle flags for fast check-up for additional processing
2148bf80f4bSopenharmony_ci        defaultGpuResources.push_back(gpuResourceMgrImpl.CreateSwapchainImage(
2158bf80f4bSopenharmony_ci            {}, DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER, desc));
2168bf80f4bSopenharmony_ci    }
2178bf80f4bSopenharmony_ci    {
2188bf80f4bSopenharmony_ci        GpuImageDesc desc {
2198bf80f4bSopenharmony_ci            ImageType::CORE_IMAGE_TYPE_2D,
2208bf80f4bSopenharmony_ci            ImageViewType::CORE_IMAGE_VIEW_TYPE_2D,
2218bf80f4bSopenharmony_ci            Format::BASE_FORMAT_D16_UNORM,
2228bf80f4bSopenharmony_ci            ImageTiling::CORE_IMAGE_TILING_OPTIMAL,
2238bf80f4bSopenharmony_ci            ImageUsageFlagBits::CORE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
2248bf80f4bSopenharmony_ci                ImageUsageFlagBits::CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
2258bf80f4bSopenharmony_ci            MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
2268bf80f4bSopenharmony_ci                MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT,
2278bf80f4bSopenharmony_ci            0,                                                                        // ImageCreateFlags
2288bf80f4bSopenharmony_ci            EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, // EngineImageCreationFlags
2298bf80f4bSopenharmony_ci            2,
2308bf80f4bSopenharmony_ci            2,
2318bf80f4bSopenharmony_ci            1,
2328bf80f4bSopenharmony_ci            1,
2338bf80f4bSopenharmony_ci            1,
2348bf80f4bSopenharmony_ci            SampleCountFlagBits::CORE_SAMPLE_COUNT_1_BIT,
2358bf80f4bSopenharmony_ci            {},
2368bf80f4bSopenharmony_ci        };
2378bf80f4bSopenharmony_ci        defaultGpuResources.push_back(
2388bf80f4bSopenharmony_ci            gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER_DEPTH, desc));
2398bf80f4bSopenharmony_ci    }
2408bf80f4bSopenharmony_ci}
2418bf80f4bSopenharmony_ci
2428bf80f4bSopenharmony_civoid CreateDefaultSamplers(IGpuResourceManager& gpuResourceMgr, vector<RenderHandleReference>& defaultGpuResources)
2438bf80f4bSopenharmony_ci{
2448bf80f4bSopenharmony_ci    defaultGpuResources.push_back(
2458bf80f4bSopenharmony_ci        gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_NEAREST_REPEAT,
2468bf80f4bSopenharmony_ci            GpuSamplerDesc {
2478bf80f4bSopenharmony_ci                Filter::CORE_FILTER_NEAREST,                          // magFilter
2488bf80f4bSopenharmony_ci                Filter::CORE_FILTER_NEAREST,                          // minFilter
2498bf80f4bSopenharmony_ci                Filter::CORE_FILTER_NEAREST,                          // mipMapMode
2508bf80f4bSopenharmony_ci                SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeU
2518bf80f4bSopenharmony_ci                SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeV
2528bf80f4bSopenharmony_ci                SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeW
2538bf80f4bSopenharmony_ci            }));
2548bf80f4bSopenharmony_ci    defaultGpuResources.push_back(
2558bf80f4bSopenharmony_ci        gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_NEAREST_CLAMP,
2568bf80f4bSopenharmony_ci            GpuSamplerDesc {
2578bf80f4bSopenharmony_ci                Filter::CORE_FILTER_NEAREST,                                 // magFilter
2588bf80f4bSopenharmony_ci                Filter::CORE_FILTER_NEAREST,                                 // minFilter
2598bf80f4bSopenharmony_ci                Filter::CORE_FILTER_NEAREST,                                 // mipMapMode
2608bf80f4bSopenharmony_ci                SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
2618bf80f4bSopenharmony_ci                SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
2628bf80f4bSopenharmony_ci                SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
2638bf80f4bSopenharmony_ci            }));
2648bf80f4bSopenharmony_ci
2658bf80f4bSopenharmony_ci    defaultGpuResources.push_back(
2668bf80f4bSopenharmony_ci        gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_REPEAT,
2678bf80f4bSopenharmony_ci            GpuSamplerDesc {
2688bf80f4bSopenharmony_ci                Filter::CORE_FILTER_LINEAR,                           // magFilter
2698bf80f4bSopenharmony_ci                Filter::CORE_FILTER_LINEAR,                           // minFilter
2708bf80f4bSopenharmony_ci                Filter::CORE_FILTER_LINEAR,                           // mipMapMode
2718bf80f4bSopenharmony_ci                SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeU
2728bf80f4bSopenharmony_ci                SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeV
2738bf80f4bSopenharmony_ci                SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeW
2748bf80f4bSopenharmony_ci            }));
2758bf80f4bSopenharmony_ci    defaultGpuResources.push_back(
2768bf80f4bSopenharmony_ci        gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_CLAMP,
2778bf80f4bSopenharmony_ci            GpuSamplerDesc {
2788bf80f4bSopenharmony_ci                Filter::CORE_FILTER_LINEAR,                                  // magFilter
2798bf80f4bSopenharmony_ci                Filter::CORE_FILTER_LINEAR,                                  // minFilter
2808bf80f4bSopenharmony_ci                Filter::CORE_FILTER_LINEAR,                                  // mipMapMode
2818bf80f4bSopenharmony_ci                SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
2828bf80f4bSopenharmony_ci                SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
2838bf80f4bSopenharmony_ci                SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
2848bf80f4bSopenharmony_ci            }));
2858bf80f4bSopenharmony_ci
2868bf80f4bSopenharmony_ci    GpuSamplerDesc linearMipmapRepeat {
2878bf80f4bSopenharmony_ci        Filter::CORE_FILTER_LINEAR,                           // magFilter
2888bf80f4bSopenharmony_ci        Filter::CORE_FILTER_LINEAR,                           // minFilter
2898bf80f4bSopenharmony_ci        Filter::CORE_FILTER_LINEAR,                           // mipMapMode
2908bf80f4bSopenharmony_ci        SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeU
2918bf80f4bSopenharmony_ci        SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeV
2928bf80f4bSopenharmony_ci        SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeW
2938bf80f4bSopenharmony_ci    };
2948bf80f4bSopenharmony_ci    linearMipmapRepeat.minLod = 0.0f;
2958bf80f4bSopenharmony_ci    linearMipmapRepeat.maxLod = 32.0f;
2968bf80f4bSopenharmony_ci    defaultGpuResources.push_back(gpuResourceMgr.Create(
2978bf80f4bSopenharmony_ci        DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_MIPMAP_REPEAT, linearMipmapRepeat));
2988bf80f4bSopenharmony_ci    GpuSamplerDesc linearMipmapClamp {
2998bf80f4bSopenharmony_ci        Filter::CORE_FILTER_LINEAR,                                  // magFilter
3008bf80f4bSopenharmony_ci        Filter::CORE_FILTER_LINEAR,                                  // minFilter
3018bf80f4bSopenharmony_ci        Filter::CORE_FILTER_LINEAR,                                  // mipMapMode
3028bf80f4bSopenharmony_ci        SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
3038bf80f4bSopenharmony_ci        SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
3048bf80f4bSopenharmony_ci        SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
3058bf80f4bSopenharmony_ci    };
3068bf80f4bSopenharmony_ci    linearMipmapClamp.minLod = 0.0f;
3078bf80f4bSopenharmony_ci    linearMipmapClamp.maxLod = 32.0f;
3088bf80f4bSopenharmony_ci    defaultGpuResources.push_back(gpuResourceMgr.Create(
3098bf80f4bSopenharmony_ci        DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_MIPMAP_CLAMP, linearMipmapClamp));
3108bf80f4bSopenharmony_ci}
3118bf80f4bSopenharmony_ci
3128bf80f4bSopenharmony_cistring_view GetPipelineCacheUri(DeviceBackendType backendType)
3138bf80f4bSopenharmony_ci{
3148bf80f4bSopenharmony_ci    switch (backendType) {
3158bf80f4bSopenharmony_ci        case DeviceBackendType::VULKAN:
3168bf80f4bSopenharmony_ci            return "cache://deviceVkCache.bin";
3178bf80f4bSopenharmony_ci        case DeviceBackendType::OPENGLES:
3188bf80f4bSopenharmony_ci            return "cache://deviceGLESCache.bin";
3198bf80f4bSopenharmony_ci        case DeviceBackendType::OPENGL:
3208bf80f4bSopenharmony_ci            return "cache://deviceGLCache.bin";
3218bf80f4bSopenharmony_ci        default:
3228bf80f4bSopenharmony_ci            break;
3238bf80f4bSopenharmony_ci    }
3248bf80f4bSopenharmony_ci    return "";
3258bf80f4bSopenharmony_ci}
3268bf80f4bSopenharmony_ci} // namespace
3278bf80f4bSopenharmony_ci
3288bf80f4bSopenharmony_ciIRenderContext* RenderPluginState::CreateInstance(IEngine& engine)
3298bf80f4bSopenharmony_ci{
3308bf80f4bSopenharmony_ci    if (!context_) {
3318bf80f4bSopenharmony_ci        context_ = IRenderContext::Ptr { new RenderContext(*this, engine) };
3328bf80f4bSopenharmony_ci    }
3338bf80f4bSopenharmony_ci    return context_.get();
3348bf80f4bSopenharmony_ci}
3358bf80f4bSopenharmony_ci
3368bf80f4bSopenharmony_ciIRenderContext* RenderPluginState::GetInstance()
3378bf80f4bSopenharmony_ci{
3388bf80f4bSopenharmony_ci    return context_.get();
3398bf80f4bSopenharmony_ci}
3408bf80f4bSopenharmony_ci
3418bf80f4bSopenharmony_civoid RenderPluginState::Destroy()
3428bf80f4bSopenharmony_ci{
3438bf80f4bSopenharmony_ci    context_.reset();
3448bf80f4bSopenharmony_ci}
3458bf80f4bSopenharmony_ci
3468bf80f4bSopenharmony_ciRenderContext::RenderContext(RenderPluginState& pluginState, IEngine& engine)
3478bf80f4bSopenharmony_ci    : pluginState_(pluginState), engine_(engine), fileManager_(&engine.GetFileManager())
3488bf80f4bSopenharmony_ci{
3498bf80f4bSopenharmony_ci    for (const auto& ref : interfaceInfos_) {
3508bf80f4bSopenharmony_ci        RegisterInterfaceType(ref);
3518bf80f4bSopenharmony_ci    }
3528bf80f4bSopenharmony_ci    LogRenderBuildInfo();
3538bf80f4bSopenharmony_ci    RegisterDefaultPaths();
3548bf80f4bSopenharmony_ci}
3558bf80f4bSopenharmony_ci
3568bf80f4bSopenharmony_ciRenderContext::~RenderContext()
3578bf80f4bSopenharmony_ci{
3588bf80f4bSopenharmony_ci    GetPluginRegister().RemoveListener(*this);
3598bf80f4bSopenharmony_ci
3608bf80f4bSopenharmony_ci    if (device_) {
3618bf80f4bSopenharmony_ci        device_->WaitForIdle();
3628bf80f4bSopenharmony_ci    }
3638bf80f4bSopenharmony_ci
3648bf80f4bSopenharmony_ci    for (auto& info : plugins_) {
3658bf80f4bSopenharmony_ci        if (info.second && info.second->destroyPlugin) {
3668bf80f4bSopenharmony_ci            info.second->destroyPlugin(info.first);
3678bf80f4bSopenharmony_ci        }
3688bf80f4bSopenharmony_ci    }
3698bf80f4bSopenharmony_ci
3708bf80f4bSopenharmony_ci    // NOTE: device needs to be active for render resources (e.g. with GLES)
3718bf80f4bSopenharmony_ci    if (device_) {
3728bf80f4bSopenharmony_ci        device_->Activate();
3738bf80f4bSopenharmony_ci
3748bf80f4bSopenharmony_ci        if (device_->GetDeviceConfiguration().configurationFlags & CORE_DEVICE_CONFIGURATION_PIPELINE_CACHE_BIT) {
3758bf80f4bSopenharmony_ci            vector<uint8_t> pipelineCache = device_->GetPipelineCache();
3768bf80f4bSopenharmony_ci            if (auto file = fileManager_->CreateFile(GetPipelineCacheUri(device_->GetBackendType())); file) {
3778bf80f4bSopenharmony_ci                file->Write(pipelineCache.data(), pipelineCache.size());
3788bf80f4bSopenharmony_ci            }
3798bf80f4bSopenharmony_ci        }
3808bf80f4bSopenharmony_ci    }
3818bf80f4bSopenharmony_ci    defaultGpuResources_.clear();
3828bf80f4bSopenharmony_ci    renderer_.reset();
3838bf80f4bSopenharmony_ci    renderNodeGraphMgr_.reset();
3848bf80f4bSopenharmony_ci    renderDataStoreMgr_.reset();
3858bf80f4bSopenharmony_ci    renderUtil_.reset(); // GLES semaphore/fence destruction device needs to be active
3868bf80f4bSopenharmony_ci    if (device_) {
3878bf80f4bSopenharmony_ci        device_->Deactivate();
3888bf80f4bSopenharmony_ci    }
3898bf80f4bSopenharmony_ci}
3908bf80f4bSopenharmony_ci
3918bf80f4bSopenharmony_ciRenderResultCode RenderContext::Init(const RenderCreateInfo& createInfo)
3928bf80f4bSopenharmony_ci{
3938bf80f4bSopenharmony_ci    PLUGIN_LOG_D("Render init.");
3948bf80f4bSopenharmony_ci
3958bf80f4bSopenharmony_ci    createInfo_ = createInfo;
3968bf80f4bSopenharmony_ci    device_ = CreateDevice(createInfo_.deviceCreateInfo);
3978bf80f4bSopenharmony_ci    if (!device_) {
3988bf80f4bSopenharmony_ci        PLUGIN_LOG_E("device not created successfully, invalid render interface");
3998bf80f4bSopenharmony_ci        return RenderResultCode::RENDER_ERROR;
4008bf80f4bSopenharmony_ci    } else {
4018bf80f4bSopenharmony_ci        device_->Activate();
4028bf80f4bSopenharmony_ci
4038bf80f4bSopenharmony_ci        // Initialize the pipeline/ program cache.
4048bf80f4bSopenharmony_ci        if (device_->GetDeviceConfiguration().configurationFlags & CORE_DEVICE_CONFIGURATION_PIPELINE_CACHE_BIT) {
4058bf80f4bSopenharmony_ci            vector<uint8_t> pipelineCache;
4068bf80f4bSopenharmony_ci            if (auto file = fileManager_->OpenFile(GetPipelineCacheUri(device_->GetBackendType())); file) {
4078bf80f4bSopenharmony_ci                pipelineCache.resize(static_cast<size_t>(file->GetLength()));
4088bf80f4bSopenharmony_ci                file->Read(pipelineCache.data(), pipelineCache.size());
4098bf80f4bSopenharmony_ci            }
4108bf80f4bSopenharmony_ci            device_->InitializePipelineCache(pipelineCache);
4118bf80f4bSopenharmony_ci        }
4128bf80f4bSopenharmony_ci
4138bf80f4bSopenharmony_ci        // set engine file manager with registered paths
4148bf80f4bSopenharmony_ci        ShaderManager& shaderMgr = (ShaderManager&)device_->GetShaderManager();
4158bf80f4bSopenharmony_ci        shaderMgr.SetFileManager(engine_.GetFileManager());
4168bf80f4bSopenharmony_ci
4178bf80f4bSopenharmony_ci        {
4188bf80f4bSopenharmony_ci            IShaderManager::ShaderFilePathDesc desc;
4198bf80f4bSopenharmony_ci            desc.shaderPath = "rendershaders://";
4208bf80f4bSopenharmony_ci            desc.pipelineLayoutPath = "renderpipelinelayouts://";
4218bf80f4bSopenharmony_ci            // NOTE: does not have states and vids
4228bf80f4bSopenharmony_ci            shaderMgr.LoadShaderFiles(desc);
4238bf80f4bSopenharmony_ci        }
4248bf80f4bSopenharmony_ci        // make sure shaders found above have been created
4258bf80f4bSopenharmony_ci        shaderMgr.HandlePendingAllocations();
4268bf80f4bSopenharmony_ci
4278bf80f4bSopenharmony_ci        renderDataStoreMgr_ = make_unique<RenderDataStoreManager>(*this);
4288bf80f4bSopenharmony_ci        RegisterCoreRenderDataStores(*renderDataStoreMgr_);
4298bf80f4bSopenharmony_ci
4308bf80f4bSopenharmony_ci        // Add render data stores from plugins
4318bf80f4bSopenharmony_ci        for (auto info : CORE_NS::GetPluginRegister().GetTypeInfos(RenderDataStoreTypeInfo::UID)) {
4328bf80f4bSopenharmony_ci            renderDataStoreMgr_->AddRenderDataStoreFactory(*static_cast<const RenderDataStoreTypeInfo*>(info));
4338bf80f4bSopenharmony_ci        }
4348bf80f4bSopenharmony_ci
4358bf80f4bSopenharmony_ci        auto loader = RenderDataLoader(*fileManager_);
4368bf80f4bSopenharmony_ci        CreateDefaultRenderDataStores(*renderDataStoreMgr_, loader);
4378bf80f4bSopenharmony_ci
4388bf80f4bSopenharmony_ci        renderNodeGraphMgr_ = make_unique<RenderNodeGraphManager>(*device_, *fileManager_);
4398bf80f4bSopenharmony_ci
4408bf80f4bSopenharmony_ci        auto& renderNodeMgr = renderNodeGraphMgr_->GetRenderNodeManager();
4418bf80f4bSopenharmony_ci        RegisterCoreRenderNodes(renderNodeMgr);
4428bf80f4bSopenharmony_ci        // Add render nodes from plugins
4438bf80f4bSopenharmony_ci        for (auto info : CORE_NS::GetPluginRegister().GetTypeInfos(RenderNodeTypeInfo::UID)) {
4448bf80f4bSopenharmony_ci            renderNodeMgr.AddRenderNodeFactory(*static_cast<const RenderNodeTypeInfo*>(info));
4458bf80f4bSopenharmony_ci        }
4468bf80f4bSopenharmony_ci
4478bf80f4bSopenharmony_ci        renderUtil_ = make_unique<RenderUtil>(*this);
4488bf80f4bSopenharmony_ci
4498bf80f4bSopenharmony_ci        renderer_ = make_unique<Renderer>(*this);
4508bf80f4bSopenharmony_ci
4518bf80f4bSopenharmony_ci        IGpuResourceManager& gpuResourceMgr = device_->GetGpuResourceManager();
4528bf80f4bSopenharmony_ci        CreateDefaultBuffers(gpuResourceMgr, defaultGpuResources_);
4538bf80f4bSopenharmony_ci        CreateDefaultTextures(gpuResourceMgr, defaultGpuResources_);
4548bf80f4bSopenharmony_ci        CreateDefaultTargets(gpuResourceMgr, defaultGpuResources_);
4558bf80f4bSopenharmony_ci        CreateDefaultSamplers(gpuResourceMgr, defaultGpuResources_);
4568bf80f4bSopenharmony_ci
4578bf80f4bSopenharmony_ci        device_->Deactivate();
4588bf80f4bSopenharmony_ci
4598bf80f4bSopenharmony_ci        GetPluginRegister().AddListener(*this);
4608bf80f4bSopenharmony_ci
4618bf80f4bSopenharmony_ci        for (auto info : CORE_NS::GetPluginRegister().GetTypeInfos(IRenderPlugin::UID)) {
4628bf80f4bSopenharmony_ci            if (auto renderPlugin = static_cast<const IRenderPlugin*>(info);
4638bf80f4bSopenharmony_ci                renderPlugin && renderPlugin->createPlugin) {
4648bf80f4bSopenharmony_ci                auto token = renderPlugin->createPlugin(*this);
4658bf80f4bSopenharmony_ci                plugins_.push_back({ token, renderPlugin });
4668bf80f4bSopenharmony_ci            }
4678bf80f4bSopenharmony_ci        }
4688bf80f4bSopenharmony_ci
4698bf80f4bSopenharmony_ci        return RenderResultCode::RENDER_SUCCESS;
4708bf80f4bSopenharmony_ci    }
4718bf80f4bSopenharmony_ci}
4728bf80f4bSopenharmony_ci
4738bf80f4bSopenharmony_ciIDevice& RenderContext::GetDevice() const
4748bf80f4bSopenharmony_ci{
4758bf80f4bSopenharmony_ci    if (!device_) {
4768bf80f4bSopenharmony_ci        PLUGIN_LOG_E("Render Init not called or result was not success");
4778bf80f4bSopenharmony_ci    }
4788bf80f4bSopenharmony_ci    return *device_;
4798bf80f4bSopenharmony_ci}
4808bf80f4bSopenharmony_ci
4818bf80f4bSopenharmony_ciIRenderer& RenderContext::GetRenderer() const
4828bf80f4bSopenharmony_ci{
4838bf80f4bSopenharmony_ci    if (!renderer_) {
4848bf80f4bSopenharmony_ci        PLUGIN_LOG_E("Render Init not called or result was not success");
4858bf80f4bSopenharmony_ci    }
4868bf80f4bSopenharmony_ci    return *renderer_;
4878bf80f4bSopenharmony_ci}
4888bf80f4bSopenharmony_ci
4898bf80f4bSopenharmony_ciIRenderDataStoreManager& RenderContext::GetRenderDataStoreManager() const
4908bf80f4bSopenharmony_ci{
4918bf80f4bSopenharmony_ci    if (!renderDataStoreMgr_) {
4928bf80f4bSopenharmony_ci        PLUGIN_LOG_E("Render Init not called or result was not success");
4938bf80f4bSopenharmony_ci    }
4948bf80f4bSopenharmony_ci    return *renderDataStoreMgr_;
4958bf80f4bSopenharmony_ci}
4968bf80f4bSopenharmony_ci
4978bf80f4bSopenharmony_ciIRenderNodeGraphManager& RenderContext::GetRenderNodeGraphManager() const
4988bf80f4bSopenharmony_ci{
4998bf80f4bSopenharmony_ci    if (!renderNodeGraphMgr_) {
5008bf80f4bSopenharmony_ci        PLUGIN_LOG_E("Render Init not called or result was not success");
5018bf80f4bSopenharmony_ci    }
5028bf80f4bSopenharmony_ci    return *renderNodeGraphMgr_;
5038bf80f4bSopenharmony_ci}
5048bf80f4bSopenharmony_ci
5058bf80f4bSopenharmony_ciIRenderUtil& RenderContext::GetRenderUtil() const
5068bf80f4bSopenharmony_ci{
5078bf80f4bSopenharmony_ci    if (!renderUtil_) {
5088bf80f4bSopenharmony_ci        PLUGIN_LOG_E("Render Init not called or result was not success");
5098bf80f4bSopenharmony_ci    }
5108bf80f4bSopenharmony_ci    return *renderUtil_;
5118bf80f4bSopenharmony_ci}
5128bf80f4bSopenharmony_ci
5138bf80f4bSopenharmony_civoid RenderContext::RegisterDefaultPaths()
5148bf80f4bSopenharmony_ci{
5158bf80f4bSopenharmony_ci    // Already handeled during plugin registration. If own filemanager instance is used then these are needed.
5168bf80f4bSopenharmony_ci#if (RENDER_EMBEDDED_ASSETS_ENABLED == 1)
5178bf80f4bSopenharmony_ci    // Create engine:// protocol that points to embedded engine asset files.
5188bf80f4bSopenharmony_ci    PLUGIN_LOG_D("Registered core asset path: 'rofsRndr://render/'");
5198bf80f4bSopenharmony_ci    fileManager_->RegisterPath("render", "rofsRndr://render/", false);
5208bf80f4bSopenharmony_ci#endif
5218bf80f4bSopenharmony_ci    for (uint32_t idx = 0; idx < countof(RENDER_DATA_PATHS); ++idx) {
5228bf80f4bSopenharmony_ci        fileManager_->RegisterPath(RENDER_DATA_PATHS[idx].protocol, RENDER_DATA_PATHS[idx].uri, false);
5238bf80f4bSopenharmony_ci    }
5248bf80f4bSopenharmony_ci}
5258bf80f4bSopenharmony_ci
5268bf80f4bSopenharmony_ciunique_ptr<Device> RenderContext::CreateDevice(const DeviceCreateInfo& createInfo)
5278bf80f4bSopenharmony_ci{
5288bf80f4bSopenharmony_ci    switch (createInfo.backendType) {
5298bf80f4bSopenharmony_ci        case DeviceBackendType::OPENGL:
5308bf80f4bSopenharmony_ci#if (RENDER_HAS_GL_BACKEND)
5318bf80f4bSopenharmony_ci            return CreateDeviceGL(*this, createInfo);
5328bf80f4bSopenharmony_ci#else
5338bf80f4bSopenharmony_ci            return nullptr;
5348bf80f4bSopenharmony_ci#endif
5358bf80f4bSopenharmony_ci        case DeviceBackendType::OPENGLES:
5368bf80f4bSopenharmony_ci#if (RENDER_HAS_GLES_BACKEND)
5378bf80f4bSopenharmony_ci            return CreateDeviceGLES(*this, createInfo);
5388bf80f4bSopenharmony_ci#else
5398bf80f4bSopenharmony_ci            return nullptr;
5408bf80f4bSopenharmony_ci#endif
5418bf80f4bSopenharmony_ci        case DeviceBackendType::VULKAN:
5428bf80f4bSopenharmony_ci#if (RENDER_HAS_VULKAN_BACKEND)
5438bf80f4bSopenharmony_ci            return CreateDeviceVk(*this, createInfo);
5448bf80f4bSopenharmony_ci#else
5458bf80f4bSopenharmony_ci            return nullptr;
5468bf80f4bSopenharmony_ci#endif
5478bf80f4bSopenharmony_ci        default:
5488bf80f4bSopenharmony_ci            break;
5498bf80f4bSopenharmony_ci    }
5508bf80f4bSopenharmony_ci    return nullptr;
5518bf80f4bSopenharmony_ci}
5528bf80f4bSopenharmony_ci
5538bf80f4bSopenharmony_ciIEngine& RenderContext::GetEngine() const
5548bf80f4bSopenharmony_ci{
5558bf80f4bSopenharmony_ci    return engine_;
5568bf80f4bSopenharmony_ci}
5578bf80f4bSopenharmony_ci
5588bf80f4bSopenharmony_cistring_view RenderContext::GetVersion()
5598bf80f4bSopenharmony_ci{
5608bf80f4bSopenharmony_ci    return {};
5618bf80f4bSopenharmony_ci}
5628bf80f4bSopenharmony_ci
5638bf80f4bSopenharmony_ciRenderCreateInfo RenderContext::GetCreateInfo() const
5648bf80f4bSopenharmony_ci{
5658bf80f4bSopenharmony_ci    return createInfo_;
5668bf80f4bSopenharmony_ci}
5678bf80f4bSopenharmony_ci
5688bf80f4bSopenharmony_ciconst IInterface* RenderContext::GetInterface(const Uid& uid) const
5698bf80f4bSopenharmony_ci{
5708bf80f4bSopenharmony_ci    if ((uid == IRenderContext::UID) || (uid == IClassFactory::UID) || (uid == IInterface::UID)) {
5718bf80f4bSopenharmony_ci        return static_cast<const IRenderContext*>(this);
5728bf80f4bSopenharmony_ci    }
5738bf80f4bSopenharmony_ci    if (uid == IClassRegister::UID) {
5748bf80f4bSopenharmony_ci        return static_cast<const IClassRegister*>(this);
5758bf80f4bSopenharmony_ci    }
5768bf80f4bSopenharmony_ci    return nullptr;
5778bf80f4bSopenharmony_ci}
5788bf80f4bSopenharmony_ci
5798bf80f4bSopenharmony_ciIInterface* RenderContext::GetInterface(const Uid& uid)
5808bf80f4bSopenharmony_ci{
5818bf80f4bSopenharmony_ci    if ((uid == IRenderContext::UID) || (uid == IClassFactory::UID) || (uid == IInterface::UID)) {
5828bf80f4bSopenharmony_ci        return static_cast<IRenderContext*>(this);
5838bf80f4bSopenharmony_ci    }
5848bf80f4bSopenharmony_ci    if (uid == IClassRegister::UID) {
5858bf80f4bSopenharmony_ci        return static_cast<IClassRegister*>(this);
5868bf80f4bSopenharmony_ci    }
5878bf80f4bSopenharmony_ci    return nullptr;
5888bf80f4bSopenharmony_ci}
5898bf80f4bSopenharmony_ci
5908bf80f4bSopenharmony_civoid RenderContext::Ref()
5918bf80f4bSopenharmony_ci{
5928bf80f4bSopenharmony_ci    refCount_++;
5938bf80f4bSopenharmony_ci}
5948bf80f4bSopenharmony_ci
5958bf80f4bSopenharmony_civoid RenderContext::Unref()
5968bf80f4bSopenharmony_ci{
5978bf80f4bSopenharmony_ci    if (--refCount_ == 1) {
5988bf80f4bSopenharmony_ci        pluginState_.Destroy();
5998bf80f4bSopenharmony_ci        delete this;
6008bf80f4bSopenharmony_ci    }
6018bf80f4bSopenharmony_ci}
6028bf80f4bSopenharmony_ci
6038bf80f4bSopenharmony_ciIInterface::Ptr RenderContext::CreateInstance(const Uid& uid)
6048bf80f4bSopenharmony_ci{
6058bf80f4bSopenharmony_ci    const auto& data = GetInterfaceMetadata(uid);
6068bf80f4bSopenharmony_ci    if (data.createInterface) {
6078bf80f4bSopenharmony_ci        return IInterface::Ptr { data.createInterface(*this, data.token) };
6088bf80f4bSopenharmony_ci    }
6098bf80f4bSopenharmony_ci    return {};
6108bf80f4bSopenharmony_ci}
6118bf80f4bSopenharmony_ci
6128bf80f4bSopenharmony_civoid RenderContext::RegisterInterfaceType(const InterfaceTypeInfo& interfaceInfo)
6138bf80f4bSopenharmony_ci{
6148bf80f4bSopenharmony_ci    // keep interfaceTypeInfos_ sorted according to UIDs
6158bf80f4bSopenharmony_ci    const auto pos = std::upper_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), interfaceInfo.uid,
6168bf80f4bSopenharmony_ci        [](Uid value, const InterfaceTypeInfo* element) { return value < element->uid; });
6178bf80f4bSopenharmony_ci    interfaceTypeInfos_.insert(pos, &interfaceInfo);
6188bf80f4bSopenharmony_ci}
6198bf80f4bSopenharmony_ci
6208bf80f4bSopenharmony_civoid RenderContext::UnregisterInterfaceType(const InterfaceTypeInfo& interfaceInfo)
6218bf80f4bSopenharmony_ci{
6228bf80f4bSopenharmony_ci    if (!interfaceTypeInfos_.empty()) {
6238bf80f4bSopenharmony_ci        const auto pos = std::lower_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), interfaceInfo.uid,
6248bf80f4bSopenharmony_ci            [](const InterfaceTypeInfo* element, Uid value) { return element->uid < value; });
6258bf80f4bSopenharmony_ci        if ((pos != interfaceTypeInfos_.cend()) && (*pos)->uid == interfaceInfo.uid) {
6268bf80f4bSopenharmony_ci            interfaceTypeInfos_.erase(pos);
6278bf80f4bSopenharmony_ci        }
6288bf80f4bSopenharmony_ci    }
6298bf80f4bSopenharmony_ci}
6308bf80f4bSopenharmony_ci
6318bf80f4bSopenharmony_ciarray_view<const InterfaceTypeInfo* const> RenderContext::GetInterfaceMetadata() const
6328bf80f4bSopenharmony_ci{
6338bf80f4bSopenharmony_ci    return interfaceTypeInfos_;
6348bf80f4bSopenharmony_ci}
6358bf80f4bSopenharmony_ci
6368bf80f4bSopenharmony_ciconst InterfaceTypeInfo& RenderContext::GetInterfaceMetadata(const Uid& uid) const
6378bf80f4bSopenharmony_ci{
6388bf80f4bSopenharmony_ci    static InterfaceTypeInfo invalidType {};
6398bf80f4bSopenharmony_ci
6408bf80f4bSopenharmony_ci    if (!interfaceTypeInfos_.empty()) {
6418bf80f4bSopenharmony_ci        const auto pos = std::lower_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), uid,
6428bf80f4bSopenharmony_ci            [](const InterfaceTypeInfo* element, Uid value) { return element->uid < value; });
6438bf80f4bSopenharmony_ci        if ((pos != interfaceTypeInfos_.cend()) && (*pos)->uid == uid) {
6448bf80f4bSopenharmony_ci            return *(*pos);
6458bf80f4bSopenharmony_ci        }
6468bf80f4bSopenharmony_ci    }
6478bf80f4bSopenharmony_ci    return invalidType;
6488bf80f4bSopenharmony_ci}
6498bf80f4bSopenharmony_ci
6508bf80f4bSopenharmony_ciIInterface* RenderContext::GetInstance(const Uid& uid) const
6518bf80f4bSopenharmony_ci{
6528bf80f4bSopenharmony_ci    const auto& data = GetInterfaceMetadata(uid);
6538bf80f4bSopenharmony_ci    if (data.getInterface) {
6548bf80f4bSopenharmony_ci        return data.getInterface(const_cast<RenderContext&>(*this), data.token);
6558bf80f4bSopenharmony_ci    }
6568bf80f4bSopenharmony_ci    return nullptr;
6578bf80f4bSopenharmony_ci}
6588bf80f4bSopenharmony_ci
6598bf80f4bSopenharmony_civoid RenderContext::OnTypeInfoEvent(EventType type, array_view<const ITypeInfo* const> typeInfos)
6608bf80f4bSopenharmony_ci{
6618bf80f4bSopenharmony_ci    auto& renderNodeMgr = renderNodeGraphMgr_->GetRenderNodeManager();
6628bf80f4bSopenharmony_ci    if (type == EventType::ADDED) {
6638bf80f4bSopenharmony_ci        for (const auto* info : typeInfos) {
6648bf80f4bSopenharmony_ci            if (info && info->typeUid == IRenderPlugin::UID && static_cast<const IRenderPlugin*>(info)->createPlugin) {
6658bf80f4bSopenharmony_ci                auto renderPlugin = static_cast<const IRenderPlugin*>(info);
6668bf80f4bSopenharmony_ci                if (std::none_of(plugins_.begin(), plugins_.end(),
6678bf80f4bSopenharmony_ci                        [renderPlugin](const pair<PluginToken, const IRenderPlugin*>& pluginData) {
6688bf80f4bSopenharmony_ci                            return pluginData.second == renderPlugin;
6698bf80f4bSopenharmony_ci                        })) {
6708bf80f4bSopenharmony_ci                    auto token = renderPlugin->createPlugin(*this);
6718bf80f4bSopenharmony_ci                    plugins_.push_back({ token, renderPlugin });
6728bf80f4bSopenharmony_ci                }
6738bf80f4bSopenharmony_ci            } else if (info && info->typeUid == RenderDataStoreTypeInfo::UID) {
6748bf80f4bSopenharmony_ci                renderDataStoreMgr_->AddRenderDataStoreFactory(*static_cast<const RenderDataStoreTypeInfo*>(info));
6758bf80f4bSopenharmony_ci            } else if (info && info->typeUid == RenderNodeTypeInfo::UID) {
6768bf80f4bSopenharmony_ci                renderNodeMgr.AddRenderNodeFactory(*static_cast<const RenderNodeTypeInfo*>(info));
6778bf80f4bSopenharmony_ci            }
6788bf80f4bSopenharmony_ci        }
6798bf80f4bSopenharmony_ci    } else if (type == EventType::REMOVED) {
6808bf80f4bSopenharmony_ci        for (const auto* info : typeInfos) {
6818bf80f4bSopenharmony_ci            if (info && info->typeUid == IRenderPlugin::UID) {
6828bf80f4bSopenharmony_ci                auto renderPlugin = static_cast<const IRenderPlugin*>(info);
6838bf80f4bSopenharmony_ci                if (auto pos = std::find_if(plugins_.begin(), plugins_.end(),
6848bf80f4bSopenharmony_ci                        [renderPlugin](const pair<PluginToken, const IRenderPlugin*>& pluginData) {
6858bf80f4bSopenharmony_ci                            return pluginData.second == renderPlugin;
6868bf80f4bSopenharmony_ci                        });
6878bf80f4bSopenharmony_ci                    pos != plugins_.end()) {
6888bf80f4bSopenharmony_ci                    if (renderPlugin->destroyPlugin) {
6898bf80f4bSopenharmony_ci                        renderPlugin->destroyPlugin(pos->first);
6908bf80f4bSopenharmony_ci                    }
6918bf80f4bSopenharmony_ci                    plugins_.erase(pos);
6928bf80f4bSopenharmony_ci                }
6938bf80f4bSopenharmony_ci            } else if (info && info->typeUid == RenderDataStoreTypeInfo::UID) {
6948bf80f4bSopenharmony_ci                renderDataStoreMgr_->RemoveRenderDataStoreFactory(*static_cast<const RenderDataStoreTypeInfo*>(info));
6958bf80f4bSopenharmony_ci            } else if (info && info->typeUid == RenderNodeTypeInfo::UID) {
6968bf80f4bSopenharmony_ci                renderNodeGraphMgr_->Destroy(static_cast<const RenderNodeTypeInfo*>(info)->typeName);
6978bf80f4bSopenharmony_ci                renderNodeMgr.RemoveRenderNodeFactory(*static_cast<const RenderNodeTypeInfo*>(info));
6988bf80f4bSopenharmony_ci            }
6998bf80f4bSopenharmony_ci        }
7008bf80f4bSopenharmony_ci    }
7018bf80f4bSopenharmony_ci}
7028bf80f4bSopenharmony_ci
7038bf80f4bSopenharmony_ciRENDER_END_NAMESPACE()
704